--- a/.hgtags Wed Jan 28 17:48:59 2015 +0100
+++ b/.hgtags Thu Jan 29 03:54:45 2015 +0000
@@ -288,3 +288,5 @@
6494b13f88a867026ee316b444d9a4fa589dd6bd jdk9-b43
abbfccd659b91a7bb815d5e36fed635dcdd40f31 jdk9-b44
bfc24ae2b900187585079bb11e66e459d1e525fe jdk9-b45
+722378bc599e38d9a1dd484de30f10dfd7b21438 jdk9-b46
+8327024a99559982b848e9c2191da9c0bf8838fd jdk9-b47
--- a/.hgtags-top-repo Wed Jan 28 17:48:59 2015 +0100
+++ b/.hgtags-top-repo Thu Jan 29 03:54:45 2015 +0000
@@ -288,3 +288,5 @@
02ee8c65622e8bd97496d584e22fc7dcf0edc4ae jdk9-b43
8994f5d87b3bb5e8d317d4e8ccb326da1a73684a jdk9-b44
3dd628fde2086218d548841022ee8436b6b88185 jdk9-b45
+12f1e276447bcc81516e85367d53e4f08897049d jdk9-b46
+b6cca3e6175a69f39e5799b7349ddb0176630291 jdk9-b47
--- a/common/autoconf/configure Wed Jan 28 17:48:59 2015 +0100
+++ b/common/autoconf/configure Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/common/bin/compare.sh Wed Jan 28 17:48:59 2015 +0100
+++ b/common/bin/compare.sh Thu Jan 29 03:54:45 2015 +0000
@@ -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<com\.apple\.jobjc\..*itemsPtr();/d' \
- -e '/[<>].*public void setItemsPtr(com\.apple\.jobjc\.Pointer<com\.apple\.jobjc\..*);/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<com\.apple\.jobjc\..*itemsPtr();/d' \
+ -e '/[<>].*public void setItemsPtr(com\.apple\.jobjc\.Pointer<com\.apple\.jobjc\..*);/d' \
-e '/[<>].*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 '/[<>] <!-- Generated by javadoc .* on .* -->/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</dev/null | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.this | $UNIQ > $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</dev/null | $AWK '{ print $1;}' | $SORT | $TEE $WORK_FILE_BASE.deps.this | $UNIQ > $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
--- a/corba/.hgtags Wed Jan 28 17:48:59 2015 +0100
+++ b/corba/.hgtags Thu Jan 29 03:54:45 2015 +0000
@@ -288,3 +288,5 @@
9645e35616b60c5c07b4fdf11a132afc8081dfa8 jdk9-b43
1f57bd728c9e6865ccb9d43ccd80a1c11230a32f jdk9-b44
9e3f2bed80c0e5a84a256ce41f1d10c5ade48466 jdk9-b45
+326f2068b4a4c05e2fa27d6acf93eba7b54b090d jdk9-b46
+ee8447ca632e1d39180b4767c749db101bff7314 jdk9-b47
--- a/hotspot/.hgtags Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/.hgtags Thu Jan 29 03:54:45 2015 +0000
@@ -448,3 +448,5 @@
65a9747147b8090037541040ba67156ec914db6a jdk9-b43
43a44b56dca61a4d766a20f0528fdd8b5ceff873 jdk9-b44
5dc8184af1e2bb30b0103113d1f1a58a21a80c37 jdk9-b45
+a184ee1d717297bd35b7c3e35393e137921a3ed2 jdk9-b46
+3b241fb72b8925b75941d612db762a6d5da66d02 jdk9-b47
--- a/hotspot/agent/make/Makefile Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/agent/make/Makefile Thu Jan 29 03:54:45 2015 +0000
@@ -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 \
--- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Thu Jan 29 03:54:45 2015 +0000
@@ -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;
--- a/hotspot/agent/src/os/linux/symtab.c Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/agent/src/os/linux/symtab.c Thu Jan 29 03:54:45 2015 +0000
@@ -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.
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java Thu Jan 29 03:54:45 2015 +0000
@@ -34,6 +34,6 @@
}
public boolean isBigEndian() {
- return true;
+ return "big".equals(System.getProperty("sun.cpu.endian"));
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java Thu Jan 29 03:54:45 2015 +0000
@@ -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." +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64CFrame.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/ppc64/LinuxPPC64ThreadContext.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ppc64/PPC64ThreadContext.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java Thu Jan 29 03:54:45 2015 +0000
@@ -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." +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64Thread.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadContext.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ppc64/ProcPPC64ThreadFactory.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Thu Jan 29 03:54:45 2015 +0000
@@ -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." +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64Thread.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadContext.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/ppc64/RemotePPC64ThreadFactory.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Thu Jan 29 03:54:45 2015 +0000
@@ -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)
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_ppc64/LinuxPPC64JavaThreadPDAccess.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64CurrentFrameGuess.java Thu Jan 29 03:54:45 2015 +0000
@@ -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.*;
+
+/** <P> 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. </P>
+ */
+
+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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64JavaCallWrapper.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64RegisterMap.java Thu Jan 29 03:54:45 2015 +0000
@@ -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; }
+}
--- a/hotspot/make/aix/makefiles/ppc64.make Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/make/aix/makefiles/ppc64.make Thu Jan 29 03:54:45 2015 +0000
@@ -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.
--- a/hotspot/make/aix/makefiles/xlc.make Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/make/aix/makefiles/xlc.make Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/hotspot/make/linux/makefiles/sa.make Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/make/linux/makefiles/sa.make Thu Jan 29 03:54:45 2015 +0000
@@ -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:
--- a/hotspot/make/sa.files Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/make/sa.files Thu Jan 29 03:54:45 2015 +0000
@@ -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 \
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -284,19 +284,20 @@
MTCTR_OPCODE = (MTSPR_OPCODE | 9 << SPR_0_4_SHIFT),
MFCTR_OPCODE = (MFSPR_OPCODE | 9 << SPR_0_4_SHIFT),
- MTTFHAR_OPCODE = (MTSPR_OPCODE | 128 << SPR_0_4_SHIFT),
- MFTFHAR_OPCODE = (MFSPR_OPCODE | 128 << SPR_0_4_SHIFT),
- MTTFIAR_OPCODE = (MTSPR_OPCODE | 129 << SPR_0_4_SHIFT),
- MFTFIAR_OPCODE = (MFSPR_OPCODE | 129 << SPR_0_4_SHIFT),
- MTTEXASR_OPCODE = (MTSPR_OPCODE | 130 << SPR_0_4_SHIFT),
- MFTEXASR_OPCODE = (MFSPR_OPCODE | 130 << SPR_0_4_SHIFT),
- MTTEXASRU_OPCODE = (MTSPR_OPCODE | 131 << SPR_0_4_SHIFT),
- MFTEXASRU_OPCODE = (MFSPR_OPCODE | 131 << SPR_0_4_SHIFT),
+ // Attention: Higher and lower half are inserted in reversed order.
+ MTTFHAR_OPCODE = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT),
+ MFTFHAR_OPCODE = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT),
+ MTTFIAR_OPCODE = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 1 << SPR_0_4_SHIFT),
+ MFTFIAR_OPCODE = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 1 << SPR_0_4_SHIFT),
+ MTTEXASR_OPCODE = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 2 << SPR_0_4_SHIFT),
+ MFTEXASR_OPCODE = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 2 << SPR_0_4_SHIFT),
+ MTTEXASRU_OPCODE = (MTSPR_OPCODE | 4 << SPR_5_9_SHIFT | 3 << SPR_0_4_SHIFT),
+ MFTEXASRU_OPCODE = (MFSPR_OPCODE | 4 << SPR_5_9_SHIFT | 3 << SPR_0_4_SHIFT),
- MTVRSAVE_OPCODE = (MTSPR_OPCODE | 256 << SPR_0_4_SHIFT),
- MFVRSAVE_OPCODE = (MFSPR_OPCODE | 256 << SPR_0_4_SHIFT),
+ MTVRSAVE_OPCODE = (MTSPR_OPCODE | 8 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT),
+ MFVRSAVE_OPCODE = (MFSPR_OPCODE | 8 << SPR_5_9_SHIFT | 0 << SPR_0_4_SHIFT),
- MFTB_OPCODE = (MFSPR_OPCODE | 268 << SPR_0_4_SHIFT),
+ MFTB_OPCODE = (MFSPR_OPCODE | 8 << SPR_5_9_SHIFT | 12 << SPR_0_4_SHIFT),
MTCRF_OPCODE = (31u << OPCODE_SHIFT | 144u << 1),
MFCR_OPCODE = (31u << OPCODE_SHIFT | 19u << 1),
@@ -1494,6 +1495,26 @@
inline void mftexasr(Register d);
inline void mftexasru(Register d);
+ // TEXASR bit description
+ enum transaction_failure_reason {
+ // Upper half (TEXASRU):
+ tm_failure_persistent = 7, // The failure is likely to recur on each execution.
+ tm_disallowed = 8, // The instruction is not permitted.
+ tm_nesting_of = 9, // The maximum transaction level was exceeded.
+ tm_footprint_of = 10, // The tracking limit for transactional storage accesses was exceeded.
+ tm_self_induced_cf = 11, // A self-induced conflict occurred in Suspended state.
+ tm_non_trans_cf = 12, // A conflict occurred with a non-transactional access by another processor.
+ tm_trans_cf = 13, // A conflict occurred with another transaction.
+ tm_translation_cf = 14, // A conflict occurred with a TLB invalidation.
+ tm_inst_fetch_cf = 16, // An instruction fetch was performed from a block that was previously written transactionally.
+ tm_tabort = 31, // Termination was caused by the execution of an abort instruction.
+ // Lower half:
+ tm_suspended = 32, // Failure was recorded in Suspended state.
+ tm_failure_summary = 36, // Failure has been detected and recorded.
+ tm_tfiar_exact = 37, // Value in the TFIAR is exact.
+ tm_rot = 38, // Rollback-only transaction.
+ };
+
// PPC 1, section 2.4.1 Branch Instructions
inline void b( address a, relocInfo::relocType rt = relocInfo::none);
inline void b( Label& L);
@@ -1581,6 +1602,7 @@
inline void bnectrl(ConditionRegister crx, relocInfo::relocType rt = relocInfo::none);
// condition register logic instructions
+ // NOTE: There's a preferred form: d and s2 should point into the same condition register.
inline void crand( int d, int s1, int s2);
inline void crnand(int d, int s1, int s2);
inline void cror( int d, int s1, int s2);
@@ -1590,6 +1612,19 @@
inline void crandc(int d, int s1, int s2);
inline void crorc( int d, int s1, int s2);
+ // More convenient version.
+ int condition_register_bit(ConditionRegister cr, Condition c) {
+ return 4 * (int)(intptr_t)cr + c;
+ }
+ void crand( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+ void crnand(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+ void cror( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+ void crxor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+ void crnor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+ void creqv( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+ void crandc(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+ void crorc( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc);
+
// icache and dcache related instructions
inline void icbi( Register s1, Register s2);
//inline void dcba(Register s1, Register s2); // Instruction for embedded processor only.
@@ -1673,6 +1708,10 @@
inline void smt_prio_low();
inline void smt_prio_medium_low();
inline void smt_prio_medium();
+ // >= Power7
+ inline void smt_yield();
+ inline void smt_mdoio();
+ inline void smt_mdoom();
// trap instructions
inline void twi_0(Register a); // for load with acquire semantics use load+twi_0+isync (trap can't occur)
@@ -1958,6 +1997,7 @@
inline void tbeginrot_(); // R=1 Rollback-Only Transaction
inline void tend_(); // A=0
inline void tendall_(); // A=1
+ inline void tabort_();
inline void tabort_(Register a);
inline void tabortwc_(int t, Register a, Register b);
inline void tabortwci_(int t, Register a, int si);
@@ -1967,6 +2007,10 @@
inline void tresume_(); // tsr with L=1
inline void tcheck(int f);
+ static bool is_tbegin(int x) {
+ return TBEGIN_OPCODE == (x & (0x3f << OPCODE_SHIFT | 0x3ff << 1));
+ }
+
// The following encoders use r0 as second operand. These instructions
// read r0 as '0'.
inline void lwzx( Register d, Register s2);
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -453,6 +453,48 @@
inline void Assembler::crandc(int d, int s1, int s2) { emit_int32(CRANDC_OPCODE | bt(d) | ba(s1) | bb(s2)); }
inline void Assembler::crorc( int d, int s1, int s2) { emit_int32(CRORC_OPCODE | bt(d) | ba(s1) | bb(s2)); }
+// More convenient version.
+inline void Assembler::crand( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+ int dst_bit = condition_register_bit(crdst, cdst),
+ src_bit = condition_register_bit(crsrc, csrc);
+ crand(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::crnand(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+ int dst_bit = condition_register_bit(crdst, cdst),
+ src_bit = condition_register_bit(crsrc, csrc);
+ crnand(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::cror( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+ int dst_bit = condition_register_bit(crdst, cdst),
+ src_bit = condition_register_bit(crsrc, csrc);
+ cror(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::crxor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+ int dst_bit = condition_register_bit(crdst, cdst),
+ src_bit = condition_register_bit(crsrc, csrc);
+ crxor(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::crnor( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+ int dst_bit = condition_register_bit(crdst, cdst),
+ src_bit = condition_register_bit(crsrc, csrc);
+ crnor(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::creqv( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+ int dst_bit = condition_register_bit(crdst, cdst),
+ src_bit = condition_register_bit(crsrc, csrc);
+ creqv(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::crandc(ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+ int dst_bit = condition_register_bit(crdst, cdst),
+ src_bit = condition_register_bit(crsrc, csrc);
+ crandc(dst_bit, src_bit, dst_bit);
+}
+inline void Assembler::crorc( ConditionRegister crdst, Condition cdst, ConditionRegister crsrc, Condition csrc) {
+ int dst_bit = condition_register_bit(crdst, cdst),
+ src_bit = condition_register_bit(crsrc, csrc);
+ crorc(dst_bit, src_bit, dst_bit);
+}
+
// Conditional move (>= Power7)
inline void Assembler::isel(Register d, ConditionRegister cr, Condition cc, bool inv, Register a, Register b) {
if (b == noreg) {
@@ -516,6 +558,10 @@
inline void Assembler::smt_prio_medium() { Assembler::or_unchecked(R2, R2, R2); }
inline void Assembler::smt_prio_medium_high() { Assembler::or_unchecked(R5, R5, R5); }
inline void Assembler::smt_prio_high() { Assembler::or_unchecked(R3, R3, R3); }
+// >= Power7
+inline void Assembler::smt_yield() { Assembler::or_unchecked(R27, R27, R27); }
+inline void Assembler::smt_mdoio() { Assembler::or_unchecked(R29, R29, R29); }
+inline void Assembler::smt_mdoom() { Assembler::or_unchecked(R30, R30, R30); }
inline void Assembler::twi_0(Register a) { twi_unchecked(0, a, 0);}
@@ -778,7 +824,8 @@
inline void Assembler::tbeginrot_() { emit_int32( TBEGIN_OPCODE | /*R=1*/ 1u << (31-10) | rc(1)); }
inline void Assembler::tend_() { emit_int32( TEND_OPCODE | rc(1)); }
inline void Assembler::tendall_() { emit_int32( TEND_OPCODE | /*A=1*/ 1u << (31-6) | rc(1)); }
-inline void Assembler::tabort_(Register a) { emit_int32( TABORT_OPCODE | ra(a) | rc(1)); }
+inline void Assembler::tabort_() { emit_int32( TABORT_OPCODE | rc(1)); }
+inline void Assembler::tabort_(Register a) { assert(a != R0, "r0 not allowed"); emit_int32( TABORT_OPCODE | ra(a) | rc(1)); }
inline void Assembler::tabortwc_(int t, Register a, Register b) { emit_int32( TABORTWC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); }
inline void Assembler::tabortwci_(int t, Register a, int si) { emit_int32( TABORTWCI_OPCODE | to(t) | ra(a) | sh1620(si) | rc(1)); }
inline void Assembler::tabortdc_(int t, Register a, Register b) { emit_int32( TABORTDC_OPCODE | to(t) | ra(a) | rb(b) | rc(1)); }
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1712,7 +1712,7 @@
andi_(R0, klass, TypeEntries::type_unknown);
// Already unknown. Nothing to do anymore.
//bne(CCR0, do_nothing);
- crorc(/*CCR0 eq*/2, /*CCR1 eq*/4+2, /*CCR0 eq*/2); // cr0 eq = cr1 eq or cr0 ne
+ crorc(CCR0, Assembler::equal, CCR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne
beq(CCR0, do_nothing);
clrrdi_(R0, tmp, exact_log2(-TypeEntries::type_mask));
@@ -1826,9 +1826,9 @@
lbz(tmp2, Method::intrinsic_id_offset_in_bytes(), R19_method);
cmpwi(CCR0, tmp1, Bytecodes::_invokedynamic);
cmpwi(CCR1, tmp1, Bytecodes::_invokehandle);
- cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
+ cror(CCR0, Assembler::equal, CCR1, Assembler::equal);
cmpwi(CCR1, tmp2, vmIntrinsics::_compiledLambdaForm);
- cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
+ cror(CCR0, Assembler::equal, CCR1, Assembler::equal);
bne(CCR0, profile_continue);
}
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2015 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1079,7 +1079,7 @@
__ sldi(tmp2, R5_ARG3, log2_elem_size); // size in bytes
__ cmpld(CCR0, R3_ARG1, R4_ARG2); // Use unsigned comparison!
__ cmpld(CCR1, tmp1, tmp2);
- __ crand(/*CCR0 lt*/0, /*CCR1 lt*/4+0, /*CCR0 lt*/0);
+ __ crand(CCR0, Assembler::less, CCR1, Assembler::less);
__ blt(CCR0, l_overlap); // Src before dst and distance smaller than size.
// need to copy forwards
--- a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -264,11 +264,11 @@
__ cmpdi(CCR0, Rmdo, 0);
__ beq(CCR0, no_mdo);
- // Increment backedge counter in the MDO.
- const int mdo_bc_offs = in_bytes(MethodData::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
- __ lwz(Rscratch2, mdo_bc_offs, Rmdo);
+ // Increment invocation counter in the MDO.
+ const int mdo_ic_offs = in_bytes(MethodData::invocation_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
+ __ lwz(Rscratch2, mdo_ic_offs, Rmdo);
__ addi(Rscratch2, Rscratch2, increment);
- __ stw(Rscratch2, mdo_bc_offs, Rmdo);
+ __ stw(Rscratch2, mdo_ic_offs, Rmdo);
__ load_const_optimized(Rscratch1, mask, R0);
__ and_(Rscratch1, Rscratch2, Rscratch1);
__ bne(CCR0, done);
@@ -276,12 +276,12 @@
}
// Increment counter in MethodCounters*.
- const int mo_bc_offs = in_bytes(MethodCounters::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
+ const int mo_ic_offs = in_bytes(MethodCounters::invocation_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
__ bind(no_mdo);
__ get_method_counters(R19_method, R3_counters, done);
- __ lwz(Rscratch2, mo_bc_offs, R3_counters);
+ __ lwz(Rscratch2, mo_ic_offs, R3_counters);
__ addi(Rscratch2, Rscratch2, increment);
- __ stw(Rscratch2, mo_bc_offs, R3_counters);
+ __ stw(Rscratch2, mo_ic_offs, R3_counters);
__ load_const_optimized(Rscratch1, mask, R0);
__ and_(Rscratch1, Rscratch2, Rscratch1);
__ beq(CCR0, *overflow);
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013, 2014 SAP AG. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013, 2015 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -335,11 +335,11 @@
__ cmpwi(CCR0, Rscratch2, JVM_CONSTANT_UnresolvedClass); // Unresolved class?
__ cmpwi(CCR1, Rscratch2, JVM_CONSTANT_UnresolvedClassInError); // Unresolved class in error state?
- __ cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
+ __ cror(CCR0, Assembler::equal, CCR1, Assembler::equal);
// Resolved class - need to call vm to get java mirror of the class.
__ cmpwi(CCR1, Rscratch2, JVM_CONSTANT_Class);
- __ crnor(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); // Neither resolved class nor unresolved case from above?
+ __ crnor(CCR0, Assembler::equal, CCR1, Assembler::equal); // Neither resolved class nor unresolved case from above?
__ beq(CCR0, notClass);
__ li(R4, wide ? 1 : 0);
@@ -2611,7 +2611,7 @@
__ cmpwi(CCR0, Rflags, ltos);
__ cmpwi(CCR1, Rflags, dtos);
__ addi(base, R15_esp, Interpreter::expr_offset_in_bytes(1));
- __ crnor(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
+ __ crnor(CCR0, Assembler::equal, CCR1, Assembler::equal);
__ beq(CCR0, is_one_slot);
__ addi(base, R15_esp, Interpreter::expr_offset_in_bytes(2));
__ bind(is_one_slot);
@@ -3563,7 +3563,7 @@
// Make sure klass does not have has_finalizer, or is abstract, or interface or java/lang/Class.
__ andi_(R0, Rinstance_size, Klass::_lh_instance_slow_path_bit); // slow path bit equals 0?
- __ crnand(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); // slow path bit set or not fully initialized?
+ __ crnand(CCR0, Assembler::equal, CCR1, Assembler::equal); // slow path bit set or not fully initialized?
__ beq(CCR0, Lslow_case);
// --------------------------------------------------------------------------
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -3184,7 +3184,24 @@
jmp(done);
} else {
// Stack: X Y
- Label x_negative, y_odd;
+ Label x_negative, y_not_2;
+
+ static double two = 2.0;
+ ExternalAddress two_addr((address)&two);
+
+ // constant maybe too far on 64 bit
+ lea(tmp2, two_addr);
+ fld_d(Address(tmp2, 0)); // Stack: 2 X Y
+ fcmp(tmp, 2, true, false); // Stack: X Y
+ jcc(Assembler::parity, y_not_2);
+ jcc(Assembler::notEqual, y_not_2);
+
+ fxch(); fpop(); // Stack: X
+ fmul(0); // Stack: X*X
+
+ jmp(done);
+
+ bind(y_not_2);
fldz(); // Stack: 0 X Y
fcmp(tmp, 1, true, false); // Stack: X Y
--- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -197,7 +197,38 @@
}
-// check if the given path is considered a secure directory for
+// Check if the given statbuf is considered a secure directory for
+// the backing store files. Returns true if the directory is considered
+// a secure location. Returns false if the statbuf is a symbolic link or
+// if an error occurred.
+//
+static bool is_statbuf_secure(struct stat *statp) {
+ if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
+ // The path represents a link or some non-directory file type,
+ // which is not what we expected. Declare it insecure.
+ //
+ return false;
+ }
+ // We have an existing directory, check if the permissions are safe.
+ //
+ if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+ // The directory is open for writing and could be subjected
+ // to a symlink or a hard link attack. Declare it insecure.
+ //
+ return false;
+ }
+ // See if the uid of the directory matches the effective uid of the process.
+ //
+ if (statp->st_uid != geteuid()) {
+ // The directory was not created by this user, declare it insecure.
+ //
+ return false;
+ }
+ return true;
+}
+
+
+// Check if the given path is considered a secure directory for
// the backing store files. Returns true if the directory exists
// and is considered a secure location. Returns false if the path
// is a symbolic link or if an error occurred.
@@ -211,27 +242,185 @@
return false;
}
- // the path exists, now check it's mode
- if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
- // the path represents a link or some non-directory file type,
- // which is not what we expected. declare it insecure.
- //
+ // The path exists, see if it is secure.
+ return is_statbuf_secure(&statbuf);
+}
+
+
+// Check if the given directory file descriptor is considered a secure
+// directory for the backing store files. Returns true if the directory
+// exists and is considered a secure location. Returns false if the path
+// is a symbolic link or if an error occurred.
+//
+static bool is_dirfd_secure(int dir_fd) {
+ struct stat statbuf;
+ int result = 0;
+
+ RESTARTABLE(::fstat(dir_fd, &statbuf), result);
+ if (result == OS_ERR) {
+ return false;
+ }
+
+ // The path exists, now check its mode.
+ return is_statbuf_secure(&statbuf);
+}
+
+
+// Check to make sure fd1 and fd2 are referencing the same file system object.
+//
+static bool is_same_fsobject(int fd1, int fd2) {
+ struct stat statbuf1;
+ struct stat statbuf2;
+ int result = 0;
+
+ RESTARTABLE(::fstat(fd1, &statbuf1), result);
+ if (result == OS_ERR) {
+ return false;
+ }
+ RESTARTABLE(::fstat(fd2, &statbuf2), result);
+ if (result == OS_ERR) {
+ return false;
+ }
+
+ if ((statbuf1.st_ino == statbuf2.st_ino) &&
+ (statbuf1.st_dev == statbuf2.st_dev)) {
+ return true;
+ } else {
return false;
}
- else {
- // we have an existing directory, check if the permissions are safe.
- //
- if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
- // the directory is open for writing and could be subjected
- // to a symlnk attack. declare it insecure.
- //
- return false;
+}
+
+
+// Open the directory of the given path and validate it.
+// Return a DIR * of the open directory.
+//
+static DIR *open_directory_secure(const char* dirname) {
+ // Open the directory using open() so that it can be verified
+ // to be secure by calling is_dirfd_secure(), opendir() and then check
+ // to see if they are the same file system object. This method does not
+ // introduce a window of opportunity for the directory to be attacked that
+ // calling opendir() and is_directory_secure() does.
+ int result;
+ DIR *dirp = NULL;
+ RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
+ if (result == OS_ERR) {
+ // Directory doesn't exist or is a symlink, so there is nothing to cleanup.
+ if (PrintMiscellaneous && Verbose) {
+ if (errno == ELOOP) {
+ warning("directory %s is a symlink and is not secure\n", dirname);
+ } else {
+ warning("could not open directory %s: %s\n", dirname, strerror(errno));
+ }
}
+ return dirp;
+ }
+ int fd = result;
+
+ // Determine if the open directory is secure.
+ if (!is_dirfd_secure(fd)) {
+ // The directory is not a secure directory.
+ os::close(fd);
+ return dirp;
+ }
+
+ // Open the directory.
+ dirp = ::opendir(dirname);
+ if (dirp == NULL) {
+ // The directory doesn't exist, close fd and return.
+ os::close(fd);
+ return dirp;
+ }
+
+ // Check to make sure fd and dirp are referencing the same file system object.
+ if (!is_same_fsobject(fd, dirfd(dirp))) {
+ // The directory is not secure.
+ os::close(fd);
+ os::closedir(dirp);
+ dirp = NULL;
+ return dirp;
+ }
+
+ // Close initial open now that we know directory is secure
+ os::close(fd);
+
+ return dirp;
+}
+
+// NOTE: The code below uses fchdir(), open() and unlink() because
+// fdopendir(), openat() and unlinkat() are not supported on all
+// versions. Once the support for fdopendir(), openat() and unlinkat()
+// is available on all supported versions the code can be changed
+// to use these functions.
+
+// Open the directory of the given path, validate it and set the
+// current working directory to it.
+// Return a DIR * of the open directory and the saved cwd fd.
+//
+static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
+
+ // Open the directory.
+ DIR* dirp = open_directory_secure(dirname);
+ if (dirp == NULL) {
+ // Directory doesn't exist or is insecure, so there is nothing to cleanup.
+ return dirp;
+ }
+ int fd = dirfd(dirp);
+
+ // Open a fd to the cwd and save it off.
+ int result;
+ RESTARTABLE(::open(".", O_RDONLY), result);
+ if (result == OS_ERR) {
+ *saved_cwd_fd = -1;
+ } else {
+ *saved_cwd_fd = result;
+ }
+
+ // Set the current directory to dirname by using the fd of the directory.
+ result = fchdir(fd);
+
+ return dirp;
+}
+
+// Close the directory and restore the current working directory.
+//
+static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
+
+ int result;
+ // If we have a saved cwd change back to it and close the fd.
+ if (saved_cwd_fd != -1) {
+ result = fchdir(saved_cwd_fd);
+ ::close(saved_cwd_fd);
+ }
+
+ // Close the directory.
+ os::closedir(dirp);
+}
+
+// Check if the given file descriptor is considered a secure.
+//
+static bool is_file_secure(int fd, const char *filename) {
+
+ int result;
+ struct stat statbuf;
+
+ // Determine if the file is secure.
+ RESTARTABLE(::fstat(fd, &statbuf), result);
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ warning("fstat failed on %s: %s\n", filename, strerror(errno));
+ }
+ return false;
+ }
+ if (statbuf.st_nlink > 1) {
+ // A file with multiple links is not expected.
+ if (PrintMiscellaneous && Verbose) {
+ warning("file %s has multiple links\n", filename);
+ }
+ return false;
}
return true;
}
-
// return the user name for the given user id
//
// the caller is expected to free the allocated memory.
@@ -317,9 +506,11 @@
const char* tmpdirname = os::get_temp_directory();
+ // open the temp directory
DIR* tmpdirp = os::opendir(tmpdirname);
if (tmpdirp == NULL) {
+ // Cannot open the directory to get the user name, return.
return NULL;
}
@@ -344,25 +535,14 @@
strcat(usrdir_name, "/");
strcat(usrdir_name, dentry->d_name);
- DIR* subdirp = os::opendir(usrdir_name);
+ // open the user directory
+ DIR* subdirp = open_directory_secure(usrdir_name);
if (subdirp == NULL) {
FREE_C_HEAP_ARRAY(char, usrdir_name);
continue;
}
- // Since we don't create the backing store files in directories
- // pointed to by symbolic links, we also don't follow them when
- // looking for the files. We check for a symbolic link after the
- // call to opendir in order to eliminate a small window where the
- // symlink can be exploited.
- //
- if (!is_directory_secure(usrdir_name)) {
- FREE_C_HEAP_ARRAY(char, usrdir_name);
- os::closedir(subdirp);
- continue;
- }
-
struct dirent* udentry;
char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
errno = 0;
@@ -465,26 +645,6 @@
}
-// remove file
-//
-// this method removes the file with the given file name in the
-// named directory.
-//
-static void remove_file(const char* dirname, const char* filename) {
-
- size_t nbytes = strlen(dirname) + strlen(filename) + 2;
- char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
-
- strcpy(path, dirname);
- strcat(path, "/");
- strcat(path, filename);
-
- remove_file(path);
-
- FREE_C_HEAP_ARRAY(char, path);
-}
-
-
// cleanup stale shared memory resources
//
// This method attempts to remove all stale shared memory files in
@@ -496,17 +656,11 @@
//
static void cleanup_sharedmem_resources(const char* dirname) {
- // open the user temp directory
- DIR* dirp = os::opendir(dirname);
-
+ int saved_cwd_fd;
+ // open the directory and set the current working directory to it
+ DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
if (dirp == NULL) {
- // directory doesn't exist, so there is nothing to cleanup
- return;
- }
-
- if (!is_directory_secure(dirname)) {
- // the directory is not a secure directory
- os::closedir(dirp);
+ // directory doesn't exist or is insecure, so there is nothing to cleanup
return;
}
@@ -520,6 +674,7 @@
//
struct dirent* entry;
char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
+
errno = 0;
while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
@@ -530,7 +685,7 @@
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
// attempt to remove all unexpected files, except "." and ".."
- remove_file(dirname, entry->d_name);
+ unlink(entry->d_name);
}
errno = 0;
@@ -553,11 +708,14 @@
if ((pid == os::current_process_id()) ||
(kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
- remove_file(dirname, entry->d_name);
+ unlink(entry->d_name);
}
errno = 0;
}
- os::closedir(dirp);
+
+ // close the directory and reset the current working directory
+ close_directory_secure_cwd(dirp, saved_cwd_fd);
+
FREE_C_HEAP_ARRAY(char, dbuf);
}
@@ -614,19 +772,54 @@
return -1;
}
- int result;
+ int saved_cwd_fd;
+ // open the directory and set the current working directory to it
+ DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
+ if (dirp == NULL) {
+ // Directory doesn't exist or is insecure, so cannot create shared
+ // memory file.
+ return -1;
+ }
- RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
+ // Open the filename in the current directory.
+ // Cannot use O_TRUNC here; truncation of an existing file has to happen
+ // after the is_file_secure() check below.
+ int result;
+ RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
if (result == OS_ERR) {
if (PrintMiscellaneous && Verbose) {
- warning("could not create file %s: %s\n", filename, strerror(errno));
+ if (errno == ELOOP) {
+ warning("file %s is a symlink and is not secure\n", filename);
+ } else {
+ warning("could not create file %s: %s\n", filename, strerror(errno));
+ }
}
+ // close the directory and reset the current working directory
+ close_directory_secure_cwd(dirp, saved_cwd_fd);
+
return -1;
}
+ // close the directory and reset the current working directory
+ close_directory_secure_cwd(dirp, saved_cwd_fd);
// save the file descriptor
int fd = result;
+ // check to see if the file is secure
+ if (!is_file_secure(fd, filename)) {
+ ::close(fd);
+ return -1;
+ }
+
+ // truncate the file to get rid of any existing data
+ RESTARTABLE(::ftruncate(fd, (off_t)0), result);
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ warning("could not truncate shared memory file: %s\n", strerror(errno));
+ }
+ ::close(fd);
+ return -1;
+ }
// set the file size
RESTARTABLE(::ftruncate(fd, (off_t)size), result);
if (result == OS_ERR) {
@@ -684,8 +877,15 @@
THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
}
}
+ int fd = result;
- return result;
+ // check to see if the file is secure
+ if (!is_file_secure(fd, filename)) {
+ ::close(fd);
+ return -1;
+ }
+
+ return fd;
}
// create a named shared memory region. returns the address of the
@@ -717,13 +917,21 @@
char* dirname = get_user_tmp_dir(user_name);
char* filename = get_sharedmem_filename(dirname, vmid);
+ // get the short filename
+ char* short_filename = strrchr(filename, '/');
+ if (short_filename == NULL) {
+ short_filename = filename;
+ } else {
+ short_filename++;
+ }
+
// cleanup any stale shared memory files
cleanup_sharedmem_resources(dirname);
assert(((size > 0) && (size % os::vm_page_size() == 0)),
"unexpected PerfMemory region size");
- fd = create_sharedmem_resources(dirname, filename, size);
+ fd = create_sharedmem_resources(dirname, short_filename, size);
FREE_C_HEAP_ARRAY(char, user_name);
FREE_C_HEAP_ARRAY(char, dirname);
@@ -838,12 +1046,12 @@
// constructs for the file and the shared memory mapping.
if (mode == PerfMemory::PERF_MODE_RO) {
mmap_prot = PROT_READ;
- file_flags = O_RDONLY;
+ file_flags = O_RDONLY | O_NOFOLLOW;
}
else if (mode == PerfMemory::PERF_MODE_RW) {
#ifdef LATER
mmap_prot = PROT_READ | PROT_WRITE;
- file_flags = O_RDWR;
+ file_flags = O_RDWR | O_NOFOLLOW;
#else
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Unsupported access mode");
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -197,7 +197,38 @@
}
-// check if the given path is considered a secure directory for
+// Check if the given statbuf is considered a secure directory for
+// the backing store files. Returns true if the directory is considered
+// a secure location. Returns false if the statbuf is a symbolic link or
+// if an error occurred.
+//
+static bool is_statbuf_secure(struct stat *statp) {
+ if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
+ // The path represents a link or some non-directory file type,
+ // which is not what we expected. Declare it insecure.
+ //
+ return false;
+ }
+ // We have an existing directory, check if the permissions are safe.
+ //
+ if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+ // The directory is open for writing and could be subjected
+ // to a symlink or a hard link attack. Declare it insecure.
+ //
+ return false;
+ }
+ // See if the uid of the directory matches the effective uid of the process.
+ //
+ if (statp->st_uid != geteuid()) {
+ // The directory was not created by this user, declare it insecure.
+ //
+ return false;
+ }
+ return true;
+}
+
+
+// Check if the given path is considered a secure directory for
// the backing store files. Returns true if the directory exists
// and is considered a secure location. Returns false if the path
// is a symbolic link or if an error occurred.
@@ -211,22 +242,180 @@
return false;
}
- // the path exists, now check it's mode
- if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
- // the path represents a link or some non-directory file type,
- // which is not what we expected. declare it insecure.
- //
+ // The path exists, see if it is secure.
+ return is_statbuf_secure(&statbuf);
+}
+
+
+// Check if the given directory file descriptor is considered a secure
+// directory for the backing store files. Returns true if the directory
+// exists and is considered a secure location. Returns false if the path
+// is a symbolic link or if an error occurred.
+//
+static bool is_dirfd_secure(int dir_fd) {
+ struct stat statbuf;
+ int result = 0;
+
+ RESTARTABLE(::fstat(dir_fd, &statbuf), result);
+ if (result == OS_ERR) {
+ return false;
+ }
+
+ // The path exists, now check its mode.
+ return is_statbuf_secure(&statbuf);
+}
+
+
+// Check to make sure fd1 and fd2 are referencing the same file system object.
+//
+static bool is_same_fsobject(int fd1, int fd2) {
+ struct stat statbuf1;
+ struct stat statbuf2;
+ int result = 0;
+
+ RESTARTABLE(::fstat(fd1, &statbuf1), result);
+ if (result == OS_ERR) {
+ return false;
+ }
+ RESTARTABLE(::fstat(fd2, &statbuf2), result);
+ if (result == OS_ERR) {
+ return false;
+ }
+
+ if ((statbuf1.st_ino == statbuf2.st_ino) &&
+ (statbuf1.st_dev == statbuf2.st_dev)) {
+ return true;
+ } else {
return false;
}
- else {
- // we have an existing directory, check if the permissions are safe.
- //
- if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
- // the directory is open for writing and could be subjected
- // to a symlnk attack. declare it insecure.
- //
- return false;
+}
+
+
+// Open the directory of the given path and validate it.
+// Return a DIR * of the open directory.
+//
+static DIR *open_directory_secure(const char* dirname) {
+ // Open the directory using open() so that it can be verified
+ // to be secure by calling is_dirfd_secure(), opendir() and then check
+ // to see if they are the same file system object. This method does not
+ // introduce a window of opportunity for the directory to be attacked that
+ // calling opendir() and is_directory_secure() does.
+ int result;
+ DIR *dirp = NULL;
+ RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ if (errno == ELOOP) {
+ warning("directory %s is a symlink and is not secure\n", dirname);
+ } else {
+ warning("could not open directory %s: %s\n", dirname, strerror(errno));
+ }
}
+ return dirp;
+ }
+ int fd = result;
+
+ // Determine if the open directory is secure.
+ if (!is_dirfd_secure(fd)) {
+ // The directory is not a secure directory.
+ os::close(fd);
+ return dirp;
+ }
+
+ // Open the directory.
+ dirp = ::opendir(dirname);
+ if (dirp == NULL) {
+ // The directory doesn't exist, close fd and return.
+ os::close(fd);
+ return dirp;
+ }
+
+ // Check to make sure fd and dirp are referencing the same file system object.
+ if (!is_same_fsobject(fd, dirfd(dirp))) {
+ // The directory is not secure.
+ os::close(fd);
+ os::closedir(dirp);
+ dirp = NULL;
+ return dirp;
+ }
+
+ // Close initial open now that we know directory is secure
+ os::close(fd);
+
+ return dirp;
+}
+
+// NOTE: The code below uses fchdir(), open() and unlink() because
+// fdopendir(), openat() and unlinkat() are not supported on all
+// versions. Once the support for fdopendir(), openat() and unlinkat()
+// is available on all supported versions the code can be changed
+// to use these functions.
+
+// Open the directory of the given path, validate it and set the
+// current working directory to it.
+// Return a DIR * of the open directory and the saved cwd fd.
+//
+static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
+
+ // Open the directory.
+ DIR* dirp = open_directory_secure(dirname);
+ if (dirp == NULL) {
+ // Directory doesn't exist or is insecure, so there is nothing to cleanup.
+ return dirp;
+ }
+ int fd = dirfd(dirp);
+
+ // Open a fd to the cwd and save it off.
+ int result;
+ RESTARTABLE(::open(".", O_RDONLY), result);
+ if (result == OS_ERR) {
+ *saved_cwd_fd = -1;
+ } else {
+ *saved_cwd_fd = result;
+ }
+
+ // Set the current directory to dirname by using the fd of the directory.
+ result = fchdir(fd);
+
+ return dirp;
+}
+
+// Close the directory and restore the current working directory.
+//
+static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
+
+ int result;
+ // If we have a saved cwd change back to it and close the fd.
+ if (saved_cwd_fd != -1) {
+ result = fchdir(saved_cwd_fd);
+ ::close(saved_cwd_fd);
+ }
+
+ // Close the directory.
+ os::closedir(dirp);
+}
+
+// Check if the given file descriptor is considered a secure.
+//
+static bool is_file_secure(int fd, const char *filename) {
+
+ int result;
+ struct stat statbuf;
+
+ // Determine if the file is secure.
+ RESTARTABLE(::fstat(fd, &statbuf), result);
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ warning("fstat failed on %s: %s\n", filename, strerror(errno));
+ }
+ return false;
+ }
+ if (statbuf.st_nlink > 1) {
+ // A file with multiple links is not expected.
+ if (PrintMiscellaneous && Verbose) {
+ warning("file %s has multiple links\n", filename);
+ }
+ return false;
}
return true;
}
@@ -317,9 +506,11 @@
const char* tmpdirname = os::get_temp_directory();
+ // open the temp directory
DIR* tmpdirp = os::opendir(tmpdirname);
if (tmpdirp == NULL) {
+ // Cannot open the directory to get the user name, return.
return NULL;
}
@@ -344,7 +535,8 @@
strcat(usrdir_name, "/");
strcat(usrdir_name, dentry->d_name);
- DIR* subdirp = os::opendir(usrdir_name);
+ // open the user directory
+ DIR* subdirp = open_directory_secure(usrdir_name);
if (subdirp == NULL) {
FREE_C_HEAP_ARRAY(char, usrdir_name);
@@ -465,26 +657,6 @@
}
-// remove file
-//
-// this method removes the file with the given file name in the
-// named directory.
-//
-static void remove_file(const char* dirname, const char* filename) {
-
- size_t nbytes = strlen(dirname) + strlen(filename) + 2;
- char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
-
- strcpy(path, dirname);
- strcat(path, "/");
- strcat(path, filename);
-
- remove_file(path);
-
- FREE_C_HEAP_ARRAY(char, path);
-}
-
-
// cleanup stale shared memory resources
//
// This method attempts to remove all stale shared memory files in
@@ -496,17 +668,11 @@
//
static void cleanup_sharedmem_resources(const char* dirname) {
- // open the user temp directory
- DIR* dirp = os::opendir(dirname);
-
+ int saved_cwd_fd;
+ // open the directory
+ DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
if (dirp == NULL) {
- // directory doesn't exist, so there is nothing to cleanup
- return;
- }
-
- if (!is_directory_secure(dirname)) {
- // the directory is not a secure directory
- os::closedir(dirp);
+ // directory doesn't exist or is insecure, so there is nothing to cleanup
return;
}
@@ -520,6 +686,7 @@
//
struct dirent* entry;
char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
+
errno = 0;
while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
@@ -528,9 +695,8 @@
if (pid == 0) {
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
-
// attempt to remove all unexpected files, except "." and ".."
- remove_file(dirname, entry->d_name);
+ unlink(entry->d_name);
}
errno = 0;
@@ -552,12 +718,14 @@
//
if ((pid == os::current_process_id()) ||
(kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
-
- remove_file(dirname, entry->d_name);
+ unlink(entry->d_name);
}
errno = 0;
}
- os::closedir(dirp);
+
+ // close the directory and reset the current working directory
+ close_directory_secure_cwd(dirp, saved_cwd_fd);
+
FREE_C_HEAP_ARRAY(char, dbuf);
}
@@ -614,19 +782,54 @@
return -1;
}
- int result;
+ int saved_cwd_fd;
+ // open the directory and set the current working directory to it
+ DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
+ if (dirp == NULL) {
+ // Directory doesn't exist or is insecure, so cannot create shared
+ // memory file.
+ return -1;
+ }
- RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
+ // Open the filename in the current directory.
+ // Cannot use O_TRUNC here; truncation of an existing file has to happen
+ // after the is_file_secure() check below.
+ int result;
+ RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
if (result == OS_ERR) {
if (PrintMiscellaneous && Verbose) {
- warning("could not create file %s: %s\n", filename, strerror(errno));
+ if (errno == ELOOP) {
+ warning("file %s is a symlink and is not secure\n", filename);
+ } else {
+ warning("could not create file %s: %s\n", filename, strerror(errno));
+ }
}
+ // close the directory and reset the current working directory
+ close_directory_secure_cwd(dirp, saved_cwd_fd);
+
return -1;
}
+ // close the directory and reset the current working directory
+ close_directory_secure_cwd(dirp, saved_cwd_fd);
// save the file descriptor
int fd = result;
+ // check to see if the file is secure
+ if (!is_file_secure(fd, filename)) {
+ ::close(fd);
+ return -1;
+ }
+
+ // truncate the file to get rid of any existing data
+ RESTARTABLE(::ftruncate(fd, (off_t)0), result);
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ warning("could not truncate shared memory file: %s\n", strerror(errno));
+ }
+ ::close(fd);
+ return -1;
+ }
// set the file size
RESTARTABLE(::ftruncate(fd, (off_t)size), result);
if (result == OS_ERR) {
@@ -684,8 +887,15 @@
THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
}
}
+ int fd = result;
- return result;
+ // check to see if the file is secure
+ if (!is_file_secure(fd, filename)) {
+ ::close(fd);
+ return -1;
+ }
+
+ return fd;
}
// create a named shared memory region. returns the address of the
@@ -716,6 +926,13 @@
char* dirname = get_user_tmp_dir(user_name);
char* filename = get_sharedmem_filename(dirname, vmid);
+ // get the short filename
+ char* short_filename = strrchr(filename, '/');
+ if (short_filename == NULL) {
+ short_filename = filename;
+ } else {
+ short_filename++;
+ }
// cleanup any stale shared memory files
cleanup_sharedmem_resources(dirname);
@@ -723,7 +940,7 @@
assert(((size > 0) && (size % os::vm_page_size() == 0)),
"unexpected PerfMemory region size");
- fd = create_sharedmem_resources(dirname, filename, size);
+ fd = create_sharedmem_resources(dirname, short_filename, size);
FREE_C_HEAP_ARRAY(char, user_name);
FREE_C_HEAP_ARRAY(char, dirname);
@@ -838,12 +1055,12 @@
// constructs for the file and the shared memory mapping.
if (mode == PerfMemory::PERF_MODE_RO) {
mmap_prot = PROT_READ;
- file_flags = O_RDONLY;
+ file_flags = O_RDONLY | O_NOFOLLOW;
}
else if (mode == PerfMemory::PERF_MODE_RW) {
#ifdef LATER
mmap_prot = PROT_READ | PROT_WRITE;
- file_flags = O_RDWR;
+ file_flags = O_RDWR | O_NOFOLLOW;
#else
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Unsupported access mode");
--- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -199,7 +199,38 @@
}
-// check if the given path is considered a secure directory for
+// Check if the given statbuf is considered a secure directory for
+// the backing store files. Returns true if the directory is considered
+// a secure location. Returns false if the statbuf is a symbolic link or
+// if an error occurred.
+//
+static bool is_statbuf_secure(struct stat *statp) {
+ if (S_ISLNK(statp->st_mode) || !S_ISDIR(statp->st_mode)) {
+ // The path represents a link or some non-directory file type,
+ // which is not what we expected. Declare it insecure.
+ //
+ return false;
+ }
+ // We have an existing directory, check if the permissions are safe.
+ //
+ if ((statp->st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+ // The directory is open for writing and could be subjected
+ // to a symlink or a hard link attack. Declare it insecure.
+ //
+ return false;
+ }
+ // See if the uid of the directory matches the effective uid of the process.
+ //
+ if (statp->st_uid != geteuid()) {
+ // The directory was not created by this user, declare it insecure.
+ //
+ return false;
+ }
+ return true;
+}
+
+
+// Check if the given path is considered a secure directory for
// the backing store files. Returns true if the directory exists
// and is considered a secure location. Returns false if the path
// is a symbolic link or if an error occurred.
@@ -213,27 +244,185 @@
return false;
}
- // the path exists, now check it's mode
- if (S_ISLNK(statbuf.st_mode) || !S_ISDIR(statbuf.st_mode)) {
- // the path represents a link or some non-directory file type,
- // which is not what we expected. declare it insecure.
- //
+ // The path exists, see if it is secure.
+ return is_statbuf_secure(&statbuf);
+}
+
+
+// Check if the given directory file descriptor is considered a secure
+// directory for the backing store files. Returns true if the directory
+// exists and is considered a secure location. Returns false if the path
+// is a symbolic link or if an error occurred.
+//
+static bool is_dirfd_secure(int dir_fd) {
+ struct stat statbuf;
+ int result = 0;
+
+ RESTARTABLE(::fstat(dir_fd, &statbuf), result);
+ if (result == OS_ERR) {
+ return false;
+ }
+
+ // The path exists, now check its mode.
+ return is_statbuf_secure(&statbuf);
+}
+
+
+// Check to make sure fd1 and fd2 are referencing the same file system object.
+//
+static bool is_same_fsobject(int fd1, int fd2) {
+ struct stat statbuf1;
+ struct stat statbuf2;
+ int result = 0;
+
+ RESTARTABLE(::fstat(fd1, &statbuf1), result);
+ if (result == OS_ERR) {
+ return false;
+ }
+ RESTARTABLE(::fstat(fd2, &statbuf2), result);
+ if (result == OS_ERR) {
+ return false;
+ }
+
+ if ((statbuf1.st_ino == statbuf2.st_ino) &&
+ (statbuf1.st_dev == statbuf2.st_dev)) {
+ return true;
+ } else {
return false;
}
- else {
- // we have an existing directory, check if the permissions are safe.
- //
- if ((statbuf.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
- // the directory is open for writing and could be subjected
- // to a symlnk attack. declare it insecure.
- //
- return false;
+}
+
+
+// Open the directory of the given path and validate it.
+// Return a DIR * of the open directory.
+//
+static DIR *open_directory_secure(const char* dirname) {
+ // Open the directory using open() so that it can be verified
+ // to be secure by calling is_dirfd_secure(), opendir() and then check
+ // to see if they are the same file system object. This method does not
+ // introduce a window of opportunity for the directory to be attacked that
+ // calling opendir() and is_directory_secure() does.
+ int result;
+ DIR *dirp = NULL;
+ RESTARTABLE(::open(dirname, O_RDONLY|O_NOFOLLOW), result);
+ if (result == OS_ERR) {
+ // Directory doesn't exist or is a symlink, so there is nothing to cleanup.
+ if (PrintMiscellaneous && Verbose) {
+ if (errno == ELOOP) {
+ warning("directory %s is a symlink and is not secure\n", dirname);
+ } else {
+ warning("could not open directory %s: %s\n", dirname, strerror(errno));
+ }
}
+ return dirp;
+ }
+ int fd = result;
+
+ // Determine if the open directory is secure.
+ if (!is_dirfd_secure(fd)) {
+ // The directory is not a secure directory.
+ os::close(fd);
+ return dirp;
+ }
+
+ // Open the directory.
+ dirp = ::opendir(dirname);
+ if (dirp == NULL) {
+ // The directory doesn't exist, close fd and return.
+ os::close(fd);
+ return dirp;
+ }
+
+ // Check to make sure fd and dirp are referencing the same file system object.
+ if (!is_same_fsobject(fd, dirp->dd_fd)) {
+ // The directory is not secure.
+ os::close(fd);
+ os::closedir(dirp);
+ dirp = NULL;
+ return dirp;
+ }
+
+ // Close initial open now that we know directory is secure
+ os::close(fd);
+
+ return dirp;
+}
+
+// NOTE: The code below uses fchdir(), open() and unlink() because
+// fdopendir(), openat() and unlinkat() are not supported on all
+// versions. Once the support for fdopendir(), openat() and unlinkat()
+// is available on all supported versions the code can be changed
+// to use these functions.
+
+// Open the directory of the given path, validate it and set the
+// current working directory to it.
+// Return a DIR * of the open directory and the saved cwd fd.
+//
+static DIR *open_directory_secure_cwd(const char* dirname, int *saved_cwd_fd) {
+
+ // Open the directory.
+ DIR* dirp = open_directory_secure(dirname);
+ if (dirp == NULL) {
+ // Directory doesn't exist or is insecure, so there is nothing to cleanup.
+ return dirp;
+ }
+ int fd = dirp->dd_fd;
+
+ // Open a fd to the cwd and save it off.
+ int result;
+ RESTARTABLE(::open(".", O_RDONLY), result);
+ if (result == OS_ERR) {
+ *saved_cwd_fd = -1;
+ } else {
+ *saved_cwd_fd = result;
+ }
+
+ // Set the current directory to dirname by using the fd of the directory.
+ result = fchdir(fd);
+
+ return dirp;
+}
+
+// Close the directory and restore the current working directory.
+//
+static void close_directory_secure_cwd(DIR* dirp, int saved_cwd_fd) {
+
+ int result;
+ // If we have a saved cwd change back to it and close the fd.
+ if (saved_cwd_fd != -1) {
+ result = fchdir(saved_cwd_fd);
+ ::close(saved_cwd_fd);
+ }
+
+ // Close the directory.
+ os::closedir(dirp);
+}
+
+// Check if the given file descriptor is considered a secure.
+//
+static bool is_file_secure(int fd, const char *filename) {
+
+ int result;
+ struct stat statbuf;
+
+ // Determine if the file is secure.
+ RESTARTABLE(::fstat(fd, &statbuf), result);
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ warning("fstat failed on %s: %s\n", filename, strerror(errno));
+ }
+ return false;
+ }
+ if (statbuf.st_nlink > 1) {
+ // A file with multiple links is not expected.
+ if (PrintMiscellaneous && Verbose) {
+ warning("file %s has multiple links\n", filename);
+ }
+ return false;
}
return true;
}
-
// return the user name for the given user id
//
// the caller is expected to free the allocated memory.
@@ -308,9 +497,11 @@
const char* tmpdirname = os::get_temp_directory();
+ // open the temp directory
DIR* tmpdirp = os::opendir(tmpdirname);
if (tmpdirp == NULL) {
+ // Cannot open the directory to get the user name, return.
return NULL;
}
@@ -335,7 +526,8 @@
strcat(usrdir_name, "/");
strcat(usrdir_name, dentry->d_name);
- DIR* subdirp = os::opendir(usrdir_name);
+ // open the user directory
+ DIR* subdirp = open_directory_secure(usrdir_name);
if (subdirp == NULL) {
FREE_C_HEAP_ARRAY(char, usrdir_name);
@@ -504,26 +696,6 @@
}
-// remove file
-//
-// this method removes the file with the given file name in the
-// named directory.
-//
-static void remove_file(const char* dirname, const char* filename) {
-
- size_t nbytes = strlen(dirname) + strlen(filename) + 2;
- char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
-
- strcpy(path, dirname);
- strcat(path, "/");
- strcat(path, filename);
-
- remove_file(path);
-
- FREE_C_HEAP_ARRAY(char, path);
-}
-
-
// cleanup stale shared memory resources
//
// This method attempts to remove all stale shared memory files in
@@ -535,17 +707,11 @@
//
static void cleanup_sharedmem_resources(const char* dirname) {
- // open the user temp directory
- DIR* dirp = os::opendir(dirname);
-
+ int saved_cwd_fd;
+ // open the directory
+ DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
if (dirp == NULL) {
- // directory doesn't exist, so there is nothing to cleanup
- return;
- }
-
- if (!is_directory_secure(dirname)) {
- // the directory is not a secure directory
- os::closedir(dirp);
+ // directory doesn't exist or is insecure, so there is nothing to cleanup
return;
}
@@ -559,6 +725,7 @@
//
struct dirent* entry;
char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
+
errno = 0;
while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
@@ -569,7 +736,7 @@
if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
// attempt to remove all unexpected files, except "." and ".."
- remove_file(dirname, entry->d_name);
+ unlink(entry->d_name);
}
errno = 0;
@@ -592,11 +759,14 @@
if ((pid == os::current_process_id()) ||
(kill(pid, 0) == OS_ERR && (errno == ESRCH || errno == EPERM))) {
- remove_file(dirname, entry->d_name);
+ unlink(entry->d_name);
}
errno = 0;
}
- os::closedir(dirp);
+
+ // close the directory and reset the current working directory
+ close_directory_secure_cwd(dirp, saved_cwd_fd);
+
FREE_C_HEAP_ARRAY(char, dbuf);
}
@@ -653,19 +823,54 @@
return -1;
}
- int result;
+ int saved_cwd_fd;
+ // open the directory and set the current working directory to it
+ DIR* dirp = open_directory_secure_cwd(dirname, &saved_cwd_fd);
+ if (dirp == NULL) {
+ // Directory doesn't exist or is insecure, so cannot create shared
+ // memory file.
+ return -1;
+ }
- RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE), result);
+ // Open the filename in the current directory.
+ // Cannot use O_TRUNC here; truncation of an existing file has to happen
+ // after the is_file_secure() check below.
+ int result;
+ RESTARTABLE(::open(filename, O_RDWR|O_CREAT|O_NOFOLLOW, S_IREAD|S_IWRITE), result);
if (result == OS_ERR) {
if (PrintMiscellaneous && Verbose) {
- warning("could not create file %s: %s\n", filename, strerror(errno));
+ if (errno == ELOOP) {
+ warning("file %s is a symlink and is not secure\n", filename);
+ } else {
+ warning("could not create file %s: %s\n", filename, strerror(errno));
+ }
}
+ // close the directory and reset the current working directory
+ close_directory_secure_cwd(dirp, saved_cwd_fd);
+
return -1;
}
+ // close the directory and reset the current working directory
+ close_directory_secure_cwd(dirp, saved_cwd_fd);
// save the file descriptor
int fd = result;
+ // check to see if the file is secure
+ if (!is_file_secure(fd, filename)) {
+ ::close(fd);
+ return -1;
+ }
+
+ // truncate the file to get rid of any existing data
+ RESTARTABLE(::ftruncate(fd, (off_t)0), result);
+ if (result == OS_ERR) {
+ if (PrintMiscellaneous && Verbose) {
+ warning("could not truncate shared memory file: %s\n", strerror(errno));
+ }
+ ::close(fd);
+ return -1;
+ }
// set the file size
RESTARTABLE(::ftruncate(fd, (off_t)size), result);
if (result == OS_ERR) {
@@ -701,8 +906,15 @@
THROW_MSG_(vmSymbols::java_io_IOException(), strerror(errno), OS_ERR);
}
}
+ int fd = result;
- return result;
+ // check to see if the file is secure
+ if (!is_file_secure(fd, filename)) {
+ ::close(fd);
+ return -1;
+ }
+
+ return fd;
}
// create a named shared memory region. returns the address of the
@@ -734,13 +946,21 @@
char* dirname = get_user_tmp_dir(user_name);
char* filename = get_sharedmem_filename(dirname, vmid);
+ // get the short filename
+ char* short_filename = strrchr(filename, '/');
+ if (short_filename == NULL) {
+ short_filename = filename;
+ } else {
+ short_filename++;
+ }
+
// cleanup any stale shared memory files
cleanup_sharedmem_resources(dirname);
assert(((size > 0) && (size % os::vm_page_size() == 0)),
"unexpected PerfMemory region size");
- fd = create_sharedmem_resources(dirname, filename, size);
+ fd = create_sharedmem_resources(dirname, short_filename, size);
FREE_C_HEAP_ARRAY(char, user_name);
FREE_C_HEAP_ARRAY(char, dirname);
@@ -856,12 +1076,12 @@
// constructs for the file and the shared memory mapping.
if (mode == PerfMemory::PERF_MODE_RO) {
mmap_prot = PROT_READ;
- file_flags = O_RDONLY;
+ file_flags = O_RDONLY | O_NOFOLLOW;
}
else if (mode == PerfMemory::PERF_MODE_RW) {
#ifdef LATER
mmap_prot = PROT_READ | PROT_WRITE;
- file_flags = O_RDWR;
+ file_flags = O_RDWR | O_NOFOLLOW;
#else
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Unsupported access mode");
--- a/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007, 2008, 2011 Red Hat, Inc.
+ * Copyright 2007, 2008, 2011, 2015, Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -237,7 +237,13 @@
// operation. Note that some platforms only support this with the
// limitation that the only valid value to store is the immediate
// constant 1. There is a test for this in JNI_CreateJavaVM().
- return __sync_lock_test_and_set (dest, exchange_value);
+ jint result = __sync_lock_test_and_set (dest, exchange_value);
+ // All atomic operations are expected to be full memory barriers
+ // (see atomic.hpp). However, __sync_lock_test_and_set is not
+ // a full memory barrier, but an acquire barrier. Hence, this added
+ // barrier.
+ __sync_synchronize();
+ return result;
#endif // M68K
#endif // ARM
}
@@ -250,7 +256,9 @@
#ifdef M68K
return m68k_lock_test_and_set(dest, exchange_value);
#else
- return __sync_lock_test_and_set (dest, exchange_value);
+ intptr_t result = __sync_lock_test_and_set (dest, exchange_value);
+ __sync_synchronize();
+ return result;
#endif // M68K
#endif // ARM
}
--- a/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2007, 2008, 2011 Red Hat, Inc.
+ * Copyright 2007, 2008, 2011, 2015, Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -231,7 +231,13 @@
// operation. Note that some platforms only support this with the
// limitation that the only valid value to store is the immediate
// constant 1. There is a test for this in JNI_CreateJavaVM().
- return __sync_lock_test_and_set (dest, exchange_value);
+ jint result = __sync_lock_test_and_set (dest, exchange_value);
+ // All atomic operations are expected to be full memory barriers
+ // (see atomic.hpp). However, __sync_lock_test_and_set is not
+ // a full memory barrier, but an acquire barrier. Hence, this added
+ // barrier.
+ __sync_synchronize();
+ return result;
#endif // M68K
#endif // ARM
}
@@ -244,7 +250,9 @@
#ifdef M68K
return m68k_lock_test_and_set(dest, exchange_value);
#else
- return __sync_lock_test_and_set (dest, exchange_value);
+ intptr_t result = __sync_lock_test_and_set (dest, exchange_value);
+ __sync_synchronize();
+ return result;
#endif // M68K
#endif // ARM
}
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -89,8 +89,8 @@
public:
ArgumentMap *_vars;
ArgumentMap *_stack;
- short _stack_height;
- short _max_stack;
+ int _stack_height;
+ int _max_stack;
bool _initialized;
ArgumentMap empty_map;
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
//
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -64,6 +64,7 @@
ciConstantPoolCache* _field_cache; // cached map index->field
GrowableArray<ciField*>* _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, "");
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/compactHashtable.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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 <sys/stat.h>
+
+/////////////////////////////////////////////////////
+//
+// 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 <class T, class N> const char* CompactHashtable<T, N>::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<Symbol*, char>;
+
+#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<count; i++) {
+ char c = *from++;
+ switch (c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ value = (value << 4) + c - '0';
+ break;
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ value = (value << 4) + 10 + c - 'a';
+ break;
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ value = (value << 4) + 10 + c - 'A';
+ break;
+ default:
+ ShouldNotReachHere();
+ }
+ }
+ return value;
+}
+
+void HashtableTextDump::get_utf8(char* utf8_buffer, int utf8_length) {
+ // cache in local vars
+ const char* from = _p;
+ const char* end = _end;
+ char* to = utf8_buffer;
+ int n = utf8_length;
+
+ for (; n > 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);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/compactHashtable.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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<mtSymbol> {
+ 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 T, class N> 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<bool> _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<bool> _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
--- a/hotspot/src/share/vm/classfile/stringTable.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/classfile/stringTable.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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<oop, mtSymbol>* 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;
+ }
+}
--- a/hotspot/src/share/vm/classfile/stringTable.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/classfile/stringTable.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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,
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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<Symbol*, char> 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<Symbol*, mtSymbol>* 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<Symbol*, mtSymbol>* 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<Symbol*, mtSymbol>* 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;
+ }
+}
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -73,6 +73,8 @@
operator Symbol*() { return _temp; }
};
+template <class T, class N> class CompactHashtable;
+
class SymbolTable : public RehashableHashtable<Symbol*, mtSymbol> {
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<Symbol*, char> _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<mtSymbol>* 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<Symbol*, mtSymbol>::copy_buckets(top, end);
- }
- static void copy_table(char** top, char*end) {
- the_table()->Hashtable<Symbol*, mtSymbol>::copy_table(top, end);
- }
- static void reverse(void* boundary = NULL) {
- the_table()->Hashtable<Symbol*, mtSymbol>::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();
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
// ----------------------------------------------------------------------------
@@ -1904,11 +1905,12 @@
InstanceKlass::cast(WK_KLASS(Reference_klass))->set_reference_type(REF_OTHER);
InstanceRefKlass::update_nonstatic_oop_maps(WK_KLASS(Reference_klass));
- initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(PhantomReference_klass), scan, CHECK);
+ initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Cleaner_klass), scan, CHECK);
InstanceKlass::cast(WK_KLASS(SoftReference_klass))->set_reference_type(REF_SOFT);
InstanceKlass::cast(WK_KLASS(WeakReference_klass))->set_reference_type(REF_WEAK);
InstanceKlass::cast(WK_KLASS(FinalReference_klass))->set_reference_type(REF_FINAL);
InstanceKlass::cast(WK_KLASS(PhantomReference_klass))->set_reference_type(REF_PHANTOM);
+ InstanceKlass::cast(WK_KLASS(Cleaner_klass))->set_reference_type(REF_CLEANER);
// JSR 292 classes
WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass);
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -128,6 +128,7 @@
do_klass(WeakReference_klass, java_lang_ref_WeakReference, Pre ) \
do_klass(FinalReference_klass, java_lang_ref_FinalReference, Pre ) \
do_klass(PhantomReference_klass, java_lang_ref_PhantomReference, Pre ) \
+ do_klass(Cleaner_klass, sun_misc_Cleaner, Pre ) \
do_klass(Finalizer_klass, java_lang_ref_Finalizer, Pre ) \
\
do_klass(Thread_klass, java_lang_Thread, Pre ) \
--- a/hotspot/src/share/vm/classfile/verifier.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1555,14 +1555,14 @@
case Bytecodes::_invokespecial :
case Bytecodes::_invokestatic :
verify_invoke_instructions(
- &bcs, code_length, ¤t_frame,
- &this_uninit, return_type, cp, CHECK_VERIFY(this));
+ &bcs, code_length, ¤t_frame, (bci >= ex_min && bci < ex_max),
+ &this_uninit, return_type, cp, &stackmap_table, CHECK_VERIFY(this));
no_control_flow = false; break;
case Bytecodes::_invokeinterface :
case Bytecodes::_invokedynamic :
verify_invoke_instructions(
- &bcs, code_length, ¤t_frame,
- &this_uninit, return_type, cp, CHECK_VERIFY(this));
+ &bcs, code_length, ¤t_frame, (bci >= ex_min && bci < ex_max),
+ &this_uninit, return_type, cp, &stackmap_table, CHECK_VERIFY(this));
no_control_flow = false; break;
case Bytecodes::_new :
{
@@ -2406,8 +2406,9 @@
void ClassVerifier::verify_invoke_init(
RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type,
- StackMapFrame* current_frame, u4 code_length, bool *this_uninit,
- constantPoolHandle cp, TRAPS) {
+ StackMapFrame* current_frame, u4 code_length, bool in_try_block,
+ bool *this_uninit, constantPoolHandle cp, StackMapTable* stackmap_table,
+ TRAPS) {
u2 bci = bcs->bci();
VerificationType type = current_frame->pop_stack(
VerificationType::reference_check(), CHECK_VERIFY(this));
@@ -2423,28 +2424,36 @@
return;
}
- // Check if this call is done from inside of a TRY block. If so, make
- // sure that all catch clause paths end in a throw. Otherwise, this
- // can result in returning an incomplete object.
- ExceptionTable exhandlers(_method());
- int exlength = exhandlers.length();
- for(int i = 0; i < exlength; i++) {
- u2 start_pc = exhandlers.start_pc(i);
- u2 end_pc = exhandlers.end_pc(i);
+ // If this invokespecial call is done from inside of a TRY block then make
+ // sure that all catch clause paths end in a throw. Otherwise, this can
+ // result in returning an incomplete object.
+ if (in_try_block) {
+ ExceptionTable exhandlers(_method());
+ int exlength = exhandlers.length();
+ for(int i = 0; i < exlength; i++) {
+ u2 start_pc = exhandlers.start_pc(i);
+ u2 end_pc = exhandlers.end_pc(i);
- if (bci >= start_pc && bci < end_pc) {
- if (!ends_in_athrow(exhandlers.handler_pc(i))) {
- verify_error(ErrorContext::bad_code(bci),
- "Bad <init> method call from after the start of a try block");
- return;
- } else if (VerboseVerification) {
- ResourceMark rm;
- tty->print_cr(
- "Survived call to ends_in_athrow(): %s",
- current_class()->name()->as_C_string());
+ if (bci >= start_pc && bci < end_pc) {
+ if (!ends_in_athrow(exhandlers.handler_pc(i))) {
+ verify_error(ErrorContext::bad_code(bci),
+ "Bad <init> method call from after the start of a try block");
+ return;
+ } else if (VerboseVerification) {
+ ResourceMark rm;
+ tty->print_cr(
+ "Survived call to ends_in_athrow(): %s",
+ current_class()->name()->as_C_string());
+ }
}
}
- }
+
+ // Check the exception handler target stackmaps with the locals from the
+ // incoming stackmap (before initialize_object() changes them to outgoing
+ // state).
+ verify_exception_handler_targets(bci, true, current_frame,
+ stackmap_table, CHECK_VERIFY(this));
+ } // in_try_block
current_frame->initialize_object(type, current_type());
*this_uninit = true;
@@ -2477,8 +2486,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()),
@@ -2499,6 +2507,13 @@
}
}
}
+ // Check the exception handler target stackmaps with the locals from the
+ // incoming stackmap (before initialize_object() changes them to outgoing
+ // state).
+ if (in_try_block) {
+ verify_exception_handler_targets(bci, *this_uninit, current_frame,
+ stackmap_table, CHECK_VERIFY(this));
+ }
current_frame->initialize_object(type, new_class_type);
} else {
verify_error(ErrorContext::bad_type(bci, current_frame->stack_top_ctx()),
@@ -2527,8 +2542,8 @@
void ClassVerifier::verify_invoke_instructions(
RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
- bool *this_uninit, VerificationType return_type,
- constantPoolHandle cp, TRAPS) {
+ bool in_try_block, bool *this_uninit, VerificationType return_type,
+ constantPoolHandle cp, StackMapTable* stackmap_table, TRAPS) {
// Make sure the constant pool item is the right type
u2 index = bcs->get_index_u2();
Bytecodes::Code opcode = bcs->raw_code();
@@ -2694,7 +2709,8 @@
opcode != Bytecodes::_invokedynamic) {
if (method_name == vmSymbols::object_initializer_name()) { // <init> method
verify_invoke_init(bcs, index, ref_class_type, current_frame,
- code_length, this_uninit, cp, CHECK_VERIFY(this));
+ code_length, in_try_block, this_uninit, cp, stackmap_table,
+ CHECK_VERIFY(this));
} else { // other methods
// Ensures that target class is assignable to method class.
if (opcode == Bytecodes::_invokespecial) {
--- a/hotspot/src/share/vm/classfile/verifier.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/classfile/verifier.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -301,8 +301,9 @@
void verify_invoke_init(
RawBytecodeStream* bcs, u2 ref_index, VerificationType ref_class_type,
- StackMapFrame* current_frame, u4 code_length, bool* this_uninit,
- constantPoolHandle cp, TRAPS);
+ StackMapFrame* current_frame, u4 code_length, bool in_try_block,
+ bool* this_uninit, constantPoolHandle cp, StackMapTable* stackmap_table,
+ TRAPS);
// Used by ends_in_athrow() to push all handlers that contain bci onto
// the handler_stack, if the handler is not already on the stack.
@@ -316,8 +317,8 @@
void verify_invoke_instructions(
RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
- bool* this_uninit, VerificationType return_type,
- constantPoolHandle cp, TRAPS);
+ bool in_try_block, bool* this_uninit, VerificationType return_type,
+ constantPoolHandle cp, StackMapTable* stackmap_table, TRAPS);
VerificationType get_newarray_type(u2 index, u2 bci, TRAPS);
void verify_anewarray(u2 bci, u2 index, constantPoolHandle cp,
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -79,6 +79,7 @@
template(java_lang_ref_WeakReference, "java/lang/ref/WeakReference") \
template(java_lang_ref_FinalReference, "java/lang/ref/FinalReference") \
template(java_lang_ref_PhantomReference, "java/lang/ref/PhantomReference") \
+ template(sun_misc_Cleaner, "sun/misc/Cleaner") \
template(java_lang_ref_Finalizer, "java/lang/ref/Finalizer") \
template(java_lang_reflect_AccessibleObject, "java/lang/reflect/AccessibleObject") \
template(java_lang_reflect_Method, "java/lang/reflect/Method") \
--- a/hotspot/src/share/vm/code/codeCache.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/code/codeCache.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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) {
--- a/hotspot/src/share/vm/code/codeCache.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/code/codeCache.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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();
--- a/hotspot/src/share/vm/code/dependencies.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/code/dependencies.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -560,7 +560,7 @@
put_star = !Dependencies::is_concrete_klass((Klass*)arg.metadata_value());
} else if (arg.is_method()) {
what = "method ";
- put_star = !Dependencies::is_concrete_method((Method*)arg.metadata_value());
+ put_star = !Dependencies::is_concrete_method((Method*)arg.metadata_value(), NULL);
} else if (arg.is_klass()) {
what = "class ";
} else {
@@ -878,8 +878,8 @@
// Static methods don't override non-static so punt
return true;
}
- if ( !Dependencies::is_concrete_method(lm)
- && !Dependencies::is_concrete_method(m)
+ if ( !Dependencies::is_concrete_method(lm, k)
+ && !Dependencies::is_concrete_method(m, ctxk)
&& lm->method_holder()->is_subtype_of(m->method_holder()))
// Method m is overridden by lm, but both are non-concrete.
return true;
@@ -915,8 +915,17 @@
} else if (!k->oop_is_instance()) {
return false; // no methods to find in an array type
} else {
- Method* m = InstanceKlass::cast(k)->find_method(_name, _signature);
- if (m == NULL || !Dependencies::is_concrete_method(m)) return false;
+ // Search class hierarchy first.
+ Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature);
+ if (!Dependencies::is_concrete_method(m, k)) {
+ // Check interface defaults also, if any exist.
+ Array<Method*>* default_methods = InstanceKlass::cast(k)->default_methods();
+ if (default_methods == NULL)
+ return false;
+ m = InstanceKlass::cast(k)->find_method(default_methods, _name, _signature);
+ if (!Dependencies::is_concrete_method(m, NULL))
+ return false;
+ }
_found_methods[_num_participants] = m;
// Note: If add_participant(k) is called,
// the method m will already be memoized for it.
@@ -1209,15 +1218,17 @@
return true;
}
-bool Dependencies::is_concrete_method(Method* m) {
- // Statics are irrelevant to virtual call sites.
- if (m->is_static()) return false;
-
- // We could also return false if m does not yet appear to be
- // executed, if the VM version supports this distinction also.
- // Default methods are considered "concrete" as well.
- return !m->is_abstract() &&
- !m->is_overpass(); // error functions aren't concrete
+bool Dependencies::is_concrete_method(Method* m, Klass * k) {
+ // NULL is not a concrete method,
+ // statics are irrelevant to virtual call sites,
+ // abstract methods are not concrete,
+ // overpass (error) methods are not concrete if k is abstract
+ //
+ // note "true" is conservative answer --
+ // overpass clause is false if k == NULL, implies return true if
+ // answer depends on overpass clause.
+ return ! ( m == NULL || m -> is_static() || m -> is_abstract() ||
+ m->is_overpass() && k != NULL && k -> is_abstract() );
}
@@ -1242,16 +1253,6 @@
return true;
}
-bool Dependencies::is_concrete_method(ciMethod* m) {
- // Statics are irrelevant to virtual call sites.
- if (m->is_static()) return false;
-
- // We could also return false if m does not yet appear to be
- // executed, if the VM version supports this distinction also.
- return !m->is_abstract();
-}
-
-
bool Dependencies::has_finalizable_subclass(ciInstanceKlass* k) {
return k->has_finalizable_subclass();
}
@@ -1469,7 +1470,7 @@
Klass* wit = wf.find_witness_definer(ctxk);
if (wit != NULL) return NULL; // Too many witnesses.
Method* fm = wf.found_method(0); // Will be NULL if num_parts == 0.
- if (Dependencies::is_concrete_method(m)) {
+ if (Dependencies::is_concrete_method(m, ctxk)) {
if (fm == NULL) {
// It turns out that m was always the only implementation.
fm = m;
@@ -1499,61 +1500,6 @@
return wf.find_witness_definer(ctxk, changes);
}
-// Find the set of all non-abstract methods under ctxk that match m[0].
-// (The method m[0] must be defined or inherited in ctxk.)
-// Include m itself in the set, unless it is abstract.
-// Fill the given array m[0..(mlen-1)] with this set, and return the length.
-// (The length may be zero if no concrete methods are found anywhere.)
-// If there are too many concrete methods to fit in marray, return -1.
-int Dependencies::find_exclusive_concrete_methods(Klass* ctxk,
- int mlen,
- Method* marray[]) {
- Method* m0 = marray[0];
- ClassHierarchyWalker wf(m0);
- assert(wf.check_method_context(ctxk, m0), "proper context");
- wf.record_witnesses(mlen);
- bool participants_hide_witnesses = true;
- Klass* wit = wf.find_witness_definer(ctxk);
- if (wit != NULL) return -1; // Too many witnesses.
- int num = wf.num_participants();
- assert(num <= mlen, "oob");
- // Keep track of whether m is also part of the result set.
- int mfill = 0;
- assert(marray[mfill] == m0, "sanity");
- if (Dependencies::is_concrete_method(m0))
- mfill++; // keep m0 as marray[0], the first result
- for (int i = 0; i < num; i++) {
- Method* fm = wf.found_method(i);
- if (fm == m0) continue; // Already put this guy in the list.
- if (mfill == mlen) {
- return -1; // Oops. Too many methods after all!
- }
- marray[mfill++] = fm;
- }
-#ifndef PRODUCT
- // Make sure the dependency mechanism will pass this discovery:
- if (VerifyDependencies) {
- // Turn off dependency tracing while actually testing deps.
- FlagSetting fs(TraceDependencies, false);
- switch (mfill) {
- case 1:
- guarantee(NULL == (void *)check_unique_concrete_method(ctxk, marray[0]),
- "verify dep.");
- break;
- case 2:
- guarantee(NULL == (void *)
- check_exclusive_concrete_methods(ctxk, marray[0], marray[1]),
- "verify dep.");
- break;
- default:
- ShouldNotReachHere(); // mlen > 2 yet supported
- }
- }
-#endif //PRODUCT
- return mfill;
-}
-
-
Klass* Dependencies::check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes) {
Klass* search_at = ctxk;
if (changes != NULL)
@@ -1561,7 +1507,6 @@
return find_finalizable_subclass(search_at);
}
-
Klass* Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) {
assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "sanity");
assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity");
--- a/hotspot/src/share/vm/code/dependencies.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/code/dependencies.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -288,7 +288,7 @@
// In that case, there would be a middle ground between concrete
// and abstract (as defined by the Java language and VM).
static bool is_concrete_klass(Klass* k); // k is instantiable
- static bool is_concrete_method(Method* m); // m is invocable
+ static bool is_concrete_method(Method* m, Klass* k); // m is invocable
static Klass* find_finalizable_subclass(Klass* k);
// These versions of the concreteness queries work through the CI.
@@ -302,7 +302,6 @@
// not go back into the VM to get their value; they must cache the
// bit in the CI, either eagerly or lazily.)
static bool is_concrete_klass(ciInstanceKlass* k); // k appears instantiable
- static bool is_concrete_method(ciMethod* m); // m appears invocable
static bool has_finalizable_subclass(ciInstanceKlass* k);
// As a general rule, it is OK to compile under the assumption that
@@ -349,7 +348,6 @@
static Klass* find_unique_concrete_subtype(Klass* ctxk);
static Method* find_unique_concrete_method(Klass* ctxk, Method* m);
static int find_exclusive_concrete_subtypes(Klass* ctxk, int klen, Klass* k[]);
- static int find_exclusive_concrete_methods(Klass* ctxk, int mlen, Method* m[]);
// Create the encoding which will be stored in an nmethod.
void encode_content_bytes();
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -252,7 +252,7 @@
} else {
task = new CompileTask();
DEBUG_ONLY(_num_allocated_tasks++;)
- assert (_num_allocated_tasks < 10000, "Leaking compilation tasks?");
+ assert (WhiteBoxAPI || _num_allocated_tasks < 10000, "Leaking compilation tasks?");
task->set_next(NULL);
task->set_is_free(true);
}
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -105,7 +105,6 @@
tty->print(".");
print_symbol(method_name(), _method_mode);
if (signature() != NULL) {
- tty->print(" ");
signature()->print_symbol_on(tty);
}
}
@@ -467,43 +466,85 @@
return UnknownCommand;
}
-
static void usage() {
- tty->print_cr(" CompileCommand and the CompilerOracle allows simple control over");
- tty->print_cr(" what's allowed to be compiled. The standard supported directives");
- tty->print_cr(" are exclude and compileonly. The exclude directive stops a method");
- tty->print_cr(" from being compiled and compileonly excludes all methods except for");
- tty->print_cr(" the ones mentioned by compileonly directives. The basic form of");
- tty->print_cr(" all commands is a command name followed by the name of the method");
- tty->print_cr(" in one of two forms: the standard class file format as in");
- tty->print_cr(" class/name.methodName or the PrintCompilation format");
- tty->print_cr(" class.name::methodName. The method name can optionally be followed");
- tty->print_cr(" by a space then the signature of the method in the class file");
- tty->print_cr(" format. Otherwise the directive applies to all methods with the");
- tty->print_cr(" same name and class regardless of signature. Leading and trailing");
- tty->print_cr(" *'s in the class and/or method name allows a small amount of");
- tty->print_cr(" wildcarding. ");
+ tty->cr();
+ tty->print_cr("The CompileCommand option enables the user of the JVM to control specific");
+ tty->print_cr("behavior of the dynamic compilers. Many commands require a pattern that defines");
+ tty->print_cr("the set of methods the command shall be applied to. The CompileCommand");
+ tty->print_cr("option provides the following commands:");
tty->cr();
- tty->print_cr(" Examples:");
+ tty->print_cr(" break,<pattern> - debug breakpoint in compiler and in generated code");
+ tty->print_cr(" print,<pattern> - print assembly");
+ tty->print_cr(" exclude,<pattern> - don't compile or inline");
+ tty->print_cr(" inline,<pattern> - always inline");
+ tty->print_cr(" dontinline,<pattern> - don't inline");
+ tty->print_cr(" compileonly,<pattern> - compile only");
+ tty->print_cr(" log,<pattern> - log compilation");
+ tty->print_cr(" option,<pattern>,<option type>,<option name>,<value>");
+ tty->print_cr(" - set value of custom option");
+ tty->print_cr(" option,<pattern>,<bool option name>");
+ tty->print_cr(" - shorthand for setting boolean flag");
+ tty->print_cr(" quiet - silence the compile command output");
+ tty->print_cr(" help - print this text");
+ tty->cr();
+ tty->print_cr("The preferred format for the method matching pattern is:");
+ tty->print_cr(" package/Class.method()");
+ tty->cr();
+ tty->print_cr("For backward compatibility this form is also allowed:");
+ tty->print_cr(" package.Class::method()");
+ tty->cr();
+ tty->print_cr("The signature can be separated by an optional whitespace or comma:");
+ tty->print_cr(" package/Class.method ()");
+ tty->cr();
+ tty->print_cr("The class and method identifier can be used together with leading or");
+ tty->print_cr("trailing *'s for a small amount of wildcarding:");
+ tty->print_cr(" *ackage/Clas*.*etho*()");
+ tty->cr();
+ tty->print_cr("It is possible to use more than one CompileCommand on the command line:");
+ tty->print_cr(" -XX:CompileCommand=exclude,java/*.* -XX:CompileCommand=log,java*.*");
tty->cr();
- tty->print_cr(" exclude java/lang/StringBuffer.append");
- tty->print_cr(" compileonly java/lang/StringBuffer.toString ()Ljava/lang/String;");
- tty->print_cr(" exclude java/lang/String*.*");
- tty->print_cr(" exclude *.toString");
-}
-
+ tty->print_cr("The CompileCommands can be loaded from a file with the flag");
+ tty->print_cr("-XX:CompileCommandFile=<file> or be added to the file '.hotspot_compiler'");
+ tty->print_cr("Use the same format in the file as the argument to the CompileCommand flag.");
+ tty->print_cr("Add one command on each line.");
+ tty->print_cr(" exclude java/*.*");
+ tty->print_cr(" option java/*.* ReplayInline");
+ tty->cr();
+ tty->print_cr("The following commands have conflicting behavior: 'exclude', 'inline', 'dontinline',");
+ tty->print_cr("and 'compileonly'. There is no priority of commands. Applying (a subset of) these");
+ tty->print_cr("commands to the same method results in undefined behavior.");
+ tty->cr();
+};
-// The characters allowed in a class or method name. All characters > 0x7f
-// are allowed in order to handle obfuscated class files (e.g. Volano)
-#define RANGEBASE "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_<>" \
- "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \
- "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" \
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+// The JVM specification defines the allowed characters.
+// Tokens that are disallowed by the JVM specification can have
+// a meaning to the parser so we need to include them here.
+// The parser does not enforce all rules of the JVMS - a successful parse
+// does not mean that it is an allowed name. Illegal names will
+// be ignored since they never can match a class or method.
+//
+// '\0' and 0xf0-0xff are disallowed in constant string values
+// 0x20 ' ', 0x09 '\t' and, 0x2c ',' are used in the matching
+// 0x5b '[' and 0x5d ']' can not be used because of the matcher
+// 0x28 '(' and 0x29 ')' are used for the signature
+// 0x2e '.' is always replaced before the matching
+// 0x2f '/' is only used in the class name as package separator
+
+#define RANGEBASE "\x1\x2\x3\x4\x5\x6\x7\x8\xa\xb\xc\xd\xe\xf" \
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \
+ "\x21\x22\x23\x24\x25\x26\x27\x2a\x2b\x2c\x2d" \
+ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \
+ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \
+ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5c\x5e\x5f" \
+ "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \
+ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" \
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
#define RANGE0 "[*" RANGEBASE "]"
#define RANGESLASH "[*" RANGEBASE "/]"
@@ -681,8 +722,9 @@
if (command == UnknownCommand) {
ttyLocker ttyl;
- tty->print_cr("CompilerOracle: unrecognized line");
+ tty->print_cr("CompileCommand: unrecognized command");
tty->print_cr(" \"%s\"", original_line);
+ CompilerOracle::print_tip();
return;
}
@@ -712,9 +754,17 @@
Symbol* signature = NULL;
line += bytes_read;
+
+ // Skip any leading spaces before signature
+ int whitespace_read = 0;
+ sscanf(line, "%*[ \t]%n", &whitespace_read);
+ if (whitespace_read > 0) {
+ line += whitespace_read;
+ }
+
// there might be a signature following the method.
// signatures always begin with ( so match that by hand
- if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
+ if (1 == sscanf(line, "(%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) {
sig[0] = '(';
line += bytes_read;
signature = SymbolTable::new_symbol(sig, CHECK);
@@ -740,7 +790,7 @@
if (match != NULL && !_quiet) {
// Print out the last match added
ttyLocker ttyl;
- tty->print("CompilerOracle: %s ", command_names[command]);
+ tty->print("CompileCommand: %s ", command_names[command]);
match->print();
}
line += bytes_read;
@@ -775,26 +825,36 @@
ttyLocker ttyl;
if (error_msg != NULL) {
// an error has happened
- tty->print_cr("CompilerOracle: unrecognized line");
+ tty->print_cr("CompileCommand: An error occured during parsing");
tty->print_cr(" \"%s\"", original_line);
if (error_msg != NULL) {
tty->print_cr("%s", error_msg);
}
+ CompilerOracle::print_tip();
+
} else {
// check for remaining characters
bytes_read = 0;
sscanf(line, "%*[ \t]%n", &bytes_read);
if (line[bytes_read] != '\0') {
- tty->print_cr("CompilerOracle: unrecognized line");
+ tty->print_cr("CompileCommand: Bad pattern");
tty->print_cr(" \"%s\"", original_line);
tty->print_cr(" Unrecognized text %s after command ", line);
+ CompilerOracle::print_tip();
} else if (match != NULL && !_quiet) {
- tty->print("CompilerOracle: %s ", command_names[command]);
+ tty->print("CompileCommand: %s ", command_names[command]);
match->print();
}
}
}
+void CompilerOracle::print_tip() {
+ tty->cr();
+ tty->print_cr("Usage: '-XX:CompileCommand=command,\"package/Class.method()\"'");
+ tty->print_cr("Use: '-XX:CompileCommand=help' for more information.");
+ tty->cr();
+}
+
static const char* default_cc_file = ".hotspot_compiler";
static const char* cc_file() {
--- a/hotspot/src/share/vm/compiler/compilerOracle.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/compiler/compilerOracle.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -34,6 +34,7 @@
class CompilerOracle : AllStatic {
private:
static bool _quiet;
+ static void print_tip();
public:
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -645,7 +645,7 @@
// Support for parallelizing survivor space rescan
if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) {
const size_t max_plab_samples =
- ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
+ ((DefNewGeneration*)_young_gen)->max_survivor_size() / plab_sample_minimum_size();
_survivor_plab_array = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads, mtGC);
_survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples, mtGC);
@@ -703,6 +703,12 @@
_inter_sweep_timer.start(); // start of time
}
+size_t CMSCollector::plab_sample_minimum_size() {
+ // The default value of MinTLABSize is 2k, but there is
+ // no way to get the default value if the flag has been overridden.
+ return MAX2(ThreadLocalAllocBuffer::min_size() * HeapWordSize, 2 * K);
+}
+
const char* ConcurrentMarkSweepGeneration::name() const {
return "concurrent mark-sweep generation";
}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -737,6 +737,10 @@
size_t* _cursor;
ChunkArray* _survivor_plab_array;
+ // A bounded minimum size of PLABs, should not return too small values since
+ // this will affect the size of the data structures used for parallel young gen rescan
+ size_t plab_sample_minimum_size();
+
// Support for marking stack overflow handling
bool take_from_overflow_list(size_t num, CMSMarkStack* to_stack);
bool par_take_from_overflow_list(size_t num,
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1910,7 +1910,6 @@
}
void work(uint worker_id) {
- double start = os::elapsedTime();
FreeRegionList local_cleanup_list("Local Cleanup List");
HRRSCleanupTask hrrs_cleanup_task;
G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list,
--- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -47,6 +47,13 @@
// active field set to true.
PtrQueue(qset_, perm, true /* active */) { }
+ // Flush before destroying; queue may be used to capture pending work while
+ // doing something else, with auto-flush on completion.
+ ~DirtyCardQueue() { if (!is_permanent()) flush(); }
+
+ // Process queue entries and release resources.
+ void flush() { flush_impl(); }
+
// Apply the closure to all elements, and reset the index to make the
// buffer empty. If a closure application returns "false", return
// "false" immediately, halting the iteration. If "consume" is true,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1229,7 +1229,6 @@
TraceCollectorStats tcs(g1mm()->full_collection_counters());
TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
- double start = os::elapsedTime();
g1_policy()->record_full_collection_start();
// Note: When we have a more flexible GC logging framework that
@@ -1436,7 +1435,6 @@
_allocator->init_mutator_alloc_region();
- double end = os::elapsedTime();
g1_policy()->record_full_collection_end();
if (G1Log::fine()) {
@@ -2068,7 +2066,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 +3483,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 +3510,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 +3543,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 +6181,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 +6210,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 +6251,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;
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -56,7 +56,6 @@
class GenerationSpec;
class OopsInHeapRegionClosure;
class G1KlassScanClosure;
-class G1ScanHeapEvacClosure;
class ObjectClosure;
class SpaceClosure;
class CompactibleSpaceClosure;
@@ -186,32 +185,14 @@
friend class SurvivorGCAllocRegion;
friend class OldGCAllocRegion;
friend class G1Allocator;
- friend class G1DefaultAllocator;
- friend class G1ResManAllocator;
// Closures used in implementation.
- template <G1Barrier barrier, G1Mark do_mark_object>
- 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 +640,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
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -153,14 +153,6 @@
_inc_cset_predicted_elapsed_time_ms(0.0),
_inc_cset_predicted_elapsed_time_ms_diffs(0.0),
-#ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
-#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
-#endif // _MSC_VER
-
- _short_lived_surv_rate_group(new SurvRateGroup(this, "Short Lived",
- G1YoungSurvRateNumRegionsSummary)),
- _survivor_surv_rate_group(new SurvRateGroup(this, "Survivor",
- G1YoungSurvRateNumRegionsSummary)),
// add here any more surv rate groups
_recorded_survivor_regions(0),
_recorded_survivor_head(NULL),
@@ -169,6 +161,22 @@
_gc_overhead_perc(0.0) {
+ uintx confidence_perc = G1ConfidencePercent;
+ // Put an artificial ceiling on this so that it's not set to a silly value.
+ if (confidence_perc > 100) {
+ confidence_perc = 100;
+ warning("G1ConfidencePercent is set to a value that is too large, "
+ "it's been updated to %u", confidence_perc);
+ }
+ // '_sigma' must be initialized before the SurvRateGroups below because they
+ // indirecty access '_sigma' trough the 'this' pointer in their constructor.
+ _sigma = (double) confidence_perc / 100.0;
+
+ _short_lived_surv_rate_group =
+ new SurvRateGroup(this, "Short Lived", G1YoungSurvRateNumRegionsSummary);
+ _survivor_surv_rate_group =
+ new SurvRateGroup(this, "Survivor", G1YoungSurvRateNumRegionsSummary);
+
// Set up the region size and associated fields. Given that the
// policy is created before the heap, we have to set this up here,
// so it's done as soon as possible.
@@ -283,15 +291,6 @@
double time_slice = (double) GCPauseIntervalMillis / 1000.0;
_mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
- uintx confidence_perc = G1ConfidencePercent;
- // Put an artificial ceiling on this so that it's not set to a silly value.
- if (confidence_perc > 100) {
- confidence_perc = 100;
- warning("G1ConfidencePercent is set to a value that is too large, "
- "it's been updated to %u", confidence_perc);
- }
- _sigma = (double) confidence_perc / 100.0;
-
// start conservatively (around 50ms is about right)
_concurrent_mark_remark_times_ms->add(0.05);
_concurrent_mark_cleanup_times_ms->add(0.20);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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;
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -46,9 +46,6 @@
class G1PrepareCompactClosure;
class G1MarkSweep : AllStatic {
- friend class VM_G1MarkSweep;
- friend class Scavenge;
-
public:
static void invoke_at_safepoint(ReferenceProcessor* rp,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -45,7 +45,8 @@
#include "utilities/bitMap.inline.hpp"
G1PageBasedVirtualSpace::G1PageBasedVirtualSpace() : _low_boundary(NULL),
- _high_boundary(NULL), _committed(), _page_size(0), _special(false), _executable(false) {
+ _high_boundary(NULL), _committed(), _page_size(0), _special(false),
+ _dirty(), _executable(false) {
}
bool G1PageBasedVirtualSpace::initialize_with_granularity(ReservedSpace rs, size_t page_size) {
@@ -66,6 +67,9 @@
assert(_committed.size() == 0, "virtual space initialized more than once");
uintx size_in_bits = rs.size() / page_size;
_committed.resize(size_in_bits, /* in_resource_area */ false);
+ if (_special) {
+ _dirty.resize(size_in_bits, /* in_resource_area */ false);
+ }
return true;
}
@@ -84,6 +88,7 @@
_executable = false;
_page_size = 0;
_committed.resize(0, false);
+ _dirty.resize(0, false);
}
size_t G1PageBasedVirtualSpace::committed_size() const {
@@ -120,34 +125,43 @@
return num * _page_size;
}
-MemRegion G1PageBasedVirtualSpace::commit(uintptr_t start, size_t size_in_pages) {
+bool G1PageBasedVirtualSpace::commit(uintptr_t start, size_t size_in_pages) {
// We need to make sure to commit all pages covered by the given area.
guarantee(is_area_uncommitted(start, size_in_pages), "Specified area is not uncommitted");
- if (!_special) {
+ bool zero_filled = true;
+ uintptr_t end = start + size_in_pages;
+
+ if (_special) {
+ // Check for dirty pages and update zero_filled if any found.
+ if (_dirty.get_next_one_offset(start,end) < end) {
+ zero_filled = false;
+ _dirty.clear_range(start, end);
+ }
+ } else {
os::commit_memory_or_exit(page_start(start), byte_size_for_pages(size_in_pages), _executable,
err_msg("Failed to commit pages from "SIZE_FORMAT" of length "SIZE_FORMAT, start, size_in_pages));
}
- _committed.set_range(start, start + size_in_pages);
+ _committed.set_range(start, end);
- MemRegion result((HeapWord*)page_start(start), byte_size_for_pages(size_in_pages) / HeapWordSize);
if (AlwaysPreTouch) {
- os::pretouch_memory((char*)result.start(), (char*)result.end());
+ os::pretouch_memory(page_start(start), page_start(end));
}
- return result;
+ return zero_filled;
}
-MemRegion G1PageBasedVirtualSpace::uncommit(uintptr_t start, size_t size_in_pages) {
+void G1PageBasedVirtualSpace::uncommit(uintptr_t start, size_t size_in_pages) {
guarantee(is_area_committed(start, size_in_pages), "checking");
- if (!_special) {
+ if (_special) {
+ // Mark that memory is dirty. If committed again the memory might
+ // need to be cleared explicitly.
+ _dirty.set_range(start, start + size_in_pages);
+ } else {
os::uncommit_memory(page_start(start), byte_size_for_pages(size_in_pages));
}
_committed.clear_range(start, start + size_in_pages);
-
- MemRegion result((HeapWord*)page_start(start), byte_size_for_pages(size_in_pages) / HeapWordSize);
- return result;
}
bool G1PageBasedVirtualSpace::contains(const void* p) const {
@@ -157,7 +171,7 @@
#ifndef PRODUCT
void G1PageBasedVirtualSpace::print_on(outputStream* out) {
out->print ("Virtual space:");
- if (special()) out->print(" (pinned in memory)");
+ if (_special) out->print(" (pinned in memory)");
out->cr();
out->print_cr(" - committed: " SIZE_FORMAT, committed_size());
out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size());
--- a/hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -49,6 +49,12 @@
// Bitmap used for verification of commit/uncommit operations.
BitMap _committed;
+ // Bitmap used to keep track of which pages are dirty or not for _special
+ // spaces. This is needed because for those spaces the underlying memory
+ // will only be zero filled the first time it is committed. Calls to commit
+ // will use this bitmap and return whether or not the memory is zero filled.
+ BitMap _dirty;
+
// Indicates that the entire space has been committed and pinned in memory,
// os::commit_memory() or os::uncommit_memory() have no function.
bool _special;
@@ -71,12 +77,11 @@
public:
// Commit the given area of pages starting at start being size_in_pages large.
- MemRegion commit(uintptr_t start, size_t size_in_pages);
+ // Returns true if the given area is zero filled upon completion.
+ bool commit(uintptr_t start, size_t size_in_pages);
// Uncommit the given area of pages starting at start being size_in_pages large.
- MemRegion uncommit(uintptr_t start, size_t size_in_pages);
-
- bool special() const { return _special; }
+ void uncommit(uintptr_t start, size_t size_in_pages);
// Initialization
G1PageBasedVirtualSpace();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RegionToSpaceMapper.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -67,9 +67,9 @@
}
virtual void commit_regions(uintptr_t start_idx, size_t num_regions) {
- _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region);
+ bool zero_filled = _storage.commit(start_idx * _pages_per_region, num_regions * _pages_per_region);
_commit_map.set_range(start_idx, start_idx + num_regions);
- fire_on_commit(start_idx, num_regions, true);
+ fire_on_commit(start_idx, num_regions, zero_filled);
}
virtual void uncommit_regions(uintptr_t start_idx, size_t num_regions) {
@@ -117,8 +117,7 @@
uint old_refcount = _refcounts.get_by_index(idx);
bool zero_filled = false;
if (old_refcount == 0) {
- _storage.commit(idx, 1);
- zero_filled = true;
+ zero_filled = _storage.commit(idx, 1);
}
_refcounts.set_by_index(idx, old_refcount + 1);
_commit_map.set_bit(i);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -31,7 +31,6 @@
// collection set.
class G1CollectedHeap;
-class CardTableModRefBarrierSet;
class ConcurrentG1Refine;
class G1ParPushHeapRSClosure;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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.") \
\
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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;
}
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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();
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -31,11 +31,15 @@
#include "runtime/thread.inline.hpp"
PtrQueue::PtrQueue(PtrQueueSet* qset, bool perm, bool active) :
- _qset(qset), _buf(NULL), _index(0), _active(active),
+ _qset(qset), _buf(NULL), _index(0), _sz(0), _active(active),
_perm(perm), _lock(NULL)
{}
-void PtrQueue::flush() {
+PtrQueue::~PtrQueue() {
+ assert(_perm || (_buf == NULL), "queue must be flushed before delete");
+}
+
+void PtrQueue::flush_impl() {
if (!_perm && _buf != NULL) {
if (_index == _sz) {
// No work to do.
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -65,15 +65,18 @@
Mutex* _lock;
PtrQueueSet* qset() { return _qset; }
+ bool is_permanent() const { return _perm; }
+
+ // Process queue entries and release resources, if not permanent.
+ void flush_impl();
public:
// Initialize this queue to contain a null buffer, and be part of the
// given PtrQueueSet.
PtrQueue(PtrQueueSet* qset, bool perm = false, bool active = false);
- // Release any contained resources.
- virtual void flush();
- // Calls flush() when destroyed.
- ~PtrQueue() { flush(); }
+
+ // Requires queue flushed or permanent.
+ ~PtrQueue();
// Associate a lock with a ptr queue.
void set_lock(Mutex* lock) { _lock = lock; }
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -39,7 +39,7 @@
// first before we flush it, otherwise we might end up with an
// enqueued buffer with refs into the CSet which breaks our invariants.
filter();
- PtrQueue::flush();
+ flush_impl();
}
// This method removes entries from an SATB buffer that will not be
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -60,9 +60,8 @@
// field to true. This is done in JavaThread::initialize_queues().
PtrQueue(qset, perm, false /* active */) { }
- // Overrides PtrQueue::flush() so that it can filter the buffer
- // before it is flushed.
- virtual void flush();
+ // Process queue entries and free resources.
+ void flush();
// Overrides PtrQueue::should_enqueue_buffer(). See the method's
// definition for more information.
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -63,7 +63,8 @@
virtual ~ParGCAllocBuffer() {}
static const size_t min_size() {
- return ThreadLocalAllocBuffer::min_size();
+ // Make sure that we return something that is larger than AlignmentReserve
+ return align_object_size(MAX2(MinTLABSize / HeapWordSize, (uintx)oopDesc::header_size())) + AlignmentReserve;
}
static const size_t max_size() {
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -320,7 +320,7 @@
// First check in default method array
if (!resolved_method->is_abstract() &&
(InstanceKlass::cast(klass())->default_methods() != NULL)) {
- int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false);
+ int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false, false);
if (index >= 0 ) {
vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
}
--- a/hotspot/src/share/vm/memory/heap.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/heap.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -279,10 +279,12 @@
return sizeof(HeapBlock) & (_segment_size - 1);
}
-// Finds the next free heapblock. If the current one is free, that it returned
-void* CodeHeap::next_free(HeapBlock* b) const {
- // Since free blocks are merged, there is max. on free block
- // between two used ones
+// Returns the current block if available and used.
+// If not, it returns the subsequent block (if available), NULL otherwise.
+// Free blocks are merged, therefore there is at most one free block
+// between two used ones. As a result, the subsequent block (if available) is
+// guaranteed to be used.
+void* CodeHeap::next_used(HeapBlock* b) const {
if (b != NULL && b->free()) b = next_block(b);
assert(b == NULL || !b->free(), "must be in use or at end of heap");
return (b == NULL) ? NULL : b->allocated_space();
--- a/hotspot/src/share/vm/memory/heap.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/heap.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -123,7 +123,7 @@
FreeBlock* search_freelist(size_t length);
// Iteration helpers
- void* next_free(HeapBlock* b) const;
+ void* next_used(HeapBlock* b) const;
HeapBlock* first_block() const;
HeapBlock* next_block(HeapBlock* b) const;
HeapBlock* block_start(void* p) const;
@@ -158,9 +158,9 @@
int freelist_length() const { return _freelist_length; } // number of elements in the freelist
// returns the first block or NULL
- void* first() const { return next_free(first_block()); }
+ void* first() const { return next_used(first_block()); }
// returns the next block given a block p or NULL
- void* next(void* p) const { return next_free(next_block(block_start(p))); }
+ void* next(void* p) const { return next_used(next_block(block_start(p))); }
// Statistics
size_t capacity() const;
--- a/hotspot/src/share/vm/memory/metaspace.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -3170,7 +3170,9 @@
}
// the min_misc_data_size and min_misc_code_size estimates are based on
- // MetaspaceShared::generate_vtable_methods()
+ // MetaspaceShared::generate_vtable_methods().
+ // The minimum size only accounts for the vtable methods. Any size less than the
+ // minimum required size would cause vm crash when allocating the vtable methods.
uint min_misc_data_size = align_size_up(
MetaspaceShared::num_virtuals * MetaspaceShared::vtbl_list_size * sizeof(void*), max_alignment);
@@ -3336,6 +3338,10 @@
Metachunk* new_chunk = get_initialization_chunk(NonClassType,
word_size,
vsm()->medium_chunk_bunch());
+ // For dumping shared archive, report error if allocation has failed.
+ if (DumpSharedSpaces && new_chunk == NULL) {
+ report_insufficient_metaspace(MetaspaceAux::committed_bytes() + word_size * BytesPerWord);
+ }
assert(!DumpSharedSpaces || new_chunk != NULL, "should have enough space for both chunks");
if (new_chunk != NULL) {
// Add to this manager's list of chunks in use and current_chunk().
@@ -3349,6 +3355,11 @@
class_vsm()->medium_chunk_bunch());
if (class_chunk != NULL) {
class_vsm()->add_chunk(class_chunk, true);
+ } else {
+ // For dumping shared archive, report error if allocation has failed.
+ if (DumpSharedSpaces) {
+ report_insufficient_metaspace(MetaspaceAux::committed_bytes() + class_word_size * BytesPerWord);
+ }
}
}
@@ -3829,11 +3840,13 @@
assert(cm.sum_free_chunks() == 2*MediumChunk, "sizes should add up");
}
- { // 4 pages of VSN is committed, some is used by chunks
+ const size_t page_chunks = 4 * (size_t)os::vm_page_size() / BytesPerWord;
+ // This doesn't work for systems with vm_page_size >= 16K.
+ if (page_chunks < MediumChunk) {
+ // 4 pages of VSN is committed, some is used by chunks
ChunkManager cm(SpecializedChunk, SmallChunk, MediumChunk);
VirtualSpaceNode vsn(vsn_test_size_bytes);
- const size_t page_chunks = 4 * (size_t)os::vm_page_size() / BytesPerWord;
- assert(page_chunks < MediumChunk, "Test expects medium chunks to be at least 4*page_size");
+
vsn.initialize();
vsn.expand_by(page_chunks, page_chunks);
vsn.get_chunk_vs(SmallChunk);
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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<Symbol*, mtSymbol>);
- int symbuck_count = SymbolTable::the_table()->table_size();
- int symbuck_bytes = symbuck_count * sizeof(HashtableBucket<mtSymbol>);
+ 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<mtSymbol>*)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<mtClass>*)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;
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/hotspot/src/share/vm/memory/referenceProcessor.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -118,6 +118,7 @@
_discoveredWeakRefs = &_discoveredSoftRefs[_max_num_q];
_discoveredFinalRefs = &_discoveredWeakRefs[_max_num_q];
_discoveredPhantomRefs = &_discoveredFinalRefs[_max_num_q];
+ _discoveredCleanerRefs = &_discoveredPhantomRefs[_max_num_q];
// Initialize all entries to NULL
for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
@@ -246,6 +247,13 @@
phantom_count =
process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
is_alive, keep_alive, complete_gc, task_executor);
+
+ // Process cleaners, but include them in phantom statistics. We expect
+ // Cleaner references to be temporary, and don't want to deal with
+ // possible incompatibilities arising from making it more visible.
+ phantom_count +=
+ process_discovered_reflist(_discoveredCleanerRefs, NULL, false,
+ is_alive, keep_alive, complete_gc, task_executor);
}
// Weak global JNI references. It would make more sense (semantically) to
@@ -885,6 +893,7 @@
balance_queues(_discoveredWeakRefs);
balance_queues(_discoveredFinalRefs);
balance_queues(_discoveredPhantomRefs);
+ balance_queues(_discoveredCleanerRefs);
}
size_t
@@ -998,6 +1007,9 @@
case REF_PHANTOM:
list = &_discoveredPhantomRefs[id];
break;
+ case REF_CLEANER:
+ list = &_discoveredCleanerRefs[id];
+ break;
case REF_NONE:
// we should not reach here if we are an InstanceRefKlass
default:
@@ -1263,6 +1275,17 @@
preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
keep_alive, complete_gc, yield);
}
+
+ // Cleaner references. Included in timing for phantom references. We
+ // expect Cleaner references to be temporary, and don't want to deal with
+ // possible incompatibilities arising from making it more visible.
+ for (uint i = 0; i < _max_num_q; i++) {
+ if (yield->should_return()) {
+ return;
+ }
+ preclean_discovered_reflist(_discoveredCleanerRefs[i], is_alive,
+ keep_alive, complete_gc, yield);
+ }
}
}
@@ -1331,6 +1354,7 @@
case 1: return "WeakRef";
case 2: return "FinalRef";
case 3: return "PhantomRef";
+ case 4: return "CleanerRef";
}
ShouldNotReachHere();
return NULL;
--- a/hotspot/src/share/vm/memory/referenceProcessor.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/referenceProcessor.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -264,9 +264,10 @@
DiscoveredList* _discoveredWeakRefs;
DiscoveredList* _discoveredFinalRefs;
DiscoveredList* _discoveredPhantomRefs;
+ DiscoveredList* _discoveredCleanerRefs;
public:
- static int number_of_subclasses_of_ref() { return (REF_PHANTOM - REF_OTHER); }
+ static int number_of_subclasses_of_ref() { return (REF_CLEANER - REF_OTHER); }
uint num_q() { return _num_q; }
uint max_num_q() { return _max_num_q; }
--- a/hotspot/src/share/vm/memory/referenceType.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/referenceType.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -35,7 +35,8 @@
REF_SOFT, // Subclass of java/lang/ref/SoftReference
REF_WEAK, // Subclass of java/lang/ref/WeakReference
REF_FINAL, // Subclass of java/lang/ref/FinalReference
- REF_PHANTOM // Subclass of java/lang/ref/PhantomReference
+ REF_PHANTOM, // Subclass of java/lang/ref/PhantomReference
+ REF_CLEANER // Subclass of sun/misc/Cleaner
};
#endif // SHARE_VM_MEMORY_REFRERENCETYPE_HPP
--- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -235,22 +235,19 @@
}
size_t ThreadLocalAllocBuffer::initial_desired_size() {
- size_t init_sz;
+ size_t init_sz = 0;
if (TLABSize > 0) {
- init_sz = MIN2(TLABSize / HeapWordSize, max_size());
- } else if (global_stats() == NULL) {
- // Startup issue - main thread initialized before heap initialized.
- init_sz = min_size();
- } else {
+ init_sz = TLABSize / HeapWordSize;
+ } else if (global_stats() != NULL) {
// Initial size is a function of the average number of allocating threads.
unsigned nof_threads = global_stats()->allocating_threads_avg();
init_sz = (Universe::heap()->tlab_capacity(myThread()) / HeapWordSize) /
(nof_threads * target_refills());
init_sz = align_object_size(init_sz);
- init_sz = MIN2(MAX2(init_sz, min_size()), max_size());
}
+ init_sz = MIN2(MAX2(init_sz, min_size()), max_size());
return init_sz;
}
--- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -106,7 +106,7 @@
// do nothing. tlabs must be inited by initialize() calls
}
- static const size_t min_size() { return align_object_size(MinTLABSize / HeapWordSize); }
+ static const size_t min_size() { return align_object_size(MinTLABSize / HeapWordSize) + alignment_reserve(); }
static const size_t max_size() { assert(_max_size != 0, "max_size not set up"); return _max_size; }
static void set_max_size(size_t max_size) { _max_size = max_size; }
--- a/hotspot/src/share/vm/memory/universe.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/universe.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
--- a/hotspot/src/share/vm/memory/universe.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/memory/universe.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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; }
};
--- a/hotspot/src/share/vm/oops/fieldStreams.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/oops/fieldStreams.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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;
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1420,32 +1420,41 @@
}
Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const {
- return InstanceKlass::find_method_impl(methods(), name, signature, skipping_overpass);
+ return InstanceKlass::find_method_impl(methods(), name, signature, skipping_overpass, false);
}
// find_instance_method looks up the name/signature in the local methods array
// and skips over static methods
Method* InstanceKlass::find_instance_method(
Array<Method*>* methods, Symbol* name, Symbol* signature) {
- Method* meth = InstanceKlass::find_method(methods, name, signature);
- if (meth != NULL && meth->is_static()) {
- meth = NULL;
- }
+ Method* meth = InstanceKlass::find_method_impl(methods, name, signature, false, true);
return meth;
}
+// find_instance_method looks up the name/signature in the local methods array
+// and skips over static methods
+Method* InstanceKlass::find_instance_method(Symbol* name, Symbol* signature) {
+ return InstanceKlass::find_instance_method(methods(), name, signature);
+}
+
// find_method looks up the name/signature in the local methods array
Method* InstanceKlass::find_method(
Array<Method*>* methods, Symbol* name, Symbol* signature) {
- return InstanceKlass::find_method_impl(methods, name, signature, false);
+ return InstanceKlass::find_method_impl(methods, name, signature, false, false);
}
Method* InstanceKlass::find_method_impl(
- Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass) {
- int hit = find_method_index(methods, name, signature, skipping_overpass);
+ Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) {
+ int hit = find_method_index(methods, name, signature, skipping_overpass, skipping_static);
return hit >= 0 ? methods->at(hit): NULL;
}
+bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static) {
+ return (m->signature() == signature) &&
+ (!skipping_overpass || !m->is_overpass()) &&
+ (!skipping_static || !m->is_static());
+}
+
// Used directly for default_methods to find the index into the
// default_vtable_indices, and indirectly by find_method
// find_method_index looks in the local methods array to return the index
@@ -1454,13 +1463,14 @@
// is important during method resolution to prefer a static method, for example,
// over an overpass method.
int InstanceKlass::find_method_index(
- Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass) {
+ Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) {
int hit = binary_search(methods, name);
if (hit != -1) {
Method* m = methods->at(hit);
+
// Do linear search to find matching signature. First, quick check
// for common case, ignoring overpasses if requested.
- if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return hit;
+ if (method_matches(m, signature, skipping_overpass, skipping_static)) return hit;
// search downwards through overloaded methods
int i;
@@ -1468,18 +1478,18 @@
Method* m = methods->at(i);
assert(m->is_method(), "must be method");
if (m->name() != name) break;
- if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return i;
+ if (method_matches(m, signature, skipping_overpass, skipping_static)) return i;
}
// search upwards
for (i = hit + 1; i < methods->length(); ++i) {
Method* m = methods->at(i);
assert(m->is_method(), "must be method");
if (m->name() != name) break;
- if ((m->signature() == signature) && (!skipping_overpass || !m->is_overpass())) return i;
+ if (method_matches(m, signature, skipping_overpass, skipping_static)) return i;
}
// not found
#ifdef ASSERT
- int index = skipping_overpass ? -1 : linear_search(methods, name, signature);
+ int index = skipping_overpass || skipping_static ? -1 : linear_search(methods, name, signature);
assert(index == -1, err_msg("binary search should have found entry %d", index));
#endif
}
@@ -3543,11 +3553,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 +3572,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<Method*>* 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<Method*>* old_methods,
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -490,10 +490,16 @@
// find a local method (returns NULL if not found)
Method* find_method(Symbol* name, Symbol* signature) const;
static Method* find_method(Array<Method*>* methods, Symbol* name, Symbol* signature);
+
+ // find a local method, but skip static methods
+ Method* find_instance_method(Symbol* name, Symbol* signature);
static Method* find_instance_method(Array<Method*>* methods, Symbol* name, Symbol* signature);
+ // true if method matches signature and conforms to skipping_X conditions.
+ static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static);
+
// find a local method index in default_methods (returns -1 if not found)
- static int find_method_index(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass);
+ static int find_method_index(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static);
// lookup operation (returns NULL if not found)
Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
@@ -1053,7 +1059,7 @@
// find a local method (returns NULL if not found)
Method* find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const;
- static Method* find_method_impl(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass);
+ static Method* find_method_impl(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static);
// Free CHeap allocated fields.
void release_C_heap_structures();
--- a/hotspot/src/share/vm/oops/klassVtable.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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");
--- a/hotspot/src/share/vm/oops/method.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/oops/method.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
}
--- a/hotspot/src/share/vm/oops/methodData.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/oops/methodData.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/hotspot/src/share/vm/oops/methodData.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/oops/methodData.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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; }
};
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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)
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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;
--- a/hotspot/src/share/vm/opto/c2compiler.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/c2compiler.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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();
--- a/hotspot/src/share/vm/opto/callnode.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/callnode.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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;
+}
--- a/hotspot/src/share/vm/opto/callnode.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/callnode.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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; }
--- a/hotspot/src/share/vm/opto/cfgnode.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/cfgnode.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -361,22 +361,36 @@
#endif
};
-class IfTrueNode : public CProjNode {
+class IfProjNode : public CProjNode {
public:
- IfTrueNode( IfNode *ifnode ) : CProjNode(ifnode,1) {
+ IfProjNode(IfNode *ifnode, uint idx) : CProjNode(ifnode,idx) {}
+ virtual Node *Identity(PhaseTransform *phase);
+
+protected:
+ // Type of If input when this branch is always taken
+ virtual bool always_taken(const TypeTuple* t) const = 0;
+};
+
+class IfTrueNode : public IfProjNode {
+public:
+ IfTrueNode( IfNode *ifnode ) : IfProjNode(ifnode,1) {
init_class_id(Class_IfTrue);
}
virtual int Opcode() const;
- virtual Node *Identity( PhaseTransform *phase );
+
+protected:
+ virtual bool always_taken(const TypeTuple* t) const { return t == TypeTuple::IFTRUE; }
};
-class IfFalseNode : public CProjNode {
+class IfFalseNode : public IfProjNode {
public:
- IfFalseNode( IfNode *ifnode ) : CProjNode(ifnode,0) {
+ IfFalseNode( IfNode *ifnode ) : IfProjNode(ifnode,0) {
init_class_id(Class_IfFalse);
}
virtual int Opcode() const;
- virtual Node *Identity( PhaseTransform *phase );
+
+protected:
+ virtual bool always_taken(const TypeTuple* t) const { return t == TypeTuple::IFFALSE; }
};
--- a/hotspot/src/share/vm/opto/compile.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/compile.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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);
--- a/hotspot/src/share/vm/opto/ifnode.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/ifnode.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1122,12 +1122,21 @@
//------------------------------Identity---------------------------------------
// If the test is constant & we match, then we are the input Control
-Node *IfTrueNode::Identity( PhaseTransform *phase ) {
+Node *IfProjNode::Identity(PhaseTransform *phase) {
// Can only optimize if cannot go the other way
const TypeTuple *t = phase->type(in(0))->is_tuple();
- return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFTRUE )
- ? in(0)->in(0) // IfNode control
- : this; // no progress
+ if (t == TypeTuple::IFNEITHER ||
+ // kill dead branch first otherwise the IfNode's control will
+ // have 2 control uses (the IfNode that doesn't go away because
+ // it still has uses and this branch of the
+ // If). Node::has_special_unique_user() will cause this node to
+ // be reprocessed once the dead branch is killed.
+ (always_taken(t) && in(0)->outcnt() == 1)) {
+ // IfNode control
+ return in(0)->in(0);
+ }
+ // no progress
+ return this;
}
//------------------------------dump_spec--------------------------------------
@@ -1195,13 +1204,3 @@
// Progress
return iff;
}
-
-//------------------------------Identity---------------------------------------
-// If the test is constant & we match, then we are the input Control
-Node *IfFalseNode::Identity( PhaseTransform *phase ) {
- // Can only optimize if cannot go the other way
- const TypeTuple *t = phase->type(in(0))->is_tuple();
- return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFFALSE )
- ? in(0)->in(0) // IfNode control
- : this; // no progress
-}
--- a/hotspot/src/share/vm/opto/library_call.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/library_call.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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;
}
--- a/hotspot/src/share/vm/opto/macroArrayCopy.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/macroArrayCopy.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/hotspot/src/share/vm/opto/matcher.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/matcher.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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);
--- a/hotspot/src/share/vm/opto/node.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/node.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1080,18 +1080,21 @@
assert(outcnt() == 1, "match only for unique out");
Node* n = unique_out();
int op = Opcode();
- if( this->is_Store() ) {
+ if (this->is_Store()) {
// Condition for back-to-back stores folding.
return n->Opcode() == op && n->in(MemNode::Memory) == this;
} else if (this->is_Load()) {
// Condition for removing an unused LoadNode from the MemBarAcquire precedence input
return n->Opcode() == Op_MemBarAcquire;
- } else if( op == Op_AddL ) {
+ } else if (op == Op_AddL) {
// Condition for convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y))
return n->Opcode() == Op_ConvL2I && n->in(1) == this;
- } else if( op == Op_SubI || op == Op_SubL ) {
+ } else if (op == Op_SubI || op == Op_SubL) {
// Condition for subI(x,subI(y,z)) ==> subI(addI(x,z),y)
return n->Opcode() == op && n->in(2) == this;
+ } else if (is_If() && (n->is_IfFalse() || n->is_IfTrue())) {
+ // See IfProjNode::Identity()
+ return true;
}
return false;
};
--- a/hotspot/src/share/vm/opto/parse1.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/opto/parse1.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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<Method*>* 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();
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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,
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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());
}
}
--- a/hotspot/src/share/vm/prims/whitebox.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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)
--- a/hotspot/src/share/vm/runtime/arguments.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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) {
--- a/hotspot/src/share/vm/runtime/globals.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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") \
\
@@ -2946,10 +2951,6 @@
develop(intx, MallocCatchPtr, -1, \
"Hit breakpoint when mallocing/freeing this pointer") \
\
- notproduct(intx, AssertRepeat, 1, \
- "number of times to evaluate expression in assert " \
- "(to estimate overhead); only works with -DUSE_REPEATED_ASSERTS") \
- \
notproduct(ccstrlist, SuppressErrorAt, "", \
"List of assertions (file:line) to muzzle") \
\
@@ -3779,6 +3780,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.") \
--- a/hotspot/src/share/vm/runtime/os.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/runtime/os.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -547,20 +547,16 @@
// This function supports testing of the malloc out of memory
// condition without really running the system out of memory.
//
-static u_char* testMalloc(size_t alloc_size) {
- assert(MallocMaxTestWords > 0, "sanity check");
-
- if ((cur_malloc_words + (alloc_size / BytesPerWord)) > MallocMaxTestWords) {
- return NULL;
- }
+static bool has_reached_max_malloc_test_peak(size_t alloc_size) {
+ if (MallocMaxTestWords > 0) {
+ jint words = (jint)(alloc_size / BytesPerWord);
- u_char* ptr = (u_char*)::malloc(alloc_size);
-
- if (ptr != NULL) {
- Atomic::add(((jint) (alloc_size / BytesPerWord)),
- (volatile jint *) &cur_malloc_words);
+ if ((cur_malloc_words + words) > MallocMaxTestWords) {
+ return true;
+ }
+ Atomic::add(words, (volatile jint *)&cur_malloc_words);
}
- return ptr;
+ return false;
}
void* os::malloc(size_t size, MEMFLAGS flags) {
@@ -608,12 +604,13 @@
NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
+ // For the test flag -XX:MallocMaxTestWords
+ if (has_reached_max_malloc_test_peak(size)) {
+ return NULL;
+ }
+
u_char* ptr;
- if (MallocMaxTestWords > 0) {
- ptr = testMalloc(alloc_size);
- } else {
- ptr = (u_char*)::malloc(alloc_size);
- }
+ ptr = (u_char*)::malloc(alloc_size);
#ifdef ASSERT
if (ptr == NULL) {
@@ -642,6 +639,11 @@
void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
+ // For the test flag -XX:MallocMaxTestWords
+ if (has_reached_max_malloc_test_peak(size)) {
+ return NULL;
+ }
+
#ifndef ASSERT
NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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());
--- a/hotspot/src/share/vm/runtime/virtualspace.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/runtime/virtualspace.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -661,6 +661,7 @@
static_field(SystemDictionary, WK_KLASS(WeakReference_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(FinalReference_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(PhantomReference_klass), Klass*) \
+ static_field(SystemDictionary, WK_KLASS(Cleaner_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(Finalizer_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(Thread_klass), Klass*) \
static_field(SystemDictionary, WK_KLASS(ThreadGroup_klass), Klass*) \
@@ -2559,6 +2560,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) \
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -100,6 +100,7 @@
template(RotateGCLog) \
template(WhiteBoxOperation) \
template(ClassLoaderStatsOperation) \
+ template(DumpHashtable) \
template(MarkActiveNMethods) \
template(PrintCompileQueue) \
template(PrintCodeList) \
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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<HeapDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SymboltableDCmd>(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<StringtableDCmd>(full_export, true, false));
#endif // INCLUDE_SERVICES
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
--- a/hotspot/src/share/vm/shark/llvmHeaders.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/shark/llvmHeaders.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -87,30 +87,7 @@
#undef assert
#endif
-// from hotspot/src/share/vm/utilities/debug.hpp
-#ifdef ASSERT
-#ifndef USE_REPEATED_ASSERTS
-#define assert(p, msg) \
-do { \
- if (!(p)) { \
- report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \
- BREAKPOINT; \
- } \
-} while (0)
-#else // #ifndef USE_REPEATED_ASSERTS
-#define assert(p, msg)
-do { \
- for (int __i = 0; __i < AssertRepeat; __i++) { \
- if (!(p)) { \
- report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \
- BREAKPOINT; \
- } \
- } \
-} while (0)
-#endif // #ifndef USE_REPEATED_ASSERTS
-#else
- #define assert(p, msg)
-#endif
+#define assert(p, msg) vmassert(p, msg)
#ifdef DEBUG
#undef DEBUG
--- a/hotspot/src/share/vm/utilities/debug.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/utilities/debug.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -273,6 +273,14 @@
exit(2);
}
+void report_insufficient_metaspace(size_t required_size) {
+ warning("\nThe MaxMetaspaceSize of " UINTX_FORMAT " bytes is not large enough.\n"
+ "Either don't specify the -XX:MaxMetaspaceSize=<size>\n"
+ "or increase the size to at least " SIZE_FORMAT ".\n",
+ MaxMetaspaceSize, required_size);
+ exit(2);
+}
+
void report_java_out_of_memory(const char* message) {
static jint out_of_memory_reported = 0;
@@ -326,9 +334,9 @@
// Keep this in sync with test/runtime/6888954/vmerrors.sh.
switch (n) {
- case 1: assert(str == NULL, "expected null");
- case 2: assert(num == 1023 && *str == 'X',
- err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
+ case 1: vmassert(str == NULL, "expected null");
+ case 2: vmassert(num == 1023 && *str == 'X',
+ err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
case 3: guarantee(str == NULL, "expected null");
case 4: guarantee(num == 1023 && *str == 'X',
err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
--- a/hotspot/src/share/vm/utilities/debug.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/utilities/debug.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -105,58 +105,42 @@
va_end(argp);
}
-// Used to format messages for assert(), guarantee(), fatal(), etc.
+// Used to format messages for vmassert(), guarantee(), fatal(), etc.
typedef FormatBuffer<> err_msg;
typedef FormatBufferResource err_msg_res;
// assertions
-#ifdef ASSERT
-#ifndef USE_REPEATED_ASSERTS
-#define assert(p, msg) \
+#ifndef ASSERT
+#define vmassert(p, msg)
+#else
+// Note: message says "assert" rather than "vmassert" for backward
+// compatibility with tools that parse/match the message text.
+#define vmassert(p, msg) \
do { \
if (!(p)) { \
report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \
BREAKPOINT; \
} \
} while (0)
-#else // #ifndef USE_REPEATED_ASSERTS
-#define assert(p, msg)
-do { \
- for (int __i = 0; __i < AssertRepeat; __i++) { \
- if (!(p)) { \
- report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \
- BREAKPOINT; \
- } \
- } \
-} while (0)
-#endif // #ifndef USE_REPEATED_ASSERTS
+#endif
-// This version of assert is for use with checking return status from
+// For backward compatibility.
+#define assert(p, msg) vmassert(p, msg)
+
+// This version of vmassert is for use with checking return status from
// library calls that return actual error values eg. EINVAL,
// ENOMEM etc, rather than returning -1 and setting errno.
// When the status is not what is expected it is very useful to know
// what status was actually returned, so we pass the status variable as
// an extra arg and use strerror to convert it to a meaningful string
// like "Invalid argument", "out of memory" etc
-#define assert_status(p, status, msg) \
-do { \
- if (!(p)) { \
- report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", \
- err_msg("error %s(%d) %s", strerror(status), \
- status, msg)); \
- BREAKPOINT; \
- } \
-} while (0)
+#define vmassert_status(p, status, msg) \
+ vmassert(p, err_msg("error %s(%d), %s", strerror(status), status, msg))
-// Do not assert this condition if there's already another error reported.
-#define assert_if_no_error(cond,msg) assert((cond) || is_error_reported(), msg)
-#else // #ifdef ASSERT
- #define assert(p,msg)
- #define assert_status(p,status,msg)
- #define assert_if_no_error(cond,msg)
-#endif // #ifdef ASSERT
+// For backward compatibility.
+#define assert_status(p, status, msg) vmassert_status(p, status, msg)
-// guarantee is like assert except it's always executed -- use it for
+// guarantee is like vmassert except it's always executed -- use it for
// cheap tests that catch errors that would otherwise be hard to find.
// guarantee is also used for Verify options.
#define guarantee(p, msg) \
@@ -225,21 +209,22 @@
void warning(const char* format, ...) ATTRIBUTE_PRINTF(1, 2);
-#ifdef ASSERT
-// Compile-time asserts.
-template <bool> struct StaticAssert;
-template <> struct StaticAssert<true> {};
+// Compile-time asserts. Cond must be a compile-time constant expression that
+// is convertible to bool. STATIC_ASSERT() can be used anywhere a declaration
+// may appear.
+//
+// Implementation Note: STATIC_ASSERT_FAILURE<true> provides a value member
+// rather than type member that could be used directly in the typedef, because
+// a type member would require conditional use of "typename", depending on
+// whether Cond is dependent or not. The use of a value member leads to the
+// use of an array type.
-// Only StaticAssert<true> is defined, so if cond evaluates to false we get
-// a compile time exception when trying to use StaticAssert<false>.
-#define STATIC_ASSERT(cond) \
- do { \
- StaticAssert<(cond)> DUMMY_STATIC_ASSERT; \
- (void)DUMMY_STATIC_ASSERT; /* ignore */ \
- } while (false)
-#else
-#define STATIC_ASSERT(cond)
-#endif
+template<bool x> struct STATIC_ASSERT_FAILURE;
+template<> struct STATIC_ASSERT_FAILURE<true> { enum { value = 1 }; };
+
+#define STATIC_ASSERT(Cond) \
+ typedef char STATIC_ASSERT_FAILURE_ ## __LINE__ [ \
+ STATIC_ASSERT_FAILURE< (Cond) >::value ]
// out of shared space reporting
enum SharedSpaceType {
@@ -251,6 +236,8 @@
void report_out_of_shared_space(SharedSpaceType space_type);
+void report_insufficient_metaspace(size_t required_size);
+
// out of memory reporting
void report_java_out_of_memory(const char* message);
@@ -258,7 +245,7 @@
bool is_error_reported();
void set_error_reported();
-/* Test assert(), fatal(), guarantee(), etc. */
+/* Test vmassert(), fatal(), guarantee(), etc. */
NOT_PRODUCT(void test_error_handler();)
void pd_ps(frame f);
--- a/hotspot/src/share/vm/utilities/defaultStream.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/utilities/defaultStream.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -41,6 +41,8 @@
void init();
void init_log();
+ fileStream* open_file(const char* log_name);
+ void start_log();
void finish_log();
void finish_log_on_error(char *buf, int buflen);
public:
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/hotspot/src/share/vm/utilities/ostream.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/utilities/ostream.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -367,7 +367,6 @@
#define EXTRACHARLEN 32
#define CURRENTAPPX ".current"
-#define FILENAMEBUFLEN 1024
// convert YYYY-MM-DD HH:MM:SS to YYYY-MM-DD_HH-MM-SS
char* get_datetime_string(char *buf, size_t len) {
os::local_time_string(buf, len);
@@ -401,7 +400,6 @@
buffer_length = strlen(log_name) + 1;
}
- // const char* star = strchr(basename, '*');
const char* pts = strstr(basename, "%p");
int pid_pos = (pts == NULL) ? -1 : (pts - nametail);
@@ -416,6 +414,11 @@
buffer_length += strlen(tms);
}
+ // File name is too long.
+ if (buffer_length > JVM_MAXPATHLEN) {
+ return NULL;
+ }
+
// Create big enough buffer.
char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
@@ -489,46 +492,88 @@
void test_loggc_filename() {
int pid;
char tms[32];
- char i_result[FILENAMEBUFLEN];
+ char i_result[JVM_MAXPATHLEN];
const char* o_result;
get_datetime_string(tms, sizeof(tms));
pid = os::current_process_id();
// test.log
- jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test.log", tms);
+ jio_snprintf(i_result, JVM_MAXPATHLEN, "test.log", tms);
o_result = make_log_name_internal("test.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result);
// test-%t-%p.log
- jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%s-pid%u.log", tms, pid);
+ jio_snprintf(i_result, JVM_MAXPATHLEN, "test-%s-pid%u.log", tms, pid);
o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result);
// test-%t%p.log
- jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%spid%u.log", tms, pid);
+ jio_snprintf(i_result, JVM_MAXPATHLEN, "test-%spid%u.log", tms, pid);
o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result);
// %p%t.log
- jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u%s.log", pid, tms);
+ jio_snprintf(i_result, JVM_MAXPATHLEN, "pid%u%s.log", pid, tms);
o_result = make_log_name_internal("%p%t.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result);
// %p-test.log
- jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u-test.log", pid);
+ jio_snprintf(i_result, JVM_MAXPATHLEN, "pid%u-test.log", pid);
o_result = make_log_name_internal("%p-test.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result);
// %t.log
- jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "%s.log", tms);
+ jio_snprintf(i_result, JVM_MAXPATHLEN, "%s.log", tms);
o_result = make_log_name_internal("%t.log", NULL, pid, tms);
assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)");
FREE_C_HEAP_ARRAY(char, o_result);
+
+ {
+ // longest filename
+ char longest_name[JVM_MAXPATHLEN];
+ memset(longest_name, 'a', sizeof(longest_name));
+ longest_name[JVM_MAXPATHLEN - 1] = '\0';
+ o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
+ assert(strcmp(longest_name, o_result) == 0, err_msg("longest name does not match. expected '%s' but got '%s'", longest_name, o_result));
+ FREE_C_HEAP_ARRAY(char, o_result);
+ }
+
+ {
+ // too long file name
+ char too_long_name[JVM_MAXPATHLEN + 100];
+ int too_long_length = sizeof(too_long_name);
+ memset(too_long_name, 'a', too_long_length);
+ too_long_name[too_long_length - 1] = '\0';
+ o_result = make_log_name_internal((const char*)&too_long_name, NULL, pid, tms);
+ assert(o_result == NULL, err_msg("Too long file name should return NULL, but got '%s'", o_result));
+ }
+
+ {
+ // too long with timestamp
+ char longest_name[JVM_MAXPATHLEN];
+ memset(longest_name, 'a', JVM_MAXPATHLEN);
+ longest_name[JVM_MAXPATHLEN - 3] = '%';
+ longest_name[JVM_MAXPATHLEN - 2] = 't';
+ longest_name[JVM_MAXPATHLEN - 1] = '\0';
+ o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
+ assert(o_result == NULL, err_msg("Too long file name after timestamp expansion should return NULL, but got '%s'", o_result));
+ }
+
+ {
+ // too long with pid
+ char longest_name[JVM_MAXPATHLEN];
+ memset(longest_name, 'a', JVM_MAXPATHLEN);
+ longest_name[JVM_MAXPATHLEN - 3] = '%';
+ longest_name[JVM_MAXPATHLEN - 2] = 'p';
+ longest_name[JVM_MAXPATHLEN - 1] = '\0';
+ o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms);
+ assert(o_result == NULL, err_msg("Too long file name after pid expansion should return NULL, but got '%s'", o_result));
+ }
}
#endif // PRODUCT
@@ -637,9 +682,16 @@
_bytes_written = 0L;
_file_name = make_log_name(file_name, NULL);
+ if (_file_name == NULL) {
+ warning("Cannot open file %s: file name is too long.\n", file_name);
+ _need_close = false;
+ UseGCLogFileRotation = false;
+ return;
+ }
+
// gc log file rotation
if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) {
- char tempbuf[FILENAMEBUFLEN];
+ char tempbuf[JVM_MAXPATHLEN];
jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
_file = fopen(tempbuf, "w");
} else {
@@ -671,10 +723,10 @@
// concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
// must be synchronized.
void gcLogFileStream::rotate_log(bool force, outputStream* out) {
- char time_msg[FILENAMEBUFLEN];
+ char time_msg[O_BUFLEN];
char time_str[EXTRACHARLEN];
- char current_file_name[FILENAMEBUFLEN];
- char renamed_file_name[FILENAMEBUFLEN];
+ char current_file_name[JVM_MAXPATHLEN];
+ char renamed_file_name[JVM_MAXPATHLEN];
if (!should_rotate(force)) {
return;
@@ -713,12 +765,15 @@
// have a form of extended_filename.<i>.current where i is the current rotation
// file number. After it reaches max file size, the file will be saved and renamed
// with .current removed from its tail.
- size_t filename_len = strlen(_file_name);
if (_file != NULL) {
- jio_snprintf(renamed_file_name, filename_len + EXTRACHARLEN, "%s.%d",
+ jio_snprintf(renamed_file_name, JVM_MAXPATHLEN, "%s.%d",
_file_name, _cur_file_num);
- jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX,
- _file_name, _cur_file_num);
+ int result = jio_snprintf(current_file_name, JVM_MAXPATHLEN,
+ "%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
+ if (result >= JVM_MAXPATHLEN) {
+ warning("Cannot create new log file name: %s: file name is too long.\n", current_file_name);
+ return;
+ }
const char* msg = force ? "GC log rotation request has been received."
: "GC log file has reached the maximum size.";
@@ -757,19 +812,23 @@
_cur_file_num++;
if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0;
- jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX,
+ int result = jio_snprintf(current_file_name, JVM_MAXPATHLEN, "%s.%d" CURRENTAPPX,
_file_name, _cur_file_num);
+ if (result >= JVM_MAXPATHLEN) {
+ warning("Cannot create new log file name: %s: file name is too long.\n", current_file_name);
+ return;
+ }
+
_file = fopen(current_file_name, "w");
if (_file != NULL) {
_bytes_written = 0L;
_need_close = true;
// reuse current_file_name for time_msg
- jio_snprintf(current_file_name, filename_len + EXTRACHARLEN,
+ jio_snprintf(current_file_name, JVM_MAXPATHLEN,
"%s.%d", _file_name, _cur_file_num);
jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n",
- os::local_time_string((char *)time_str, sizeof(time_str)),
- current_file_name);
+ os::local_time_string((char *)time_str, sizeof(time_str)), current_file_name);
write(time_msg, strlen(time_msg));
if (out != NULL) {
@@ -817,32 +876,64 @@
return _log_file != NULL;
}
+fileStream* defaultStream::open_file(const char* log_name) {
+ const char* try_name = make_log_name(log_name, NULL);
+ if (try_name == NULL) {
+ warning("Cannot open file %s: file name is too long.\n", log_name);
+ return NULL;
+ }
+
+ fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
+ FREE_C_HEAP_ARRAY(char, try_name);
+ if (file->is_open()) {
+ return file;
+ }
+
+ // Try again to open the file in the temp directory.
+ delete file;
+ char warnbuf[O_BUFLEN*2];
+ jio_snprintf(warnbuf, sizeof(warnbuf), "Warning: Cannot open log file: %s\n", log_name);
+ // Note: This feature is for maintainer use only. No need for L10N.
+ jio_print(warnbuf);
+ try_name = make_log_name(log_name, os::get_temp_directory());
+ if (try_name == NULL) {
+ warning("Cannot open file %s: file name is too long for directory %s.\n", log_name, os::get_temp_directory());
+ return NULL;
+ }
+
+ jio_snprintf(warnbuf, sizeof(warnbuf),
+ "Warning: Forcing option -XX:LogFile=%s\n", try_name);
+ jio_print(warnbuf);
+
+ file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
+ FREE_C_HEAP_ARRAY(char, try_name);
+ if (file->is_open()) {
+ return file;
+ }
+
+ delete file;
+ return NULL;
+}
+
void defaultStream::init_log() {
// %%% Need a MutexLocker?
const char* log_name = LogFile != NULL ? LogFile : "hotspot_%p.log";
- const char* try_name = make_log_name(log_name, NULL);
- fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
- if (!file->is_open()) {
- // Try again to open the file.
- char warnbuf[O_BUFLEN*2];
- jio_snprintf(warnbuf, sizeof(warnbuf),
- "Warning: Cannot open log file: %s\n", try_name);
- // Note: This feature is for maintainer use only. No need for L10N.
- jio_print(warnbuf);
- FREE_C_HEAP_ARRAY(char, try_name);
- try_name = make_log_name(log_name, os::get_temp_directory());
- jio_snprintf(warnbuf, sizeof(warnbuf),
- "Warning: Forcing option -XX:LogFile=%s\n", try_name);
- jio_print(warnbuf);
- delete file;
- file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
+ fileStream* file = open_file(log_name);
+
+ if (file != NULL) {
+ _log_file = file;
+ _outer_xmlStream = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file);
+ start_log();
+ } else {
+ // and leave xtty as NULL
+ LogVMOutput = false;
+ DisplayVMOutput = true;
+ LogCompilation = false;
}
- FREE_C_HEAP_ARRAY(char, try_name);
+}
- if (file->is_open()) {
- _log_file = file;
- xmlStream* xs = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file);
- _outer_xmlStream = xs;
+void defaultStream::start_log() {
+ xmlStream*xs = _outer_xmlStream;
if (this == tty) xtty = xs;
// Write XML header.
xs->print_cr("<?xml version='1.0' encoding='UTF-8'?>");
@@ -897,13 +988,6 @@
xs->head("tty");
// All further non-markup text gets copied to the tty:
xs->_text = this; // requires friend declaration!
- } else {
- delete(file);
- // and leave xtty as NULL
- LogVMOutput = false;
- DisplayVMOutput = true;
- LogCompilation = false;
- }
}
// finish_log() is called during normal VM shutdown. finish_log_on_error() is
--- a/hotspot/src/share/vm/utilities/vmError.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -22,6 +22,7 @@
*
*/
+#include <fcntl.h>
#include "precompiled.hpp"
#include "code/codeCache.hpp"
#include "compiler/compileBroker.hpp"
@@ -807,7 +808,8 @@
static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) {
int fd = -1;
if (Arguments::copy_expand_pid(pattern, strlen(pattern), &buf[pos], buflen - pos)) {
- fd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0666);
+ // the O_EXCL flag will cause the open to fail if the file exists
+ fd = open(buf, O_RDWR | O_CREAT | O_EXCL, 0666);
}
return fd;
}
--- a/hotspot/src/share/vm/utilities/xmlstream.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/src/share/vm/utilities/xmlstream.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -33,6 +33,10 @@
#include "runtime/vmThread.hpp"
#include "utilities/xmlstream.hpp"
+// Do not assert this condition if there's already another error reported.
+#define assert_if_no_error(cond, msg) \
+ vmassert((cond) || is_error_reported(), msg)
+
void xmlStream::initialize(outputStream* out) {
_out = out;
_last_flush = 0;
--- a/hotspot/test/TEST.groups Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/TEST.groups Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -69,7 +69,6 @@
gc/metaspace/TestPerfCountersAndMemoryPools.java \
runtime/6819213/TestBootNativeLibraryPath.java \
runtime/7158988/FieldMonitor.java \
- runtime/7194254/Test7194254.java \
runtime/Metaspace/FragmentMetaspace.java \
runtime/NMT/BaselineWithParameter.java \
runtime/NMT/JcmdBaselineDetail.java \
@@ -94,6 +93,7 @@
runtime/NMT/VirtualAllocTestType.java \
runtime/RedefineObject/TestRedefineObject.java \
runtime/Thread/TestThreadDumpMonitorContention.java \
+ runtime/Thread/ThreadPriorities.java \
runtime/XCheckJniJsig/XCheckJSig.java \
serviceability/attach/AttachWithStalePidFile.java \
serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \
@@ -145,6 +145,7 @@
gc/survivorAlignment \
runtime/InternalApi/ThreadCpuTimesDeadlock.java \
serviceability/threads/TestFalseDeadLock.java \
+ compiler/codecache/jmx
# Compact 2 adds full VM tests
compact2 = \
@@ -231,7 +232,8 @@
gc/g1/ \
gc/metaspace/G1AddMetaspaceDependency.java \
gc/metaspace/TestMetaspacePerfCounters.java \
- gc/startup_warnings/TestG1.java
+ gc/startup_warnings/TestG1.java \
+ gc/whitebox/TestConcMarkCycleWB.java
# All tests that explicitly set the serial GC
#
@@ -356,7 +358,8 @@
compiler/inlining/ \
compiler/integerArithmetic/ \
compiler/interpreter/ \
- -compiler/codegen/7184394
+ -compiler/codegen/7184394 \
+ -compiler/codecache/stress
hotspot_compiler_3 = \
compiler/intrinsics/ \
@@ -413,6 +416,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 +453,8 @@
:hotspot_compiler_3 \
:hotspot_compiler_closed \
:hotspot_gc \
+ :hotspot_gc_closed \
+ :hotspot_gc_gcold \
:hotspot_runtime \
:hotspot_runtime_closed \
:hotspot_serviceability
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestArrayCopyMacro.java Thu Jan 29 03:54:45 2015 +0000
@@ -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]);
+ }
+ }
+ }
+ }
+}
--- a/hotspot/test/compiler/arraycopy/TestArrayOfNoTypeCheck.java Wed Jan 28 17:48:59 2015 +0100
+++ /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");
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestArraysCopyOfNoTypeCheck.java Thu Jan 29 03:54:45 2015 +0000
@@ -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");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestInstanceCloneAsLoadsStores.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<String,Method> 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");
+ }
+
+ }
+}
--- a/hotspot/test/compiler/ciReplay/TestSA.sh Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/ciReplay/TestSA.sh Thu Jan 29 03:54:45 2015 +0000
@@ -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} ]
--- a/hotspot/test/compiler/ciReplay/common.sh Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/ciReplay/common.sh Thu Jan 29 03:54:45 2015 +0000
@@ -263,10 +263,10 @@
dir=`dirname $core_with_dir`
file=`basename $core_with_dir`
# add <core_path>/core.<pid> 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java Thu Jan 29 03:54:45 2015 +0000
@@ -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());
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/codeheapsize/CodeCacheFreeSpaceRunner.java Thu Jan 29 03:54:45 2015 +0000
@@ -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)));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/codeheapsize/GenericCodeHeapSizeRunner.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/codeheapsize/JVMStartupRunner.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestBase.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheCLITestCase.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<CodeCacheOptions, Boolean> ONLY_SEGMENTED
+ = options -> options.segmented;
+ private static final Function<CodeCacheOptions, Boolean> 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<CodeCacheOptions, Boolean> predicate,
+ EnumSet<BlobType> involvedCodeHeaps,
+ String... additionalOptions) {
+ this.description = new Description(predicate,
+ involvedCodeHeaps, additionalOptions);
+ }
+
+
+ public final Description description;
+ }
+
+ public static class Description {
+ public final EnumSet<BlobType> involvedCodeHeaps;
+ private final String[] testCaseSpecificOptions;
+ private final Function<CodeCacheOptions, Boolean> predicate;
+
+ public Description(Function<CodeCacheOptions, Boolean> predicate,
+ EnumSet<BlobType> 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<String> 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;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheInfoFormatter.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/common/CodeCacheOptions.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<BlobType> NON_SEGMENTED_HEAPS
+ = EnumSet.of(BlobType.All);
+ private static final EnumSet<BlobType> ALL_SEGMENTED_HEAPS
+ = EnumSet.complementOf(NON_SEGMENTED_HEAPS);
+ private static final EnumSet<BlobType> SEGMENTED_HEAPS_WO_PROFILED
+ = EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled);
+ private static final EnumSet<BlobType> 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<String> 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<BlobType> 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.");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/printcodecache/PrintCodeCacheRunner.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<BlobType> 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)));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Executable> 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<TestCombination> 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<TestCombination> 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<String, MethodData> data;
+
+ public TestCombination(int compLevels[], boolean inlines[]) {
+ Map<String, MethodData> 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<String> loadLog(String dtraceOutFile) throws IOException {
+ return Files.readAllLines(Paths.get(dtraceOutFile));
+ }
+
+ @Override
+ public void analyze(OutputAnalyzer oa, String dtraceOutFilePath) {
+ oa.shouldHaveExitValue(0);
+ List<String> 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;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestScript.d Thu Jan 29 03:54:45 2015 +0000
@@ -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();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestWorker.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Executable> TESTED_METHODS_LIST;
+ private final WhiteBox wb;
+ private final int compLevels[];
+
+ static {
+ List<Executable> 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 <thisClass> <fooCompLevel> <fooInlined>"
+ + "<barCompLevel> <barInlined> "
+ + "<bazCompLevel> <bazInlined>");
+ } 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");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/BeanTypeTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/CodeCacheUtils.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/CodeHeapBeanPresenceTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<BlobType> shouldBeAvailable = BlobType.getAvailable();
+ EnumSet<BlobType> 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());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/GetUsageTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<MemoryPoolMXBean, Long> getBeanUsages() {
+ Map<MemoryPoolMXBean, Long> 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<MemoryPoolMXBean, Long> initial = getBeanUsages();
+ long addr = 0;
+ try {
+ addr = CodeCacheUtils.WB.allocateCodeBlob(allocateSize, btype.id);
+ Map<MemoryPoolMXBean, Long> 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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/InitialAndMaxUsageTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Long> 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<Long> 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());
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/ManagerNamesTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/MemoryPoolsPresenceTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<String, Integer> counters = new HashMap<>();
+
+ public static void main(String args[]) {
+ new MemoryPoolsPresenceTest().runTest();
+ }
+
+ protected void runTest() {
+ List<MemoryManagerMXBean> beans
+ = ManagementFactory.getMemoryManagerMXBeans();
+ Optional<MemoryManagerMXBean> 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");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/PeakUsageTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/PoolsIndependenceTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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.
+ */
+
+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
+ * @ignore 8068385
+ * @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<String, AtomicInteger> 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();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/ThresholdNotificationsTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededSeveralTimesTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdExceededTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdIncreasedTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/jmx/UsageThresholdNotExceededTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/stress/CodeCacheStressRunner.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,52 @@
+/*
+ * 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.TimeLimitedRunner;
+import com.oracle.java.testlibrary.Utils;
+
+public class CodeCacheStressRunner {
+ private final Runnable action;
+ public CodeCacheStressRunner(Runnable action) {
+ this.action = action;
+ }
+
+ protected final void runTest() {
+ Helper.startInfiniteLoopThread(action);
+ try {
+ // adjust timeout and substract vm init and exit time
+ long timeout = Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT);
+ timeout *= 0.9;
+ new TimeLimitedRunner(timeout, 2.0d, this::test).call();
+ } catch (Exception e) {
+ throw new Error("Exception occurred during test execution", e);
+ }
+ }
+
+ private boolean test() {
+ Helper.TestCase obj = Helper.TestCase.get();
+ Helper.callMethod(obj.getCallable(), obj.expectedValue());
+ return true;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/stress/Helper.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,141 @@
+/*
+ * 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 java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.concurrent.Callable;
+import java.util.Random;
+
+import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.ByteCodeLoader;
+import com.oracle.java.testlibrary.InfiniteLoop;
+import com.oracle.java.testlibrary.Utils;
+import sun.hotspot.WhiteBox;
+
+public final class Helper {
+ public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+ public static final Random RNG = Utils.getRandomInstance();
+
+ private static final long THRESHOLD = WHITE_BOX.getIntxVMFlag("CompileThreshold");
+ private static final String TEST_CASE_IMPL_CLASS_NAME = "Helper$TestCaseImpl";
+ private static byte[] CLASS_DATA;
+ static {
+ try {
+ CLASS_DATA = loadClassData(TEST_CASE_IMPL_CLASS_NAME);
+ } catch (IOException e) {
+ throw new Error("TESTBUG: cannot load class byte code", e);
+ }
+ }
+
+ private Helper() {
+ }
+
+ public static void startInfiniteLoopThread(Runnable action) {
+ startInfiniteLoopThread(action, 0L);
+ }
+
+ public static void startInfiniteLoopThread(Runnable action, long millis) {
+ Thread t = new Thread(new InfiniteLoop(action, millis));
+ t.setDaemon(true);
+ t.start();
+ }
+
+ public static int callMethod(Callable<Integer> callable, int expected) {
+ int result = 0;
+ for (int i = 0; i < THRESHOLD; ++i) {
+ try {
+ result = callable.call();
+ } catch (Exception e) {
+ throw new AssertionError(
+ "Exception occurred during test method execution", e);
+ }
+ Asserts.assertEQ(result, expected, "Method returns unexpected value");
+ }
+ return result;
+ }
+
+ private static byte[] loadClassData(String name) throws IOException {
+ try (BufferedInputStream in = new BufferedInputStream(
+ ClassLoader.getSystemResourceAsStream(name.replace(".", "/")
+ + ".class"))) {
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int read;
+ while ((read = in.read(buffer)) != -1) {
+ result.write(buffer, 0, read);
+ }
+ return result.toByteArray();
+ }
+ }
+
+ public interface TestCase {
+
+ public static TestCase get() {
+ try {
+ Class clazz = ByteCodeLoader.load(
+ TEST_CASE_IMPL_CLASS_NAME, CLASS_DATA);
+ return (TestCase) clazz.newInstance();
+ } catch (ReflectiveOperationException e) {
+ throw new Error(String.format(
+ "TESTBUG: error while creating %s instance from reloaded class",
+ TEST_CASE_IMPL_CLASS_NAME), e);
+ }
+ }
+
+ Callable<Integer> getCallable();
+ int method();
+ int expectedValue();
+ }
+
+ public static class TestCaseImpl implements TestCase {
+ private static final int RETURN_VALUE = 42;
+ private static final int RECURSION_DEPTH = 10;
+ private volatile int i;
+
+ @Override
+ public Callable<Integer> getCallable() {
+ return () -> {
+ i = 0;
+ return method();
+ };
+ }
+
+ @Override
+ public int method() {
+ ++i;
+ int result = RETURN_VALUE;
+ if (i < RECURSION_DEPTH) {
+ return result + method();
+ }
+ return result;
+ }
+
+ @Override
+ public int expectedValue() {
+ return RETURN_VALUE * RECURSION_DEPTH;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,111 @@
+/*
+ * 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 java.lang.reflect.Method;
+import java.util.stream.IntStream;
+
+import com.oracle.java.testlibrary.Platform;
+
+/*
+ * @test OverloadCompileQueueTest
+ * @library /testlibrary /../../test/lib
+ * @build OverloadCompileQueueTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:CompileCommand=dontinline,Helper$TestCase::method
+ * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache OverloadCompileQueueTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:CompileCommand=dontinline,Helper$TestCase::method
+ * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache OverloadCompileQueueTest
+ * @summary stressing code cache by overloading compile queues
+ */
+public class OverloadCompileQueueTest implements Runnable {
+ private static final int MAX_SLEEP = 10000;
+ private static final String METHOD_TO_ENQUEUE = "method";
+ private static final int LEVEL_SIMPLE = 1;
+ private static final int LEVEL_FULL_OPTIMIZATION = 4;
+ private static final boolean INTERPRETED
+ = System.getProperty("java.vm.info").startsWith("interpreted ");
+ private static final boolean TIERED_COMPILATION
+ = Helper.WHITE_BOX.getBooleanVMFlag("TieredCompilation");
+ private static final int TIERED_STOP_AT_LEVEL
+ = Helper.WHITE_BOX.getIntxVMFlag("TieredStopAtLevel").intValue();
+ private static final int[] AVAILABLE_LEVELS;
+ static {
+ if (TIERED_COMPILATION) {
+ AVAILABLE_LEVELS = IntStream
+ .rangeClosed(LEVEL_SIMPLE, TIERED_STOP_AT_LEVEL)
+ .toArray();
+ } else if (Platform.isServer()) {
+ AVAILABLE_LEVELS = new int[] { LEVEL_FULL_OPTIMIZATION };
+ } else if (Platform.isClient() || Platform.isMinimal()) {
+ AVAILABLE_LEVELS = new int[] { LEVEL_SIMPLE };
+ } else {
+ throw new Error(String.format(
+ "TESTBUG: unknown VM: %s", System.getProperty("java.vm.name")));
+ }
+ }
+
+ public static void main(String[] args) {
+ if (INTERPRETED) {
+ System.err.println("Test isn't applicable for interpreter. Skip test.");
+ return;
+ }
+ new CodeCacheStressRunner(new OverloadCompileQueueTest()).runTest();
+ }
+
+ public OverloadCompileQueueTest() {
+ Helper.startInfiniteLoopThread(this::lockUnlock);
+ }
+
+ @Override
+ public void run() {
+ Helper.TestCase obj = Helper.TestCase.get();
+ Class clazz = obj.getClass();
+ Method mEnqueue;
+ try {
+ mEnqueue = clazz.getMethod(METHOD_TO_ENQUEUE);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new Error(String.format(
+ "TESTBUG: cannot get method '%s' of class %s",
+ METHOD_TO_ENQUEUE, clazz.getName()), e);
+ }
+ for (int compLevel : AVAILABLE_LEVELS) {
+ Helper.WHITE_BOX.enqueueMethodForCompilation(mEnqueue, compLevel);
+ }
+ }
+
+ private void lockUnlock() {
+ try {
+ Helper.WHITE_BOX.lockCompilation();
+ Thread.sleep(Helper.RNG.nextInt(MAX_SLEEP));
+ } catch (InterruptedException e) {
+ throw new Error("TESTBUG: lockUnlocker thread was unexpectedly interrupted", e);
+ } finally {
+ Helper.WHITE_BOX.unlockCompilation();
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/stress/RandomAllocationTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,71 @@
+/*
+ * 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 java.util.ArrayList;
+
+import sun.hotspot.code.BlobType;
+
+/*
+ * @test RandomAllocationTest
+ * @library /testlibrary /../../test/lib
+ * @build RandomAllocationTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:CompileCommand=dontinline,Helper$TestCase::method
+ * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache RandomAllocationTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:CompileCommand=dontinline,Helper$TestCase::method
+ * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache RandomAllocationTest
+ * @summary stressing code cache by allocating randomly sized "dummy" code blobs
+ */
+public class RandomAllocationTest implements Runnable {
+ private static final long CODE_CACHE_SIZE
+ = Helper.WHITE_BOX.getUintxVMFlag("ReservedCodeCacheSize");
+ private static final int MAX_BLOB_SIZE = (int) (CODE_CACHE_SIZE >> 7);
+ private static final BlobType[] BLOB_TYPES
+ = BlobType.getAvailable().toArray(new BlobType[0]);
+
+ public static void main(String[] args) {
+ new CodeCacheStressRunner(new RandomAllocationTest()).runTest();
+ }
+
+ private final ArrayList<Long> blobs = new ArrayList<>();
+ @Override
+ public void run() {
+ boolean allocate = blobs.isEmpty() || Helper.RNG.nextBoolean();
+ if (allocate) {
+ int type = Helper.RNG.nextInt(BLOB_TYPES.length);
+ long addr = Helper.WHITE_BOX.allocateCodeBlob(
+ Helper.RNG.nextInt(MAX_BLOB_SIZE), BLOB_TYPES[type].id);
+ if (addr != 0) {
+ blobs.add(addr);
+ }
+ } else {
+ int index = Helper.RNG.nextInt(blobs.size());
+ Helper.WHITE_BOX.freeCodeBlob(blobs.remove(index));
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codecache/stress/UnexpectedDeoptimizationTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,52 @@
+/*
+ * 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 UnexpectedDeoptimizationTest
+ * @library /testlibrary /../../test/lib
+ * @build UnexpectedDeoptimizationTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:CompileCommand=dontinline,Helper$TestCase::method
+ * -XX:+WhiteBoxAPI -XX:-SegmentedCodeCache -XX:-DeoptimizeRandom
+ * UnexpectedDeoptimizationTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:CompileCommand=dontinline,Helper$TestCase::method
+ * -XX:+WhiteBoxAPI -XX:+SegmentedCodeCache -XX:-DeoptimizeRandom
+ * UnexpectedDeoptimizationTest
+ * @summary stressing code cache by forcing unexpected deoptimizations
+ */
+public class UnexpectedDeoptimizationTest implements Runnable {
+
+ public static void main(String[] args) {
+ new CodeCacheStressRunner(new UnexpectedDeoptimizationTest()).runTest();
+ }
+
+ @Override
+ public void run() {
+ Helper.WHITE_BOX.deoptimizeFrames(Helper.RNG.nextBoolean());
+ }
+
+}
--- a/hotspot/test/compiler/exceptions/TestRecursiveReplacedException.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/exceptions/TestRecursiveReplacedException.java Thu Jan 29 03:54:45 2015 +0000
@@ -25,7 +25,7 @@
* @test
* @bug 8054224
* @summary Recursive method compiled by C1 is unable to catch StackOverflowError
- * @run main/othervm -Xcomp -XX:CompileOnly=Test.run -XX:+TieredCompilation -XX:TieredStopAtLevel=2 -Xss256K TestRecursiveReplacedException
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test.run -XX:+TieredCompilation -XX:TieredStopAtLevel=2 -Xss392K TestRecursiveReplacedException
*
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/floatingpoint/TestPow2.java Thu Jan 29 03:54:45 2015 +0000
@@ -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.
+ */
+
+/*
+ * @test
+ * @bug 8063086
+ * @summary X^2 special case for C2 yields different result than interpreter
+ * @library /testlibrary /../../test/lib /compiler/whitebox
+ * @build TestPow2
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestPow2
+ *
+ */
+
+import java.lang.reflect.*;
+import sun.hotspot.WhiteBox;
+
+public class TestPow2 {
+
+ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+ private static final double base = 5350.456329377186;
+ private static final double exp = 2.0;
+
+ static double m() {
+ return Math.pow(base, exp);
+ }
+
+ static public void main(String[] args) throws NoSuchMethodException {
+ Method test_method = TestPow2.class.getDeclaredMethod("m");
+
+ double interpreter_result = m();
+
+ // Compile with C1 if possible
+ WHITE_BOX.enqueueMethodForCompilation(test_method, CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE);
+
+ double c1_result = m();
+
+ WHITE_BOX.deoptimizeMethod(test_method);
+
+ // Compile it with C2 if possible
+ WHITE_BOX.enqueueMethodForCompilation(test_method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
+
+ double c2_result = m();
+
+ if (interpreter_result != c1_result || interpreter_result != c2_result ||
+ c1_result != c2_result) {
+ System.out.println("interpreter = " + interpreter_result + " c1 = " + c1_result + " c2 = " + c2_result);
+ throw new RuntimeException("Test Failed");
+ }
+ }
+}
--- a/hotspot/test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/jsr292/RedefineMethodUsedByMultipleMethodHandles.java Thu Jan 29 03:54:45 2015 +0000
@@ -26,6 +26,7 @@
* @bug 8042235
* @summary redefining method used by multiple MethodHandles crashes VM
* @compile -XDignore.symbol.file RedefineMethodUsedByMultipleMethodHandles.java
+ * @ignore 7076820
* @run main RedefineMethodUsedByMultipleMethodHandles
*/
--- a/hotspot/test/compiler/oracle/CheckCompileCommandOption.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/oracle/CheckCompileCommandOption.java Thu Jan 29 03:54:45 2015 +0000
@@ -172,7 +172,7 @@
out.shouldContain(expected_output);
}
- out.shouldNotContain("CompilerOracle: unrecognized line");
+ out.shouldNotContain("CompileCommand: unrecognized line");
out.shouldHaveExitValue(0);
}
@@ -183,7 +183,7 @@
pb = ProcessTools.createJavaProcessBuilder(arguments);
out = new OutputAnalyzer(pb.start());
- out.shouldContain("CompilerOracle: unrecognized line");
+ out.shouldContain("CompileCommand: unrecognized line");
out.shouldHaveExitValue(0);
}
--- a/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/profiling/spectrapredefineclass/Launcher.java Thu Jan 29 03:54:45 2015 +0000
@@ -28,6 +28,7 @@
* @bug 8038636
* @library /testlibrary
* @build Agent
+ * @ignore 7076820
* @run main ClassFileInstaller Agent
* @run main Launcher
* @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222 -XX:ReservedCodeCacheSize=3M Agent
--- a/hotspot/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/profiling/spectrapredefineclass_classloaders/Launcher.java Thu Jan 29 03:54:45 2015 +0000
@@ -28,6 +28,7 @@
* @bug 8040237
* @library /testlibrary
* @build Agent Test A B
+ * @ignore 7076820
* @run main ClassFileInstaller Agent
* @run main Launcher
* @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222 -XX:ReservedCodeCacheSize=3M Agent
--- a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
}
--- a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Thu Jan 29 03:54:45 2015 +0000
@@ -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 {
--- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Thu Jan 29 03:54:45 2015 +0000
@@ -53,6 +53,7 @@
*/
public class TestRTMDeoptOnLowAbortRatio extends CommandLineOptionTest {
private static final long LOCKING_THRESHOLD = 100L;
+ private static final long ABORT_THRESHOLD = LOCKING_THRESHOLD / 2L;
private TestRTMDeoptOnLowAbortRatio() {
super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
@@ -77,7 +78,8 @@
useStackLock),
CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD),
- "-XX:RTMAbortThreshold=1",
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+ TestRTMDeoptOnLowAbortRatio.ABORT_THRESHOLD),
"-XX:RTMAbortRatio=100",
"-XX:CompileThreshold=1",
"-XX:RTMRetryCount=0",
@@ -107,7 +109,7 @@
for (RTMLockingStatistics s : statistics) {
if (s.getTotalLocks()
- == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD + 1L) {
+ == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD) {
Asserts.assertNull(statisticsBeforeDeopt,
"Only one abort was expected during test run");
statisticsBeforeDeopt = s;
@@ -130,10 +132,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,13 +150,13 @@
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++) {
- t.forceAbort(
- i == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD);
+ AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated);
+ t.forceAbort(i >= TestRTMDeoptOnLowAbortRatio.ABORT_THRESHOLD);
}
}
}
--- a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Thu Jan 29 03:54:45 2015 +0000
@@ -58,7 +58,7 @@
* interrupts, VMM calls, etc. during first lock attempt.
*
*/
- private static final int ABORT_THRESHOLD = 10;
+ private static final int MIN_ABORT_THRESHOLD = 10;
@Override
protected void runTestCases() throws Throwable {
@@ -75,6 +75,9 @@
boolean useStackLock) throws Throwable {
CompilableTest test = new Test();
+ int abortThreshold = Math.max(lockingThreshold / 2,
+ TestRTMLockingThreshold.MIN_ABORT_THRESHOLD);
+
OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
test,
"-XX:CompileThreshold=1",
@@ -84,7 +87,7 @@
"-XX:RTMTotalCountIncrRate=1",
"-XX:RTMRetryCount=0",
CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
- TestRTMLockingThreshold.ABORT_THRESHOLD),
+ abortThreshold),
CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
lockingThreshold),
"-XX:RTMAbortRatio=100",
@@ -103,16 +106,12 @@
+ "RTM locking statistics entries.");
/**
- * We force abort on each odd iteration, so if RTMLockingThreshold==0,
- * then we have to make 1 call without abort to avoid rtm state
- * transition to NoRTM (otherwise actual abort ratio will be 100%),
- * and after that make 1 call with abort to force deoptimization.
- * This leads us to two locks for threshold 0.
- * For other threshold values we have to make RTMLockingThreshold + 1
- * locks if locking threshold is even, or + 0 if odd.
+ * If RTMLockingThreshold==0, then we have to make at least 1 call.
*/
- long expectedValue = lockingThreshold +
- (lockingThreshold == 0L ? 2L : lockingThreshold % 2L);
+ long expectedValue = lockingThreshold;
+ if (expectedValue == 0) {
+ expectedValue++;
+ }
RTMLockingStatistics statBeforeDeopt = null;
for (RTMLockingStatistics s : statistics) {
@@ -143,10 +142,7 @@
@Override
public String[] getMethodsToCompileNames() {
- return new String[] {
- getMethodWithLockName(),
- sun.misc.Unsafe.class.getName() + "::addressSize"
- };
+ return new String[] { getMethodWithLockName() };
}
public void lock(boolean abort) {
@@ -162,14 +158,16 @@
* Test <inflate monitor>
*/
public static void main(String args[]) throws Throwable {
- Asserts.assertGTE(args.length, 1, "One argument required.");
+ Asserts.assertGTE(args.length, 2, "Two arguments required.");
Test t = new Test();
-
- if (Boolean.valueOf(args[0])) {
+ boolean shouldBeInflated = Boolean.valueOf(args[0]);
+ int lockingThreshold = Integer.valueOf(args[1]);
+ if (shouldBeInflated) {
AbortProvoker.inflateMonitor(t.monitor);
}
for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) {
- t.lock(i % 2 == 1);
+ AbortProvoker.verifyMonitorState(t.monitor, shouldBeInflated);
+ t.lock(i >= lockingThreshold / 2);
}
}
}
--- a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Thu Jan 29 03:54:45 2015 +0000
@@ -35,6 +35,7 @@
* -XX:+WhiteBoxAPI TestRTMTotalCountIncrRate
*/
+import sun.misc.Unsafe;
import java.util.List;
import com.oracle.java.testlibrary.*;
@@ -97,14 +98,12 @@
Asserts.assertEQ(lock.getTotalLocks(), Test.TOTAL_ITERATIONS,
"Total locks should be exactly the same as amount of "
+ "iterations.");
- } else {
- Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM statistics "
- + "should contain information for at least on lock.");
}
}
public static class Test implements CompilableTest {
private static final long TOTAL_ITERATIONS = 10000L;
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
private final Object monitor = new Object();
// Following field have to be static in order to avoid escape analysis.
@SuppressWarnings("UnsuedDeclaration")
@@ -117,13 +116,20 @@
@Override
public String[] getMethodsToCompileNames() {
- return new String[] {
- getMethodWithLockName()
- };
+ return new String[] { getMethodWithLockName() };
}
- public void lock() {
+ public void lock(booleab forceAbort) {
synchronized(monitor) {
+ if (forceAbort) {
+ // We're calling native method in order to force
+ // abort. It's done by explicit xabort call emitted
+ // in SharedRuntime::generate_native_wrapper.
+ // If an actuall JNI call will be replaced by
+ // intrinsic - we'll be in trouble, since xabort
+ // will be no longer called and test may fail.
+ UNSAFE.addressSize();
+ }
Test.field++;
}
}
@@ -135,12 +141,18 @@
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++) {
- test.lock();
+ AbortProvoker.verifyMonitorState(test.monitor,
+ shouldBeInflated);
+ // Force abort on first iteration to avoid rare case when
+ // there were no aborts and locks count was not incremented
+ // with RTMTotalCountIncrRate > 1 (in such case JVM won't
+ // print JVM locking statistics).
+ test.lock(i == 0);
}
}
}
--- a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
}
}
--- a/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java Thu Jan 29 03:54:45 2015 +0000
@@ -125,9 +125,6 @@
RTMLockingStatistics lock = statistics.get(0);
- Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM locking statistics "
- + "should contain non zero total locks count");
-
Asserts.assertGT(lock.getTotalAborts(), 0L,
"RTM locking statistics should contain non zero total aborts "
+ "count");
--- a/hotspot/test/compiler/runtime/6865265/StackOverflowBug.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/runtime/6865265/StackOverflowBug.java Thu Jan 29 03:54:45 2015 +0000
@@ -28,7 +28,7 @@
* @summary JVM crashes with "missing exception handler" error
* @author volker.simonis@sap.com
*
- * @run main/othervm -XX:CompileThreshold=100 -Xbatch -Xss248k StackOverflowBug
+ * @run main/othervm -XX:CompileThreshold=100 -Xbatch -Xss392k StackOverflowBug
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/CompilerUtils.java Thu Jan 29 03:54:45 2015 +0000
@@ -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];
+ }
+}
--- a/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
}
}
--- a/hotspot/test/compiler/testlibrary/rtm/BusyLock.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
}
}
--- a/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java Thu Jan 29 03:54:45 2015 +0000
@@ -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) {
--- a/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java Thu Jan 29 03:54:45 2015 +0000
@@ -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()) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/uncommontrap/Verifier.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,145 @@
+/*
+ * 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 uncommontrap;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import com.oracle.java.testlibrary.Asserts;
+/**
+ * Utility tool aimed to verify presence or absence of specified uncommon trap
+ * in compilation log.
+ */
+public class Verifier {
+ public static final String PROPERTIES_FILE_SUFFIX = ".verify.properties";
+ public static final String VERIFICATION_SHOULD_BE_SKIPPED
+ = "uncommon.trap.verification.skipped";
+ public static final String UNCOMMON_TRAP_NAME = "uncommon.trap.name";
+ public static final String UNCOMMON_TRAP_BCI = "uncommon.trap.bci";
+ public static final String UNCOMMON_TRAP_COMMENT = "uncommon.trap.comment";
+ public static final String UNCOMMON_TRAP_ACTION = "uncommon.trap.action";
+ public static final String UNCOMMON_TRAP_SHOULD_EMITTED
+ = "uncommon.trap.emitted";
+ public static final String UNCOMMON_TRAP_SHOULD_FIRED
+ = "uncommon.trap.fired";
+
+ private static final String EMITTED_TRAP_PATTERN
+ = "<uncommon_trap bci='%s' reason='%s' action='%s' "
+ + "comment='%s'";
+ private static final String FIRED_TRAP_PATTERN
+ = "<uncommon_trap thread='[0-9]*' reason='%s' action='%s'";
+ private static final String JVMS_PATTERN = "<jvms bci='%s'";
+
+ public static void main(String args[]) {
+ if (args.length == 0) {
+ throw new Error("At least one argument containing name of "
+ + "compilation log file is expected");
+ }
+
+ for (String compLogFile : args) {
+ try {
+ verify(Paths.get(compLogFile));
+ } catch (IOException e) {
+ throw new Error("Unable to process compilation log.", e);
+ }
+ }
+ }
+
+ private static void verify(Path compLogFile) throws IOException {
+ Path propertiesFile = Paths.get(compLogFile.toString() +
+ PROPERTIES_FILE_SUFFIX);
+
+ Properties properties = new Properties();
+ properties.load(new FileReader(propertiesFile.toFile()));
+
+ if (Boolean.valueOf(properties.getProperty(
+ VERIFICATION_SHOULD_BE_SKIPPED, "false"))) {
+ System.out.println("Skipping verification for log file: "
+ + compLogFile.toString());
+ return;
+ }
+
+ System.out.println("Verifying log file: " + compLogFile.toString());
+
+ List<String> compLogContent = Files.readAllLines(compLogFile);
+ verifyUncommonTrapEmitted(properties, compLogContent);
+ verifyUncommonTrapFired(properties, compLogContent);
+ }
+
+ private static void verifyUncommonTrapEmitted(Properties properties,
+ List<String> compLogContent) {
+ String emittedTrapRE = String.format(EMITTED_TRAP_PATTERN,
+ properties.getProperty(UNCOMMON_TRAP_BCI, ".*"),
+ properties.getProperty(UNCOMMON_TRAP_NAME, ".*"),
+ properties.getProperty(UNCOMMON_TRAP_ACTION, ".*"),
+ properties.getProperty(UNCOMMON_TRAP_COMMENT, ".*"));
+ Pattern pattern = Pattern.compile(emittedTrapRE);
+
+ long trapsCount = compLogContent.stream()
+ .filter(line -> pattern.matcher(line).find())
+ .count();
+
+ boolean shouldBeEmitted = Boolean.valueOf(
+ properties.getProperty(UNCOMMON_TRAP_SHOULD_EMITTED));
+
+ Asserts.assertEQ(shouldBeEmitted, trapsCount > 0, String.format(
+ "Uncommon trap that matches following string in compilation log"
+ + " should %sbe emitted: %s.",
+ (shouldBeEmitted ? " " : "not "), emittedTrapRE));
+ }
+
+ private static void verifyUncommonTrapFired(Properties properties,
+ List<String> compLogContent) {
+ String firedTrapRE = String.format(FIRED_TRAP_PATTERN,
+ properties.getProperty(UNCOMMON_TRAP_NAME, ".*"),
+ properties.getProperty(UNCOMMON_TRAP_ACTION, ".*"));
+ String jvmsRE = String.format(JVMS_PATTERN,
+ properties.getProperty(UNCOMMON_TRAP_BCI, ".*"));
+
+ boolean trapFired = false;
+ Pattern firedTrapPattern = Pattern.compile(firedTrapRE);
+ Pattern jvmsPattern = Pattern.compile(jvmsRE);
+
+ Iterator<String> iterator = compLogContent.iterator();
+ while (iterator.hasNext() && !trapFired) {
+ trapFired = firedTrapPattern.matcher(iterator.next()).find()
+ && jvmsPattern.matcher(iterator.next()).find();
+ }
+
+ boolean shouldBeFired = Boolean.valueOf(
+ properties.getProperty(UNCOMMON_TRAP_SHOULD_FIRED));
+ Asserts.assertEQ(shouldBeFired, trapFired, String.format(
+ "Uncommon trap that matches following string in compilation log"
+ + " should %sbe fired: %s.",
+ (shouldBeFired ? "" : "not "), firedTrapRE));
+ }
+}
+
--- a/hotspot/test/compiler/uncommontrap/8009761/Test8009761.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/uncommontrap/8009761/Test8009761.java Thu Jan 29 03:54:45 2015 +0000
@@ -32,7 +32,7 @@
* @build Test8009761
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss256K Test8009761
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss392K Test8009761
*/
public class Test8009761 {
--- a/hotspot/test/compiler/uncommontrap/StackOverflowGuardPagesOff.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/uncommontrap/StackOverflowGuardPagesOff.java Thu Jan 29 03:54:45 2015 +0000
@@ -25,7 +25,7 @@
* @test
* @bug 8029383
* @summary stack overflow if callee is marked for deoptimization causes crash
- * @run main/othervm -XX:TieredStopAtLevel=1 -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,StackOverflowGuardPagesOff::m1 -XX:CompileCommand=exclude,StackOverflowGuardPagesOff::m2 -Xss256K -XX:-UseOnStackReplacement StackOverflowGuardPagesOff
+ * @run main/othervm -XX:TieredStopAtLevel=1 -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,StackOverflowGuardPagesOff::m1 -XX:CompileCommand=exclude,StackOverflowGuardPagesOff::m2 -Xss392K -XX:-UseOnStackReplacement StackOverflowGuardPagesOff
*
*/
--- a/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/uncommontrap/TestStackBangMonitorOwned.java Thu Jan 29 03:54:45 2015 +0000
@@ -25,7 +25,7 @@
* @test
* @bug 8032410
* @summary Stack overflow at deoptimization doesn't release owned monitors
- * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangMonitorOwned::m1 -XX:CompileCommand=exclude,TestStackBangMonitorOwned::m2 -Xss256K -XX:-UseOnStackReplacement TestStackBangMonitorOwned
+ * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangMonitorOwned::m1 -XX:CompileCommand=exclude,TestStackBangMonitorOwned::m2 -Xss392K -XX:-UseOnStackReplacement TestStackBangMonitorOwned
*
*/
public class TestStackBangMonitorOwned {
--- a/hotspot/test/compiler/uncommontrap/TestStackBangRbp.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/uncommontrap/TestStackBangRbp.java Thu Jan 29 03:54:45 2015 +0000
@@ -25,7 +25,7 @@
* @test
* @bug 8028308
* @summary rbp not restored when stack overflow is thrown from deopt/uncommon trap blobs
- * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangRbp::m1 -XX:CompileCommand=exclude,TestStackBangRbp::m2 -Xss256K -XX:-UseOnStackReplacement TestStackBangRbp
+ * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=dontinline,TestStackBangRbp::m1 -XX:CompileCommand=exclude,TestStackBangRbp::m2 -Xss392K -XX:-UseOnStackReplacement TestStackBangRbp
*
*/
public class TestStackBangRbp {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/uncommontrap/TestUnstableIfTrap.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,257 @@
+/*
+ * 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 java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+import com.oracle.java.testlibrary.ByteCodeLoader;
+import com.oracle.java.testlibrary.Platform;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+import sun.hotspot.WhiteBox;
+import uncommontrap.Verifier;
+
+/*
+ * @test
+ * @bug 8030976 8059226
+ * @library /testlibrary /compiler/testlibrary /../../test/lib
+ * @build TestUnstableIfTrap com.oracle.java.testlibrary.* uncommontrap.Verifier
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbatch -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,UnstableIfExecutable.test
+ * -XX:LogFile=always_taken_not_fired.xml
+ * TestUnstableIfTrap ALWAYS_TAKEN false
+ * @run main/othervm -Xbatch -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,UnstableIfExecutable.test
+ * -XX:LogFile=always_taken_fired.xml
+ * TestUnstableIfTrap ALWAYS_TAKEN true
+ * @run main/othervm -Xbatch -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,UnstableIfExecutable.test
+ * -XX:LogFile=never_taken_not_fired.xml
+ * TestUnstableIfTrap NEVER_TAKEN false
+ * @run main/othervm -Xbatch -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI -XX:+LogCompilation
+ * -XX:CompileCommand=compileonly,UnstableIfExecutable.test
+ * -XX:LogFile=never_taken_fired.xml
+ * TestUnstableIfTrap NEVER_TAKEN true
+ * @run main uncommontrap.Verifier always_taken_not_fired.xml
+ * always_taken_fired.xml
+ * never_taken_not_fired.xml
+ * never_taken_fired.xml
+ */
+public class TestUnstableIfTrap {
+ private static final WhiteBox WB = WhiteBox.getWhiteBox();
+ private static final String CLASS_NAME = "UnstableIfExecutable";
+ private static final String METHOD_NAME = "test";
+ private static final String FIELD_NAME = "field";
+ private static final int ITERATIONS = 1_000_000;
+ // There is no dependency on particular class file version, so it could be
+ // set to any version (if you're updating this test for Java 42).
+ private static final int CLASS_FILE_VERSION = 49;
+ private static final int MAX_TIER = 4;
+ // This test aimed to verify that uncommon trap with reason "unstable_if"
+ // is emitted when method that contain control-flow divergence such that
+ // one of two branches is never taken (and other one is taken always).
+ // C2 will made a decision whether or not the branch was ever taken
+ // depending on method's profile.
+ // If profile was collected for a few method's invocations, then C2 will not
+ // trust in branches' probabilities and the tested trap won't be emitted.
+ // In fact, a method has to be invoked at least 40 time at the day when this
+ // comment was written (see Parse::dynamic_branch_prediction for an actual
+ // value). It would be to implementation dependent to use "40" as
+ // a threshold value in the test, so in order to improve test's robustness
+ // the threshold value is 1000: if the tested method was compiled by C2
+ // before it was invoked 1000 times, then we won't verify that trap was
+ // emitted and fired.
+ private static final int MIN_INVOCATIONS_BEFORE_C2_COMPILATION = 1000;
+ /**
+ * Description of test case parameters and uncommon trap that will
+ * be emitted during tested method compilation.
+ */
+ private static enum TestCaseName {
+ ALWAYS_TAKEN(false, "taken always"),
+ NEVER_TAKEN(true, "taken never");
+ TestCaseName(boolean predicate, String comment) {
+ this.predicate = predicate;
+ this.comment = comment;
+ }
+
+ public final boolean predicate;
+ public final String name = "unstable_if";
+ public final String comment;
+ }
+
+ public static void main(String args[]) {
+ if (args.length != 2) {
+ throw new Error("Expected two arguments: test case name and a "
+ + "boolean determining if uncommon trap should be fired.");
+ }
+ test(TestCaseName.valueOf(args[0]), Boolean.valueOf(args[1]));
+ }
+
+ private static void test(TestCaseName testCase, boolean shouldBeFired) {
+ Method testMethod;
+ Label unstableIfLocation = new Label();
+ boolean shouldBeEmitted;
+ boolean compiledToEarly = false;
+
+ try {
+ Class testClass = ByteCodeLoader.load(CLASS_NAME,
+ generateTest(unstableIfLocation));
+ testMethod = testClass.getDeclaredMethod(METHOD_NAME,
+ boolean.class);
+ for (int i = 0; i < ITERATIONS; i++) {
+ testMethod.invoke(null, testCase.predicate);
+ if (i < MIN_INVOCATIONS_BEFORE_C2_COMPILATION
+ && isMethodCompiledByC2(testMethod)) {
+ compiledToEarly = true;
+ // There is no sense in further invocations: we already
+ // decided to avoid verification.
+ break;
+ }
+ }
+ // We're checking that trap should be emitted (i.e. it was compiled
+ // by C2) before the trap is fired, because otherwise the nmethod
+ // will be deoptimized and isMethodCompiledByC2 will return false.
+ shouldBeEmitted = isMethodCompiledByC2(testMethod)
+ && !compiledToEarly;
+ if (shouldBeFired) {
+ testMethod.invoke(null, !testCase.predicate);
+ }
+ } catch (ReflectiveOperationException e) {
+ throw new Error("Test case should be generated, loaded and executed"
+ + " without any issues.", e);
+ }
+
+ shouldBeFired &= shouldBeEmitted;
+
+ Properties properties = new Properties();
+ properties.setProperty(Verifier.VERIFICATION_SHOULD_BE_SKIPPED,
+ Boolean.toString(compiledToEarly));
+ properties.setProperty(Verifier.UNCOMMON_TRAP_SHOULD_EMITTED,
+ Boolean.toString(shouldBeEmitted));
+ properties.setProperty(Verifier.UNCOMMON_TRAP_SHOULD_FIRED,
+ Boolean.toString(shouldBeFired));
+ properties.setProperty(Verifier.UNCOMMON_TRAP_NAME, testCase.name);
+ properties.setProperty(Verifier.UNCOMMON_TRAP_COMMENT,
+ testCase.comment);
+ properties.setProperty(Verifier.UNCOMMON_TRAP_BCI,
+ Integer.toString(unstableIfLocation.getOffset()));
+
+ properties.list(System.out);
+
+ File f = new File(WB.getStringVMFlag("LogFile") +
+ Verifier.PROPERTIES_FILE_SUFFIX);
+ try (FileWriter wr = new FileWriter(f)) {
+ properties.store(wr, "");
+ } catch (IOException e) {
+ throw new Error("Unable to store test properties.", e);
+ }
+ }
+
+ private static boolean isMethodCompiledByC2(Method m) {
+ boolean isTiered = WB.getBooleanVMFlag("TieredCompilation");
+ boolean isMethodCompiled = WB.isMethodCompiled(m);
+ boolean isMethodCompiledAtMaxTier
+ = WB.getMethodCompilationLevel(m) == MAX_TIER;
+
+ return Platform.isServer() && isMethodCompiled
+ && (!isTiered || isMethodCompiledAtMaxTier);
+ }
+
+ /**
+ * Generates class with name {@code CLASS_NAME}, which will contain a
+ * static method {@code METHOD_NAME}:
+ *
+ * <pre>{@code
+ * public abstract class UnstableIfExecutable {
+ * private static int field = 0;
+ *
+ * public static void test(boolean alwaysTrue) {
+ * if (alwaysTrue) {
+ * field++;
+ * } else {
+ * field--;
+ * }
+ * }
+ * }
+ * }</pre>
+ *
+ * @return generated bytecode.
+ */
+ private static byte[] generateTest(Label unstableIfLocation) {
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+
+ cw.visit(CLASS_FILE_VERSION, ACC_PUBLIC | ACC_ABSTRACT, CLASS_NAME,
+ null, "java/lang/Object", null);
+
+ cw.visitField(ACC_PUBLIC | ACC_STATIC | ACC_VOLATILE, FIELD_NAME,
+ "I", null, Integer.valueOf(0));
+
+ generateTestMethod(cw, unstableIfLocation);
+
+ return cw.toByteArray();
+ }
+
+ private static void generateTestMethod(ClassVisitor cv,
+ Label unstableIfLocation) {
+ MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, METHOD_NAME,
+ "(Z)V", null, null);
+ mv.visitCode();
+
+ Label end = new Label();
+ Label falseBranch = new Label();
+
+ // push "field" field's value and 1 to stack
+ mv.visitFieldInsn(GETSTATIC, CLASS_NAME, FIELD_NAME, "I");
+ mv.visitInsn(ICONST_1);
+ // load argument's value
+ mv.visitVarInsn(ILOAD, 0); // alwaysTrue
+ // here is our unstable if
+ mv.visitLabel(unstableIfLocation);
+ mv.visitJumpInsn(IFEQ, falseBranch);
+ // increment on "true"
+ mv.visitInsn(IADD);
+ mv.visitJumpInsn(GOTO, end);
+ // decrement on "false"
+ mv.visitLabel(falseBranch);
+ mv.visitInsn(ISUB);
+ mv.visitLabel(end);
+ // bye bye
+ mv.visitInsn(RETURN);
+
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+}
+
--- a/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -34,6 +34,7 @@
/*
* @test
* @bug 8059624 8064669
+ * @ignore 8066998
* @library /testlibrary /../../test/lib
* @build ForceNMethodSweepTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
--- a/hotspot/test/gc/TestSmallHeap.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/gc/TestSmallHeap.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -26,34 +26,46 @@
* @bug 8067438
* @requires vm.gc=="null"
* @summary Verify that starting the VM with a small heap works
- * @library /testlibrary
- * @run main/othervm -Xmx4m -XX:+UseParallelGC TestSmallHeap
- * @run main/othervm -Xmx4m -XX:+UseSerialGC TestSmallHeap
- * @run main/othervm -Xmx4m -XX:+UseG1GC TestSmallHeap
- * @run main/othervm -Xmx4m -XX:+UseConcMarkSweepGC -XX:CMSMarkStackSizeMax=1032 TestSmallHeap
+ * @library /testlibrary /../../test/lib
+ * @build TestSmallHeap
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseParallelGC TestSmallHeap
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseSerialGC TestSmallHeap
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseG1GC TestSmallHeap
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx2m -XX:+UseConcMarkSweepGC TestSmallHeap
*
- * Note: It would be nice to verify the minimal supported heap size here,
- * but that turns out to be quite tricky since we align the heap size based
- * on the card table size. And the card table size is aligned based on the
- * minimal pages size provided by the os. This means that on most platforms,
- * where the minimal page size is 4k, we get a minimal heap size of 2m but
- * on Solaris/Sparc we have a page size of 8k and get a minimal heap size
- * of 8m.
+ * Note: It would be nice to verify the minimal supported heap size (2m) here,
+ * but we align the heap size based on the card table size. And the card table
+ * size is aligned based on the minimal pages size provided by the os. This
+ * means that on most platforms, where the minimal page size is 4k, we get a
+ * minimal heap size of 2m but on Solaris/Sparc we have a page size of 8k and
+ * get a minimal heap size of 4m. And on platforms where the page size is 64k
+ * we get a minimal heap size of 32m. We never use large pages for the card table.
+ *
* There is also no check in the VM for verifying that the maximum heap size
* is larger than the supported minimal heap size. This means that specifying
- * -Xmx1m on the command line is fine but will give a heap of 2m (or 4m).
- * To work around these rather strange behaviors this test uses 4m for all
- * platforms.
+ * -Xmx1m on the command line is fine but will give a heap of 2m (or 4m or 32m).
+ *
+ * To work around these rather strange behaviors this test uses -Xmx2m but then
+ * calculates what the expected heap size should be. The calculation is a
+ * simplified version of the code in the VM. We assume that the card table will
+ * use one page. Each byte in the card table corresponds to 512 bytes on the heap.
+ * So, the expected heap size is page_size * 512.
*/
+import com.oracle.java.testlibrary.*;
+import static com.oracle.java.testlibrary.Asserts.*;
+import sun.hotspot.WhiteBox;
import sun.management.ManagementFactoryHelper;
-import static com.oracle.java.testlibrary.Asserts.*;
public class TestSmallHeap {
public static void main(String[] args) {
+ WhiteBox wb = WhiteBox.getWhiteBox();
+ int pageSize = wb.getVMPageSize();
+ int heapBytesPerCard = 512;
+ long expectedMaxHeap = pageSize * heapBytesPerCard;
String maxHeap = ManagementFactoryHelper.getDiagnosticMXBean().getVMOption("MaxHeapSize").getValue();
- String expectedMaxHeap = "4194304";
- assertEQ(maxHeap, expectedMaxHeap);
+ assertEQ(Long.parseLong(maxHeap), expectedMaxHeap);
}
}
--- a/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/gc/arguments/TestMaxHeapSizeTools.java Thu Jan 29 03:54:45 2015 +0000
@@ -112,7 +112,7 @@
}
private static void checkInvalidMinInitialHeapCombinations(String gcflag) throws Exception {
- expectError(new String[] { gcflag, "-Xms8M", "-XX:InitialHeapSize=4M", "-version" });
+ expectError(new String[] { gcflag, "-Xms64M", "-XX:InitialHeapSize=32M", "-version" });
}
private static void checkValidMinInitialHeapCombinations(String gcflag) throws Exception {
--- a/hotspot/test/gc/g1/TestEagerReclaimHumongousRegions2.java Wed Jan 28 17:48:59 2015 +0100
+++ /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<Object> garbageList = new LinkedList<Object>();
-
- 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<ObjectWithSomeRefs> longList = new ArrayList<ObjectWithSomeRefs>();
-
- 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);
- }
-}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsClearMarkBits.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Object> garbageList = new LinkedList<Object>();
+
+ 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<ObjectWithSomeRefs> longList = new ArrayList<ObjectWithSomeRefs>();
+
+ 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);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/TestEagerReclaimHumongousRegionsWithRefs.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Object> garbageList = new LinkedList<Object>();
+
+ 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);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/TestG1TraceEagerReclaimHumongousObjects.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Object> garbageList = new LinkedList<Object>();
+ // 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");
+ }
+ }
+}
--- a/hotspot/test/gc/g1/TestG1TraceReclaimDeadHumongousObjectsAtYoungGC.java Wed Jan 28 17:48:59 2015 +0100
+++ /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<Object> garbageList = new LinkedList<Object>();
- // 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");
- }
- }
-}
--- a/hotspot/test/gc/g1/TestGCLogMessages.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/gc/g1/TestGCLogMessages.java Thu Jan 29 03:54:45 2015 +0000
@@ -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,17 +97,18 @@
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);
}
private static void testWithToSpaceExhaustionLogs() throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
- "-Xmx10M",
- "-Xmn5M",
+ "-Xmx32M",
+ "-Xmn16M",
"-XX:+PrintGCDetails",
GCTestWithToSpaceExhaustion.class.getName());
@@ -117,8 +120,8 @@
output.shouldHaveExitValue(0);
pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC",
- "-Xmx10M",
- "-Xmn5M",
+ "-Xmx32M",
+ "-Xmn16M",
"-XX:+PrintGCDetails",
"-XX:+UnlockExperimentalVMOptions",
"-XX:G1LogLevel=finest",
@@ -148,7 +151,7 @@
private static byte[] garbage;
private static byte[] largeObject;
public static void main(String [] args) {
- largeObject = new byte[5*1024*1024];
+ largeObject = new byte[16*1024*1024];
System.out.println("Creating garbage");
// create 128MB of garbage. This should result in at least one GC,
// some of them with to-space exhaustion.
--- a/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/gc/g1/TestHumongousAllocInitialMark.java Thu Jan 29 03:54:45 2015 +0000
@@ -31,7 +31,9 @@
import com.oracle.java.testlibrary.*;
public class TestHumongousAllocInitialMark {
- private static final int heapSize = 200; // MB
+ // Heap sizes < 224 MB are increased to 224 MB if vm_page_size == 64K to
+ // fulfill alignment constraints.
+ private static final int heapSize = 224; // MB
private static final int heapRegionSize = 1; // MB
private static final int initiatingHeapOccupancyPercent = 50; // %
--- a/hotspot/test/runtime/6888954/vmerrors.sh Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/runtime/6888954/vmerrors.sh Thu Jan 29 03:54:45 2015 +0000
@@ -1,4 +1,4 @@
-# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -71,11 +71,12 @@
# EXCEPTION_ACCESS_VIOLATION - Win-*
# SIGBUS - Solaris SPARC-64
# SIGSEGV - Linux-*, Solaris SPARC-32, Solaris X86-*
+# SIGILL - Aix
#
# Note: would like to use "pc=0x00*0f," in the pattern, but Solaris SPARC-*
# gets its signal at a PC in test_error_handler().
#
-bad_func_ptr_re='(SIGBUS|SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc='
+bad_func_ptr_re='(SIGBUS|SIGSEGV|SIGILL|EXCEPTION_ACCESS_VIOLATION).* at pc='
guarantee_re='guarantee[(](str|num).*failed: *'
fatal_re='fatal error: *'
tail_1='.*expected null'
--- a/hotspot/test/runtime/7194254/Test7194254.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 7194254
- * @summary Creates several threads with different java priorities and checks
- * whether jstack reports correct priorities for them.
- *
- * @ignore 8060219
- * @run main Test7194254
- */
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CyclicBarrier;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class Test7194254 {
-
- public static void main(String[] args) throws Exception {
- final int NUMBER_OF_JAVA_PRIORITIES =
- Thread.MAX_PRIORITY - Thread.MIN_PRIORITY + 1;
- final CyclicBarrier barrier =
- new CyclicBarrier(NUMBER_OF_JAVA_PRIORITIES + 1);
-
- for (int p = Thread.MIN_PRIORITY; p <= Thread.MAX_PRIORITY; ++p) {
- final int priority = p;
- new Thread("Priority=" + p) {
- {
- setPriority(priority);
- }
- public void run() {
- try {
- barrier.await(); // 1st
- barrier.await(); // 2nd
- } catch (Exception exc) {
- // ignore
- }
- }
- }.start();
- }
- barrier.await(); // 1st
-
- int matches = 0;
- List<String> failed = new ArrayList<>();
- try {
- String pid = getPid();
- String jstack = System.getProperty("java.home") + "/../bin/jstack";
- Process process = new ProcessBuilder(jstack, pid)
- .redirectErrorStream(true).start();
- Pattern pattern = Pattern.compile(
- "\\\"Priority=(\\d+)\\\".* prio=(\\d+).*");
- try (BufferedReader reader = new BufferedReader(
- new InputStreamReader(process.getInputStream()))) {
- String line;
- while((line = reader.readLine()) != null) {
- Matcher matcher = pattern.matcher(line);
- if (matcher.matches()) {
- matches += 1;
- String expected = matcher.group(1);
- String actual = matcher.group(2);
- if (!expected.equals(actual)) {
- failed.add(line);
- }
- }
- }
- }
- barrier.await(); // 2nd
- } finally {
- barrier.reset();
- }
-
- if (matches != NUMBER_OF_JAVA_PRIORITIES) {
- throw new AssertionError("matches: expected " +
- NUMBER_OF_JAVA_PRIORITIES + ", but was " + matches);
- }
- if (!failed.isEmpty()) {
- throw new AssertionError(failed.size() + ":" + failed);
- }
- System.out.println("Test passes.");
- }
-
- static String getPid() {
- RuntimeMXBean runtimebean = ManagementFactory.getRuntimeMXBean();
- String vmname = runtimebean.getName();
- int i = vmname.indexOf('@');
- if (i != -1) {
- vmname = vmname.substring(0, i);
- }
- return vmname;
- }
-
-}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/BadObjectClass/BootstrapRedefine.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/BadObjectClass/Object.java Thu Jan 29 03:54:45 2015 +0000
@@ -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; }
+}
--- a/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java Thu Jan 29 03:54:45 2015 +0000
@@ -43,7 +43,7 @@
pb = ProcessTools.createJavaProcessBuilder("-XX:CompileCommandFile=hs_comp.txt", "-version");
output = new OutputAnalyzer(pb.start());
- output.shouldContain("CompilerOracle: unrecognized line");
+ output.shouldContain("CompileCommand: unrecognized command");
output.shouldContain("aaa aaa");
// Skip on debug builds since we'll always read the file there
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/TestNullTerminatedFlags.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+ }
+ }
+}
+
--- a/hotspot/test/runtime/CompressedOops/UseCompressedOops.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/runtime/CompressedOops/UseCompressedOops.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<String> 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<String> flags1, String... flags2) throws Exception {
+ ArrayList<String> 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<String> flags1, String... flags2) throws Exception {
ArrayList<String> 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");
--- a/hotspot/test/runtime/NMT/ChangeTrackingLevel.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/runtime/NMT/ChangeTrackingLevel.java Thu Jan 29 03:54:45 2015 +0000
@@ -27,6 +27,7 @@
* @summary Test that you can decrease NMT tracking level but not increase it.
* @key nmt
* @library /testlibrary /../../test/lib
+ * @ignore 8067167
* @build ChangeTrackingLevel
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
--- a/hotspot/test/runtime/NMT/PrintNMTStatistics.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/runtime/NMT/PrintNMTStatistics.java Thu Jan 29 03:54:45 2015 +0000
@@ -27,6 +27,7 @@
* @bug 8005936 8058606
* @summary Verify PrintNMTStatistics on normal JVM exit for detail and summary tracking level
* @library /testlibrary
+ * @ignore 8067167
*/
import com.oracle.java.testlibrary.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/DumpSymbolAndStringTable.java Thu Jan 29 03:54:45 2015 +0000
@@ -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");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/MaxMetaspaceSize.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,41 @@
+/*
+ * 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 8067187
+ * @summary Testing CDS dumping with the -XX:MaxMetaspaceSize=<size> option
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class MaxMetaspaceSize {
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:MaxMetaspaceSize=20m", "-Xshare:dump");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("is not large enough.\nEither don't specify the -XX:MaxMetaspaceSize=<size>\nor increase the size to at least");
+ output.shouldHaveExitValue(2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java Thu Jan 29 03:54:45 2015 +0000
@@ -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");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Thread/ThreadPriorities.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,96 @@
+/*
+ * 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
+ * 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 7194254
+ * @summary Creates several threads with different java priorities and checks
+ * whether jstack reports correct priorities for them.
+ *
+ * @library /testlibrary
+ * @run main ThreadPriorities
+ */
+
+import java.util.ArrayList;
+import java.util.concurrent.CyclicBarrier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.oracle.java.testlibrary.*;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+public class ThreadPriorities {
+
+ public static void main(String[] args) throws Throwable {
+ final int NUMBER_OF_JAVA_PRIORITIES =
+ Thread.MAX_PRIORITY - Thread.MIN_PRIORITY + 1;
+ final CyclicBarrier barrier =
+ new CyclicBarrier(NUMBER_OF_JAVA_PRIORITIES + 1);
+
+ for (int p = Thread.MIN_PRIORITY; p <= Thread.MAX_PRIORITY; ++p) {
+ final int priority = p;
+ new Thread("Priority=" + p) {
+ {
+ setPriority(priority);
+ }
+ public void run() {
+ try {
+ barrier.await(); // 1st
+ barrier.await(); // 2nd
+ } catch (Exception exc) {
+ // ignore
+ }
+ }
+ }.start();
+ }
+ barrier.await(); // 1st
+
+ int matches = 0;
+ ArrayList<String> failed = new ArrayList<>();
+ ProcessBuilder pb = new ProcessBuilder(
+ JDKToolFinder.getJDKTool("jstack"),
+ String.valueOf(ProcessTools.getProcessId()));
+
+ String[] output = new OutputAnalyzer(pb.start()).getOutput().split("\\n+");
+
+ Pattern pattern = Pattern.compile(
+ "\\\"Priority=(\\d+)\\\".* prio=(\\d+).*");
+ for (String line : output) {
+ Matcher matcher = pattern.matcher(line);
+ if (matcher.matches()) {
+ matches += 1;
+ String expected = matcher.group(1);
+ String actual = matcher.group(2);
+ if (!expected.equals(actual)) {
+ failed.add(line);
+ }
+ }
+ }
+ barrier.await(); // 2nd
+ barrier.reset();
+
+ assertEquals(matches, NUMBER_OF_JAVA_PRIORITIES);
+ assertTrue(failed.isEmpty(), failed.size() + ":" + failed);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Unsafe/Reallocate.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,67 @@
+/*
+ * 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 8058897
+ * @library /testlibrary
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m Reallocate
+ */
+
+import com.oracle.java.testlibrary.*;
+import sun.misc.Unsafe;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+public class Reallocate {
+ public static void main(String args[]) throws Exception {
+ Unsafe unsafe = Utils.getUnsafe();
+
+ long address = unsafe.allocateMemory(1);
+ assertNotEquals(address, 0L);
+
+ // Make sure we reallocate correctly
+ unsafe.putByte(address, Byte.MAX_VALUE);
+ address = unsafe.reallocateMemory(address, 2);
+ assertNotEquals(address, 0L);
+ assertEquals(unsafe.getByte(address), Byte.MAX_VALUE);
+
+ // Reallocating with a 0 size should return a null pointer
+ address = unsafe.reallocateMemory(address, 0);
+ assertEquals(address, 0L);
+
+ // Reallocating with a null pointer should result in a normal allocation
+ address = unsafe.reallocateMemory(0L, 1);
+ assertNotEquals(address, 0L);
+ unsafe.putByte(address, Byte.MAX_VALUE);
+ assertEquals(unsafe.getByte(address), Byte.MAX_VALUE);
+
+ // Make sure we can throw an OOME when we fail to reallocate due to OOM
+ try {
+ unsafe.reallocateMemory(address, 100 * 1024 * 1024 * 8);
+ } catch (OutOfMemoryError e) {
+ // Expected
+ return;
+ }
+ throw new RuntimeException("Did not get expected OOM");
+ }
+}
--- a/hotspot/test/runtime/whitebox/WBStackSize.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/runtime/whitebox/WBStackSize.java Thu Jan 29 03:54:45 2015 +0000
@@ -47,7 +47,7 @@
static final long K = 1024;
static final long MIN_STACK_SIZE = 8 * K;
- static final long MAX_STACK_SIZE_ALLOCATED_IN_MAIN = 200 * K; // current value is about 130k on 64-bit platforms
+ static final long MAX_STACK_SIZE_ALLOCATED_IN_MAIN = 150 * K; // current value is about 130k on 64-bit platforms
static final WhiteBox wb = WhiteBox.getWhiteBox();
@@ -82,8 +82,10 @@
public static void main(String[] args) {
long configStackSize = wb.getIntxVMFlag("ThreadStackSize") * K;
+ System.out.println("ThreadStackSize VM option: " + configStackSize);
- System.out.println("ThreadStackSize VM option: " + configStackSize);
+ long stackProtectionSize = wb.getIntxVMFlag("StackShadowPages") * wb.getVMPageSize();
+ System.out.println("Size of protected shadow pages: " + stackProtectionSize);
long actualStackSize = wb.getThreadStackSize();
System.out.println("Full stack size: " + actualStackSize);
@@ -96,14 +98,16 @@
long remainingStackSize = wb.getThreadRemainingStackSize();
System.out.println("Remaining stack size in main(): " + remainingStackSize);
- // Up to 200k can be already allocated by VM
+ // Up to 150k can be already allocated by VM and some space is used for stack protection.
+ long spaceAlreadyOccupied = MAX_STACK_SIZE_ALLOCATED_IN_MAIN + stackProtectionSize;
+
if (remainingStackSize > configStackSize
- || (configStackSize > MAX_STACK_SIZE_ALLOCATED_IN_MAIN
- && remainingStackSize < configStackSize - MAX_STACK_SIZE_ALLOCATED_IN_MAIN)) {
+ || (configStackSize > spaceAlreadyOccupied
+ && remainingStackSize < configStackSize - spaceAlreadyOccupied)) {
throw new RuntimeException("getThreadRemainingStackSize value [" + remainingStackSize
+ "] should be at least ThreadStackSize value [" + configStackSize + "] minus ["
- + MAX_STACK_SIZE_ALLOCATED_IN_MAIN + "]");
+ + spaceAlreadyOccupied + "]");
}
testStackOverflow();
--- a/hotspot/test/serviceability/dcmd/DynLibDcmdTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/serviceability/dcmd/DynLibDcmdTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -3,7 +3,7 @@
import com.oracle.java.testlibrary.Platform;
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,14 +39,16 @@
String result = DcmdUtil.executeDcmd("VM.dynlibs");
String osDependentBaseString = null;
- if (Platform.isSolaris()) {
+ if (Platform.isAix()) {
+ osDependentBaseString = "lib%s.so";
+ } else if (Platform.isLinux()) {
+ osDependentBaseString = "lib%s.so";
+ } else if (Platform.isOSX()) {
+ osDependentBaseString = "lib%s.dylib";
+ } else if (Platform.isSolaris()) {
osDependentBaseString = "lib%s.so";
} else if (Platform.isWindows()) {
osDependentBaseString = "%s.dll";
- } else if (Platform.isOSX()) {
- osDependentBaseString = "lib%s.dylib";
- } else if (Platform.isLinux()) {
- osDependentBaseString = "lib%s.so";
}
if (osDependentBaseString == null) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/stress/gc/TestGCOld.java Thu Jan 29 03:54:45 2015 +0000
@@ -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 <size> <work> <ratio> <mutation> <steps>";
+ private static final String msg2
+ = " where <size> is the live storage in megabytes";
+ private static final String msg3
+ = " <work> is the mutator work per step (arbitrary units)";
+ private static final String msg4
+ = " <ratio> is the ratio of short-lived to long-lived allocation";
+ private static final String msg5
+ = " <mutation> is the mutations per step";
+ private static final String msg6
+ = " <steps> 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));
+
+ }
+}
--- a/hotspot/test/test_env.sh Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/test_env.sh Thu Jan 29 03:54:45 2015 +0000
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -56,7 +56,7 @@
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
- SunOS | Linux | Darwin )
+ AIX | Darwin | Linux | SunOS )
NULL=/dev/null
PS=":"
FS="/"
@@ -133,26 +133,31 @@
fi
VM_OS="unknown"
-grep "solaris" vm_version.out > ${NULL}
+grep "aix" vm_version.out > ${NULL}
if [ $? = 0 ]
then
- VM_OS="solaris"
+ VM_OS="aix"
+fi
+grep "bsd" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+ VM_OS="bsd"
fi
grep "linux" vm_version.out > ${NULL}
if [ $? = 0 ]
then
VM_OS="linux"
fi
+grep "solaris" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+ VM_OS="solaris"
+fi
grep "windows" vm_version.out > ${NULL}
if [ $? = 0 ]
then
VM_OS="windows"
fi
-grep "bsd" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
- VM_OS="bsd"
-fi
VM_CPU="unknown"
grep "sparc" vm_version.out > ${NULL}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ByteCodeLoader.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/InfiniteLoop.java Thu Jan 29 03:54:45 2015 +0000
@@ -54,7 +54,9 @@
try {
while (true) {
target.run();
- Thread.sleep(mills);
+ if (mills > 0) {
+ Thread.sleep(mills);
+ }
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -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");
}
@@ -63,6 +68,18 @@
return dataModel.equals("64");
}
+ public static boolean isAix() {
+ return isOs("aix");
+ }
+
+ public static boolean isLinux() {
+ return isOs("linux");
+ }
+
+ public static boolean isOSX() {
+ return isOs("mac");
+ }
+
public static boolean isSolaris() {
return isOs("sunos");
}
@@ -71,14 +88,6 @@
return isOs("win");
}
- public static boolean isOSX() {
- return isOs("mac");
- }
-
- public static boolean isLinux() {
- return isOs("linux");
- }
-
private static boolean isOs(String osname) {
return osName.toLowerCase().startsWith(osname.toLowerCase());
}
@@ -135,7 +144,9 @@
*/
public static boolean shouldSAAttach() throws Exception {
- if (isLinux()) {
+ if (isAix()) {
+ return false; // SA not implemented.
+ } else if (isLinux()) {
return canPtraceAttachLinux();
} else if (isOSX()) {
return canAttachOSX();
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<String> fileAsList(File file) throws IOException {
- assertTrue(file.exists() && file.isFile(),
- file.getAbsolutePath() + " does not exist or not a file");
- List<String> 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"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceResultsAnalyzer.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<String> 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<String> 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;
+ }
+}
--- a/hotspot/test/testlibrary/ctw/test/Bar.java Wed Jan 28 17:48:59 2015 +0100
+++ /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() { }
-}
--- a/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java Wed Jan 28 17:48:59 2015 +0100
+++ /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);
- }
-}
--- a/hotspot/test/testlibrary/ctw/test/ClassesListTest.java Wed Jan 28 17:48:59 2015 +0100
+++ /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);
- }
-}
--- a/hotspot/test/testlibrary/ctw/test/CtwTest.java Wed Jan 28 17:48:59 2015 +0100
+++ /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<String> args = new ArrayList<>();
- args.add(javapath);
- Collections.addAll(args, command);
-
- return new ProcessBuilder(args.toArray(new String[args.size()]));
- }
-}
--- a/hotspot/test/testlibrary/ctw/test/Foo.java Wed Jan 28 17:48:59 2015 +0100
+++ /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() { }
-}
--- a/hotspot/test/testlibrary/ctw/test/JarDirTest.java Wed Jan 28 17:48:59 2015 +0100
+++ /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);
- }
-
-}
--- a/hotspot/test/testlibrary/ctw/test/JarsTest.java Wed Jan 28 17:48:59 2015 +0100
+++ /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);
- }
-
-}
--- a/hotspot/test/testlibrary/ctw/test/classes.lst Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-java.lang.String
-java.lang.Object
-Foo
-Bar
--- a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Wed Jan 28 17:48:59 2015 +0100
+++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Thu Jan 29 03:54:45 2015 +0000
@@ -45,10 +45,10 @@
private static enum MethodGroup {
ARCH("isARM", "isPPC", "isSparc", "isX86", "isX64"),
BITNESS("is32bit", "is64bit"),
- OS("isLinux", "isSolaris", "isWindows", "isOSX"),
+ OS("isAix", "isLinux", "isOSX", "isSolaris", "isWindows"),
VM_TYPE("isClient", "isServer", "isGraal", "isMinimal"),
IGNORED("isEmbedded", "isDebugBuild", "shouldSAAttach",
- "canPtraceAttachLinux", "canAttachOSX");
+ "canPtraceAttachLinux", "canAttachOSX", "isTieredSupported");
public final List<String> methodNames;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary_tests/TestPlatformIsTieredSupported.java Thu Jan 29 03:54:45 2015 +0000
@@ -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.");
+ }
+}
--- a/jaxp/.hgtags Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/.hgtags Thu Jan 29 03:54:45 2015 +0000
@@ -288,3 +288,5 @@
40b242363040229a05224fbc5dc203a3f46a8f8f jdk9-b43
0cb0844b58924d6086d2850c22087d06679d5eef jdk9-b44
0dab3e848229127c7aca4c58b98e2d90ba70372f jdk9-b45
+74eaf7ad986576c792df4dbff05eed63e5727695 jdk9-b46
+e391de88e69b59d7c618387e3cf91032f6991ce9 jdk9-b47
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DBFNamespaceTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DBFNamespaceTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
+ }
}
-
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory01.java Wed Jan 28 17:48:59 2015 +0100
+++ /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(), "<xml>This is not parsed</xml> 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);
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactory02.java Wed Jan 28 17:48:59 2015 +0100
+++ /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);
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderFactoryTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
+ }
+}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderImpl01.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/DocumentBuilderImpl01.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/FactoryConfErrorTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/FactoryConfErrorTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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)
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserFactTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserFactTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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());
}
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest02.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest02.java Thu Jan 29 03:54:45 2015 +0000
@@ -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) {
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest03.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/SAXParserTest03.java Thu Jan 29 03:54:45 2015 +0000
@@ -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());
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/parsers/ptests/TestUtils.java Wed Jan 28 17:48:59 2015 +0100
+++ /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;
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/DOMResultTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<nnm.getLength(); i++) {
+ str = "AttributeName:" + ((Attr) nnm.item(i)).getName() +
+ ", AttributeValue:" +((Attr) nnm.item(i)).getValue();
+ bWriter.write( str, 0,str.length());
+ bWriter.newLine();
+ }
+
+ NodeList kids = node.getChildNodes();
+ if (kids != null)
+ for (int i=0; i<kids.getLength(); i++)
+ writeNodes(kids.item(i), bWriter);
+ }
+}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/DOMResultTest01.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +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.BufferedWriter;
-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.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMResult;
-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.sax.SAXSource;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-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.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.SAXException;
-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 DOMResultTest01 {
- /**
- * Unit test for simple DOM parsing.
- */
- @Test
- public void testcase01() {
- String resultFile = CLASS_DIR + "domresult01.out";
- String goldFile = GOLDEN_DIR + "domresult01GF.out";
- String xsltFile = XML_DIR + "cities.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try {
- 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));
- } catch (SAXException | TransformerConfigurationException
- | IllegalArgumentException | IOException ex) {
- failUnexpected(ex);
- } finally {
- try {
- Path resultPath = Paths.get(resultFile);
- if(Files.exists(resultPath))
- Files.delete(resultPath);
- } catch (IOException ex) {
- failCleanup(ex, 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<nnm.getLength(); i++) {
- str = "AttributeName:" + ((Attr) nnm.item(i)).getName() +
- ", AttributeValue:" +((Attr) nnm.item(i)).getValue();
- bWriter.write( str, 0,str.length());
- bWriter.newLine();
- }
-
- NodeList kids = node.getChildNodes();
- if (kids != null)
- for (int i=0; i<kids.getLength(); i++)
- writeNodes(kids.item(i), bWriter);
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/ErrorListenerTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/ErrorListenerTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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,14 @@
package javax.xml.transform.ptests;
import java.io.File;
+import java.io.FilePermission;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR;
import javax.xml.transform.stream.StreamSource;
+import jaxp.library.JAXPBaseTest;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
import org.testng.annotations.Test;
@@ -37,7 +39,7 @@
/**
* Class containing the test cases for ErrorListener interface
*/
-public class ErrorListenerTest implements ErrorListener {
+public class ErrorListenerTest extends JAXPBaseTest implements ErrorListener {
/**
* Define ErrorListener's status.
*/
@@ -58,9 +60,10 @@
try {
TransformerFactory tfactory = TransformerFactory.newInstance();
tfactory.setErrorListener (listener);
+ setPermissions(new FilePermission(XML_DIR + "invalid.xsl", "read"));
tfactory.newTransformer(new StreamSource(
new File(XML_DIR + "invalid.xsl")));
- fail("We expect an Exception here");
+ fail("Expect TransformerConfigurationException here");
} catch (TransformerConfigurationException ex) {
assertEquals(listener.status, ListenerStatus.FATAL);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXSourceTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,97 @@
+/*
+ * 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.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.dom.DOMSource;
+import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+import jaxp.library.JAXPFileReadOnlyBaseTest;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import org.testng.annotations.Test;
+import org.xml.sax.InputSource;
+
+
+/**
+ * Unit test for SAXSource sourceToInputSource API.
+ */
+public class SAXSourceTest extends JAXPFileReadOnlyBaseTest {
+ /**
+ * Test style-sheet file name
+ */
+ private final String TEST_FILE = XML_DIR + "cities.xsl";
+
+ /**
+ * Test obtaining a SAX InputSource object from a Source object.
+ *
+ * @throws IOException reading file error.
+ */
+ @Test(groups = {"readLocalFiles"})
+ public void source2inputsource01() throws IOException {
+ try (FileInputStream fis = new FileInputStream(TEST_FILE)) {
+ StreamSource streamSource = new StreamSource(fis);
+ assertNotNull(SAXSource.sourceToInputSource(streamSource));
+ }
+ }
+
+ /**
+ * This test case tries to get InputSource from DOMSource using
+ * sourceToInputSource method. It is not possible and hence null is
+ * expected. This is a negative test case,
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test(groups = {"readLocalFiles"})
+ public void source2inputsource02() throws Exception {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ dbf.newDocumentBuilder().parse(new File(TEST_FILE));
+ assertNull(SAXSource.sourceToInputSource(new DOMSource(null)));
+ }
+
+ /**
+ * This test case tries to get InputSource from SAXSource using
+ * sourceToInputSource method. This will also check if the systemId
+ * remained the same. This is a positive test case.
+ *
+ * @throws IOException reading file error.
+ */
+ @Test(groups = {"readLocalFiles"})
+ public void source2inputsource03() throws IOException {
+ String SYSTEM_ID = "file:///" + XML_DIR;
+ try (FileInputStream fis = new FileInputStream(TEST_FILE)) {
+ SAXSource saxSource =
+ new SAXSource(new InputSource(fis));
+ saxSource.setSystemId(SYSTEM_ID);
+ assertEquals(SAXSource.sourceToInputSource(saxSource).getSystemId(),
+ SYSTEM_ID);
+ }
+ }
+}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXSourceTest01.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +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.FileNotFoundException;
-import java.io.IOException;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.dom.DOMSource;
-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 static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import org.testng.annotations.Test;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-
-/**
- * Unit test for SAXSource sourceToInputSource API.
- */
-public class SAXSourceTest01 {
- /**
- * Test file name
- */
- private final String TEST_FILE = XML_DIR + "cities.xsl";
-
- /**
- * Test obtaining a SAX InputSource object from a Source object.
- */
- @Test
- public void source2inputsource01() {
- try {
- StreamSource streamSource = new StreamSource (
- new FileInputStream (TEST_FILE));
- assertNotNull(SAXSource.sourceToInputSource(streamSource));
- } catch (FileNotFoundException ex) {
- failUnexpected(ex);
- }
- }
-
- /**
- * This test case tries to get InputSource from DOMSource using
- * sourceToInputSource method. It is not possible and hence null is
- * expected. This is a negative test case
- */
- @Test
- public void source2inputsource02() {
- try {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- dbf.newDocumentBuilder().parse(new File(TEST_FILE));
- assertNull(SAXSource.sourceToInputSource(new DOMSource(null)));
- } catch (ParserConfigurationException | SAXException | IOException ex) {
- failUnexpected(ex);
- }
-
- }
-
- /**
- * This test case tries to get InputSource from SAXSource using
- * sourceToInputSource method. This will also check if the systemId
- * remained the same. This is a positive test case.
- */
- @Test
- public void source2inputsource03() {
- String SYSTEM_ID = "file:///" + XML_DIR;
- try {
- SAXSource saxSource =
- new SAXSource(new InputSource(new FileInputStream(TEST_FILE)));
- saxSource.setSystemId(SYSTEM_ID);
- assertEquals(SAXSource.sourceToInputSource(saxSource).getSystemId(),
- SYSTEM_ID);
- } catch (FileNotFoundException ex) {
- failUnexpected(ex);
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,423 @@
+/*
+ * 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.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Result;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+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.TemplatesHandler;
+import javax.xml.transform.sax.TransformerHandler;
+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 org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLFilter;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * Test newTransformerhandler() method which takes StreamSource as argument can
+ * be set to XMLReader.
+ */
+public class SAXTFactoryTest extends JAXPFileBaseTest {
+ /**
+ * Test style-sheet file.
+ */
+ private static final String XSLT_FILE = XML_DIR + "cities.xsl";
+
+ /**
+ * Test style-sheet file.
+ */
+ private static final String XSLT_INCL_FILE = XML_DIR + "citiesinclude.xsl";
+
+ /**
+ * Test XML file.
+ */
+ private static final String XML_FILE = XML_DIR + "cities.xml";
+
+ /**
+ * SAXTFactory.newTransformerhandler() method which takes SAXSource as
+ * argument can be set to XMLReader. SAXSource has input XML file as its
+ * input source. XMLReader has a transformer handler which write out the
+ * result to output file. Test verifies output file is same as golden file.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test
+ public void testcase01() throws Exception {
+ String outputFile = USER_DIR + "saxtf001.out";
+ String goldFile = GOLDEN_DIR + "saxtf001GF.out";
+
+ try (FileOutputStream fos = new FileOutputStream(outputFile)) {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory) TransformerFactory.newInstance();
+ TransformerHandler handler = saxTFactory.newTransformerHandler(new StreamSource(XSLT_FILE));
+ Result result = new StreamResult(fos);
+ handler.setResult(result);
+ reader.setContentHandler(handler);
+ reader.parse(XML_FILE);
+ }
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+
+ /**
+ * SAXTFactory.newTransformerhandler() method which takes SAXSource as
+ * argument can be set to XMLReader. SAXSource has input XML file as its
+ * input source. XMLReader has a content handler which write out the result
+ * to output file. Test verifies output file is same as golden file.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test
+ public void testcase02() throws Exception {
+ String outputFile = USER_DIR + "saxtf002.out";
+ String goldFile = GOLDEN_DIR + "saxtf002GF.out";
+
+ try (FileOutputStream fos = new FileOutputStream(outputFile);
+ FileInputStream fis = new FileInputStream(XSLT_FILE)) {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory) TransformerFactory.newInstance();
+ SAXSource ss = new SAXSource();
+ ss.setInputSource(new InputSource(fis));
+
+ TransformerHandler handler = saxTFactory.newTransformerHandler(ss);
+ Result result = new StreamResult(fos);
+ handler.setResult(result);
+ reader.setContentHandler(handler);
+ reader.parse(XML_FILE);
+ }
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+
+ /**
+ * Unit test for newTransformerhandler(Source). DcoumentBuilderFactory is
+ * namespace awareness, DocumentBuilder parse xslt file as DOMSource.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test
+ public void testcase03() throws Exception {
+ String outputFile = USER_DIR + "saxtf003.out";
+ String goldFile = GOLDEN_DIR + "saxtf003GF.out";
+
+ try (FileOutputStream fos = new FileOutputStream(outputFile)) {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+ Document document = docBuilder.parse(new File(XSLT_FILE));
+ Node node = (Node)document;
+ DOMSource domSource= new DOMSource(node);
+
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory)TransformerFactory.newInstance();
+ TransformerHandler handler =
+ saxTFactory.newTransformerHandler(domSource);
+ Result result = new StreamResult(fos);
+ handler.setResult(result);
+ reader.setContentHandler(handler);
+ reader.parse(XML_FILE);
+ }
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+
+ /**
+ * Negative test for newTransformerHandler when relative URI is in XML file.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test(expectedExceptions = TransformerConfigurationException.class)
+ public void transformerHandlerTest04() throws Exception {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+ Document document = docBuilder.parse(new File(XSLT_INCL_FILE));
+ DOMSource domSource= new DOMSource(document);
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory)TransformerFactory.newInstance();
+ saxTFactory.newTransformerHandler(domSource);
+ }
+
+ /**
+ * Unit test for XMLReader parsing when relative URI is used in xsl file and
+ * SystemId was set.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test
+ public void testcase05() throws Exception {
+ String outputFile = USER_DIR + "saxtf005.out";
+ String goldFile = GOLDEN_DIR + "saxtf005GF.out";
+
+ try (FileOutputStream fos = new FileOutputStream(outputFile)) {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory)TransformerFactory.newInstance();
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+ Document document = docBuilder.parse(new File(XSLT_INCL_FILE));
+ Node node = (Node)document;
+ DOMSource domSource= new DOMSource(node);
+
+ domSource.setSystemId("file:///" + XML_DIR);
+
+ TransformerHandler handler =
+ saxTFactory.newTransformerHandler(domSource);
+ Result result = new StreamResult(fos);
+
+ handler.setResult(result);
+ reader.setContentHandler(handler);
+ reader.parse(XML_FILE);
+ }
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+
+ /**
+ * Unit test newTransformerHandler with a DOMSource.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test
+ public void testcase06() throws Exception {
+ String outputFile = USER_DIR + "saxtf006.out";
+ String goldFile = GOLDEN_DIR + "saxtf006GF.out";
+
+ try (FileOutputStream fos = new FileOutputStream(outputFile)) {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory)TransformerFactory.newInstance();
+
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+ Node node = (Node)docBuilder.parse(new File(XSLT_INCL_FILE));
+
+ DOMSource domSource = new DOMSource(node, "file:///" + XML_DIR);
+ TransformerHandler handler =
+ saxTFactory.newTransformerHandler(domSource);
+
+ Result result = new StreamResult(fos);
+ handler.setResult(result);
+ reader.setContentHandler(handler);
+ reader.parse(XML_FILE);
+ }
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+
+ /**
+ * Test newTransformerHandler with a Template Handler.
+ *
+ * @throws Exception If any errors occur.
+ */
+ public void testcase08() throws Exception {
+ String outputFile = USER_DIR + "saxtf008.out";
+ String goldFile = GOLDEN_DIR + "saxtf008GF.out";
+
+ try (FileOutputStream fos = new FileOutputStream(outputFile)) {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory)TransformerFactory.newInstance();
+
+ TemplatesHandler thandler = saxTFactory.newTemplatesHandler();
+ reader.setContentHandler(thandler);
+ reader.parse(XSLT_FILE);
+ TransformerHandler tfhandler
+ = saxTFactory.newTransformerHandler(thandler.getTemplates());
+
+ Result result = new StreamResult(fos);
+ tfhandler.setResult(result);
+
+ reader.setContentHandler(tfhandler);
+ reader.parse(XML_FILE);
+ }
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+
+ /**
+ * Test newTransformerHandler with a Template Handler along with a relative
+ * URI in the style-sheet file.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test
+ public void testcase09() throws Exception {
+ String outputFile = USER_DIR + "saxtf009.out";
+ String goldFile = GOLDEN_DIR + "saxtf009GF.out";
+
+ try (FileOutputStream fos = new FileOutputStream(outputFile)) {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory)TransformerFactory.newInstance();
+
+ TemplatesHandler thandler = saxTFactory.newTemplatesHandler();
+ thandler.setSystemId("file:///" + XML_DIR);
+ reader.setContentHandler(thandler);
+ reader.parse(XSLT_INCL_FILE);
+ TransformerHandler tfhandler=
+ saxTFactory.newTransformerHandler(thandler.getTemplates());
+ Result result = new StreamResult(fos);
+ tfhandler.setResult(result);
+ reader.setContentHandler(tfhandler);
+ reader.parse(XML_FILE);
+ }
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+
+ /**
+ * Unit test for contentHandler setter/getter along reader as handler's
+ * parent.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test
+ public void testcase10() throws Exception {
+ String outputFile = USER_DIR + "saxtf010.out";
+ String goldFile = GOLDEN_DIR + "saxtf010GF.out";
+ // The transformer will use a SAX parser as it's reader.
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory)TransformerFactory.newInstance();
+ XMLFilter filter =
+ saxTFactory.newXMLFilter(new StreamSource(XSLT_FILE));
+ filter.setParent(reader);
+ filter.setContentHandler(new MyContentHandler(outputFile));
+
+ // Now, when you call transformer.parse, it will set itself as
+ // the content handler for the parser object (it's "parent"), and
+ // will then call the parse method on the parser.
+ filter.parse(new InputSource(XML_FILE));
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+
+ /**
+ * Unit test for contentHandler setter/getter with parent.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test
+ public void testcase11() throws Exception {
+ String outputFile = USER_DIR + "saxtf011.out";
+ String goldFile = GOLDEN_DIR + "saxtf011GF.out";
+ // The transformer will use a SAX parser as it's reader.
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ DocumentBuilder docBuilder = dbf.newDocumentBuilder();
+ Document document = docBuilder.parse(new File(XSLT_FILE));
+ Node node = (Node)document;
+ DOMSource domSource= new DOMSource(node);
+
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory)TransformerFactory.newInstance();
+ XMLFilter filter = saxTFactory.newXMLFilter(domSource);
+
+ filter.setParent(reader);
+ filter.setContentHandler(new MyContentHandler(outputFile));
+
+ // Now, when you call transformer.parse, it will set itself as
+ // the content handler for the parser object (it's "parent"), and
+ // will then call the parse method on the parser.
+ filter.parse(new InputSource(XML_FILE));
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+
+ /**
+ * Unit test for contentHandler setter/getter.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test
+ public void testcase12() throws Exception {
+ String outputFile = USER_DIR + "saxtf012.out";
+ String goldFile = GOLDEN_DIR + "saxtf012GF.out";
+ // The transformer will use a SAX parser as it's reader.
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+
+ InputSource is = new InputSource(new FileInputStream(XSLT_FILE));
+ SAXSource saxSource = new SAXSource();
+ saxSource.setInputSource(is);
+
+ SAXTransformerFactory saxTFactory = (SAXTransformerFactory)TransformerFactory.newInstance();
+ XMLFilter filter = saxTFactory.newXMLFilter(saxSource);
+
+ filter.setParent(reader);
+ filter.setContentHandler(new MyContentHandler(outputFile));
+
+ // Now, when you call transformer.parse, it will set itself as
+ // the content handler for the parser object (it's "parent"), and
+ // will then call the parse method on the parser.
+ filter.parse(new InputSource(XML_FILE));
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+
+ /**
+ * Unit test for TemplatesHandler setter/getter.
+ *
+ * @throws Exception If any errors occur.
+ */
+ @Test
+ public void testcase13() throws Exception {
+ String outputFile = USER_DIR + "saxtf013.out";
+ String goldFile = GOLDEN_DIR + "saxtf013GF.out";
+ try(FileInputStream fis = new FileInputStream(XML_FILE)) {
+ // The transformer will use a SAX parser as it's reader.
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+
+ SAXTransformerFactory saxTFactory
+ = (SAXTransformerFactory) TransformerFactory.newInstance();
+ TemplatesHandler thandler = saxTFactory.newTemplatesHandler();
+ // I have put this as it was complaining about systemid
+ thandler.setSystemId("file:///" + USER_DIR);
+
+ reader.setContentHandler(thandler);
+ reader.parse(XSLT_FILE);
+ XMLFilter filter
+ = saxTFactory.newXMLFilter(thandler.getTemplates());
+ filter.setParent(reader);
+
+ filter.setContentHandler(new MyContentHandler(outputFile));
+ filter.parse(new InputSource(fis));
+ }
+ assertTrue(compareWithGold(goldFile, outputFile));
+ }
+}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest001.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +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.FileOutputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import javax.xml.transform.Result;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-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.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-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 org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test newTransformerhandler() method which takes StreamSource as argument can
- * be set to XMLReader.
- */
-public class SAXTFactoryTest001 {
- /**
- * SAXTFactory.newTransformerhandler() method which takes SAXSource as
- * argument can be set to XMLReader. SAXSource has input XML file as its
- * input source. XMLReader has a transformer handler which write out the
- * result to output file. Test verifies output file is same as golden file.
- */
- @Test
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf001.out";
- String goldFile = GOLDEN_DIR + "saxtf001GF.out";
- String xsltFile = XML_DIR + "cities.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try (FileOutputStream fos = new FileOutputStream(outputFile)) {
- XMLReader reader = XMLReaderFactory.createXMLReader();
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory) TransformerFactory.newInstance();
- TransformerHandler handler = saxTFactory.newTransformerHandler(
- new StreamSource(xsltFile));
- Result result = new StreamResult(fos);
- handler.setResult(result);
- reader.setContentHandler(handler);
- reader.parse(xmlFile);
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (SAXException | TransformerConfigurationException | IOException ex) {
- failUnexpected(ex);
- } finally {
- try {
- Path outputPath = Paths.get(outputFile);
- if(Files.exists(outputPath))
- Files.delete(outputPath);
- } catch (IOException ex) {
- failCleanup(ex, outputFile);
- }
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest002.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +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.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.transform.Result;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-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.sax.SAXSource;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-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.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test newTransformerhandler() method which takes SAXSource as argument can
- * be set to XMLReader.
- */
-public class SAXTFactoryTest002 {
- /**
- * SAXTFactory.newTransformerhandler() method which takes SAXSource as
- * argument can be set to XMLReader. SAXSource has input XML file as its
- * input source. XMLReader has a content handler which write out the result
- * to output file. Test verifies output file is same as golden file.
- */
- @Test
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf002.out";
- String goldFile = GOLDEN_DIR + "saxtf002GF.out";
- String xsltFile = XML_DIR + "cities.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try (FileOutputStream fos = new FileOutputStream(outputFile);
- FileInputStream fis = new FileInputStream(xsltFile)) {
- XMLReader reader = XMLReaderFactory.createXMLReader();
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory) TransformerFactory.newInstance();
- SAXSource ss = new SAXSource();
- ss.setInputSource(new InputSource(fis));
-
- TransformerHandler handler = saxTFactory.newTransformerHandler(ss);
- Result result = new StreamResult(fos);
- handler.setResult(result);
- reader.setContentHandler(handler);
- reader.parse(xmlFile);
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (SAXException | IOException | TransformerConfigurationException ex) {
- failUnexpected(ex);
- } finally {
- try {
- Path outputPath = Paths.get(outputFile);
- if(Files.exists(outputPath))
- Files.delete(outputPath);
- } catch (IOException ex) {
- failCleanup(ex, outputFile);
- }
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest003.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +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.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.Result;
-import javax.xml.transform.TransformerConfigurationException;
-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.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-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.w3c.dom.Node;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test newTransformerhandler() method which takes DOMSource as argument can
- * be set to XMLReader.
- */
-public class SAXTFactoryTest003 {
- /**
- * Unit test for newTransformerhandler(Source). DcoumentBuilderFactory is
- * namespace awareness, DocumentBuilder parse xslt file as DOMSource.
- */
- @Test
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf003.out";
- String goldFile = GOLDEN_DIR + "saxtf003GF.out";
- String xsltFile = XML_DIR + "cities.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try (FileOutputStream fos = new FileOutputStream(outputFile)) {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- DocumentBuilder docBuilder = dbf.newDocumentBuilder();
- Document document = docBuilder.parse(new File(xsltFile));
- Node node = (Node)document;
- DOMSource domSource= new DOMSource(node);
-
- XMLReader reader = XMLReaderFactory.createXMLReader();
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory)TransformerFactory.newInstance();
- TransformerHandler handler =
- saxTFactory.newTransformerHandler(domSource);
- Result result = new StreamResult(fos);
- handler.setResult(result);
- reader.setContentHandler(handler);
- reader.parse(xmlFile);
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (TransformerConfigurationException | 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);
- }
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest004.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +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.IOException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import static javax.xml.transform.ptests.TransformerTestConst.XML_DIR;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import static jaxp.library.JAXPTestUtilities.failUnexpected;
-import org.testng.annotations.Test;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-/*
- * TransformerConfigurationException expected when there is relative URI is used
- * in citiesinclude.xsl file
- */
-public class SAXTFactoryTest004 {
- /**
- * Negative test for newTransformerHandler when relative URI is in XML file.
- * @throws TransformerConfigurationException If for some reason the
- * TransformerHandler can not be created.
- */
- @Test(expectedExceptions = TransformerConfigurationException.class)
- public void transformerHandlerTest01() throws TransformerConfigurationException {
- try {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- DocumentBuilder docBuilder = dbf.newDocumentBuilder();
- Document document = docBuilder.parse(new File(XML_DIR + "citiesinclude.xsl"));
- DOMSource domSource= new DOMSource(document);
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory)TransformerFactory.newInstance();
- saxTFactory.newTransformerHandler(domSource);
- } catch (ParserConfigurationException | IOException | SAXException ex) {
- failUnexpected(ex);
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest005.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +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.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.Result;
-import javax.xml.transform.TransformerConfigurationException;
-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.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-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.w3c.dom.Node;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test SAXSource API when relative URI is used in xsl file and SystemId was set
- */
-public class SAXTFactoryTest005 {
- /**
- * Unit test for XMLReader parsing when relative URI is used in xsl file and
- * SystemId was set.
- */
- @Test
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf005.out";
- String goldFile = GOLDEN_DIR + "saxtf005GF.out";
- String xsltFile = XML_DIR + "citiesinclude.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try (FileOutputStream fos = new FileOutputStream(outputFile)) {
- XMLReader reader = XMLReaderFactory.createXMLReader();
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory)TransformerFactory.newInstance();
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- DocumentBuilder docBuilder = dbf.newDocumentBuilder();
- Document document = docBuilder.parse(new File(xsltFile));
- Node node = (Node)document;
- DOMSource domSource= new DOMSource(node);
-
- domSource.setSystemId("file:///" + XML_DIR);
-
- TransformerHandler handler =
- saxTFactory.newTransformerHandler(domSource);
- Result result = new StreamResult(fos);
-
- handler.setResult(result);
- reader.setContentHandler(handler);
- reader.parse(xmlFile);
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (TransformerConfigurationException | 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);
- }
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest006.java Wed Jan 28 17:48:59 2015 +0100
+++ /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.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.Result;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-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.Node;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test newTransformerHandler with a DOMSource and StreamResult set.
- */
-public class SAXTFactoryTest006 extends TransformerTestConst{
- /**
- * Unit test newTransformerHandler with a DOMSource.
- */
- @Test
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf006.out";
- String goldFile = GOLDEN_DIR + "saxtf006GF.out";
- String xsltFile = XML_DIR + "citiesinclude.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try (FileOutputStream fos = new FileOutputStream(outputFile)) {
- XMLReader reader = XMLReaderFactory.createXMLReader();
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory)TransformerFactory.newInstance();
-
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- DocumentBuilder docBuilder = dbf.newDocumentBuilder();
- Node node = (Node)docBuilder.parse(new File(xsltFile));
-
- DOMSource domSource = new DOMSource(node, "file:///" + XML_DIR);
- TransformerHandler handler =
- saxTFactory.newTransformerHandler(domSource);
-
- Result result = new StreamResult(fos);
- handler.setResult(result);
- reader.setContentHandler(handler);
- reader.parse(xmlFile);
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (TransformerConfigurationException | 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);
- }
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest008.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +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.FileOutputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import javax.xml.transform.Result;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-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.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TemplatesHandler;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-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.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test newTransformerHandler with a Template Handler.
- */
-public class SAXTFactoryTest008 {
- /**
- * Test newTransformerHandler with a Template Handler.
- */
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf008.out";
- String goldFile = GOLDEN_DIR + "saxtf008GF.out";
- String xsltFile = XML_DIR + "cities.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try (FileOutputStream fos = new FileOutputStream(outputFile)) {
- XMLReader reader = XMLReaderFactory.createXMLReader();
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory)TransformerFactory.newInstance();
-
- TemplatesHandler thandler = saxTFactory.newTemplatesHandler();
- reader.setContentHandler(thandler);
- reader.parse(xsltFile);
- TransformerHandler tfhandler
- = saxTFactory.newTransformerHandler(thandler.getTemplates());
-
- Result result = new StreamResult(fos);
- tfhandler.setResult(result);
-
- reader.setContentHandler(tfhandler);
- reader.parse(xmlFile);
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (SAXException | IOException | TransformerConfigurationException ex) {
- failUnexpected(ex);
- } finally {
- try {
- Path outputPath = Paths.get(outputFile);
- if(Files.exists(outputPath))
- Files.delete(outputPath);
- } catch (IOException ex) {
- failCleanup(ex, outputFile);
- }
- }
- }
-
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest009.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +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.FileOutputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import javax.xml.transform.Result;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-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.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TemplatesHandler;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-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 org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test newTransformerHandler with a Template Handler along with a relative URI
- * in the xslt file.
- */
-public class SAXTFactoryTest009 {
- /**
- * Test newTransformerHandler with a Template Handler along with a relative
- * URI in the xslt file.
- */
- @Test
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf009.out";
- String goldFile = GOLDEN_DIR + "saxtf009GF.out";
- String xsltFile = XML_DIR + "citiesinclude.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try (FileOutputStream fos = new FileOutputStream(outputFile)) {
- XMLReader reader = XMLReaderFactory.createXMLReader();
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory)TransformerFactory.newInstance();
-
- TemplatesHandler thandler = saxTFactory.newTemplatesHandler();
- thandler.setSystemId("file:///" + XML_DIR);
- reader.setContentHandler(thandler);
- reader.parse(xsltFile);
- TransformerHandler tfhandler=
- saxTFactory.newTransformerHandler(thandler.getTemplates());
- Result result = new StreamResult(fos);
- tfhandler.setResult(result);
- reader.setContentHandler(tfhandler);
- reader.parse(xmlFile);
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (SAXException | IOException | TransformerConfigurationException ex) {
- failUnexpected(ex);
- } finally {
- try {
- Path outputPath = Paths.get(outputFile);
- if(Files.exists(outputPath))
- Files.delete(outputPath);
- } catch (IOException ex) {
- failCleanup(ex, outputFile);
- }
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest010.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +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.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-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.sax.SAXTransformerFactory;
-import javax.xml.transform.stream.StreamSource;
-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.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLFilter;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test XMLFilter parse InputSource along with customized ContentHandler.
- */
-public class SAXTFactoryTest010 {
- /**
- * Unit test for contentHandler setter/getter along reader as handler's
- * parent.
- */
- @Test
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf010.out";
- String goldFile = GOLDEN_DIR + "saxtf010GF.out";
- String xsltFile = XML_DIR + "cities.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try {
- // The transformer will use a SAX parser as it's reader.
- XMLReader reader = XMLReaderFactory.createXMLReader();
-
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory)TransformerFactory.newInstance();
- XMLFilter filter =
- saxTFactory.newXMLFilter(new StreamSource(xsltFile));
-
- filter.setParent(reader);
- filter.setContentHandler(new MyContentHandler(outputFile));
-
- // Now, when you call transformer.parse, it will set itself as
- // the content handler for the parser object (it's "parent"), and
- // will then call the parse method on the parser.
- filter.parse(new InputSource(xmlFile));
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (SAXException | IOException | TransformerConfigurationException ex) {
- failUnexpected(ex);
- } finally {
- try {
- Path outputPath = Paths.get(outputFile);
- if(Files.exists(outputPath))
- Files.delete(outputPath);
- } catch (IOException ex) {
- failCleanup(ex, outputFile);
- }
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest011.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +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.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.TransformerConfigurationException;
-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.sax.SAXTransformerFactory;
-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.w3c.dom.Node;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLFilter;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test XMLFilter parse InputSource along with customized ContentHandler by
- * using SAX parser as it's reader.
- */
-public class SAXTFactoryTest011 {
- /**
- * Unit test for contentHandler setter/getter with parent.
- */
- @Test
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf011.out";
- String goldFile = GOLDEN_DIR + "saxtf011GF.out";
- String xsltFile = XML_DIR + "cities.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try {
- // The transformer will use a SAX parser as it's reader.
- XMLReader reader = XMLReaderFactory.createXMLReader();
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- DocumentBuilder docBuilder = dbf.newDocumentBuilder();
- Document document = docBuilder.parse(new File(xsltFile));
- Node node = (Node)document;
- DOMSource domSource= new DOMSource(node);
-
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory)TransformerFactory.newInstance();
- XMLFilter filter = saxTFactory.newXMLFilter(domSource);
-
- filter.setParent(reader);
- filter.setContentHandler(new MyContentHandler(outputFile));
-
- // Now, when you call transformer.parse, it will set itself as
- // the content handler for the parser object (it's "parent"), and
- // will then call the parse method on the parser.
- filter.parse(new InputSource(xmlFile));
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (SAXException | IOException | TransformerConfigurationException
- | ParserConfigurationException ex) {
- failUnexpected(ex);
- } finally {
- try {
- Path outputPath = Paths.get(outputFile);
- if(Files.exists(outputPath))
- Files.delete(outputPath);
- } catch (IOException ex) {
- failCleanup(ex, outputFile);
- }
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest012.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +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.FileInputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-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.sax.SAXSource;
-import javax.xml.transform.sax.SAXTransformerFactory;
-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.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLFilter;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test XMLFilter parse InputSource along with customized ContentHandler by
- * using SAX parser as it's reader.
- */
-public class SAXTFactoryTest012 {
- /**
- * Unit test for contentHandler setter/getter.
- */
- @Test
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf012.out";
- String goldFile = GOLDEN_DIR + "saxtf012GF.out";
- String xsltFile = XML_DIR + "cities.xsl";
- String xmlFile = XML_DIR + "cities.xml";
- try {
- // The transformer will use a SAX parser as it's reader.
- XMLReader reader = XMLReaderFactory.createXMLReader();
-
- InputSource is = new InputSource(new FileInputStream(xsltFile));
- SAXSource saxSource = new SAXSource();
- saxSource.setInputSource(is);
-
- SAXTransformerFactory saxTFactory = (SAXTransformerFactory)TransformerFactory.newInstance();
- XMLFilter filter = saxTFactory.newXMLFilter(saxSource);
-
- filter.setParent(reader);
- filter.setContentHandler(new MyContentHandler(outputFile));
-
- // Now, when you call transformer.parse, it will set itself as
- // the content handler for the parser object (it's "parent"), and
- // will then call the parse method on the parser.
- filter.parse(new InputSource(xmlFile));
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (SAXException | IOException | TransformerConfigurationException ex) {
- failUnexpected(ex);
- } finally {
- try {
- Path outputPath = Paths.get(outputFile);
- if(Files.exists(outputPath))
- Files.delete(outputPath);
- } catch (IOException ex) {
- failCleanup(ex, outputFile);
- }
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/SAXTFactoryTest013.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +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.FileInputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-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.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TemplatesHandler;
-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.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLFilter;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * Test XMLFilter parse InputSource along with TemplatesHandler.
- */
-public class SAXTFactoryTest013 {
- /**
- * Unit test for TemplatesHandler setter/getter.
- */
- @Test
- public void testcase01() {
- String outputFile = CLASS_DIR + "saxtf013.out";
- String goldFile = GOLDEN_DIR + "saxtf013GF.out";
- String xsltFile = XML_DIR + "cities.xsl";
- String xmlFile = XML_DIR + "cities.xml";
-
- try {
- // The transformer will use a SAX parser as it's reader.
- XMLReader reader = XMLReaderFactory.createXMLReader();
-
- SAXTransformerFactory saxTFactory
- = (SAXTransformerFactory) TransformerFactory.newInstance();
- TemplatesHandler thandler = saxTFactory.newTemplatesHandler();
- // I have put this as it was complaining about systemid
- thandler.setSystemId("file:///" + CLASS_DIR);
-
- reader.setContentHandler(thandler);
- reader.parse(xsltFile);
- XMLFilter filter
- = saxTFactory.newXMLFilter(thandler.getTemplates());
- filter.setParent(reader);
-
- filter.setContentHandler(
- new MyContentHandler(outputFile));
- filter.parse(new InputSource(new FileInputStream(xmlFile)));
- assertTrue(compareWithGold(goldFile, outputFile));
- } catch (SAXException | IOException | TransformerConfigurationException ex) {
- failUnexpected(ex);
- } finally {
- try {
- Path outputPath = Paths.get(outputFile);
- if(Files.exists(outputPath))
- Files.delete(outputPath);
- } catch (IOException ex) {
- failCleanup(ex, outputFile);
- }
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/StreamResultTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,98 @@
+/*
+ * 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.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.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.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 StreamResultTest extends JAXPFileBaseTest {
+ /**
+ * 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(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);
+ }
+ });
+ }
+}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/StreamResultTest01.java Wed Jan 28 17:48:59 2015 +0100
+++ /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);
- }
- });
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TfClearParamTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TfClearParamTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerExcpTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerExcpTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerFactoryTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerFactoryTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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");
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest02.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest02.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest03.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/TransformerTest03.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/URIResolverTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/URIResolverTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/othervm/TFCErrorTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/ptests/othervm/TFCErrorTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
}
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathExpressionTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathExpressionTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFactoryTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFactoryTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFunctionResolverTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathFunctionResolverTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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");
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/xpath/ptests/XPathTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttrImplTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttrImplTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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";
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesNSTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesNSTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/AttributesTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ContentHandlerTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ContentHandlerTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
+ }
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/DefaultHandlerTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/DefaultHandlerTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
+
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/EHFatalTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/EHFatalTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyAttrCHandler.java Wed Jan 28 17:48:59 2015 +0100
+++ /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();
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/MyNSContentHandler.java Wed Jan 28 17:48:59 2015 +0100
+++ /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);
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSSupportTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSSupportTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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.
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
+ }
+}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/NSTableTest01.java Wed Jan 28 17:48:59 2015 +0100
+++ /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);
- }
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ParserAdapterTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ParserAdapterTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
}
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ResolverTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/ResolverTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/SAXParserNSTableTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/SAXParserNSTableTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterCBTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterCBTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
+ }
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLFilterTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderAdapterTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderAdapterTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderFactoryTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderFactoryTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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"));
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderNSTableTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderNSTableTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/org/xml/sax/ptests/XMLReaderTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionController.java Thu Jan 29 03:54:45 2015 +0000
@@ -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 <a href="content/movies.xml">movies.xml</a>
*/
- @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 <a href="content/userDetails.xsd">userDetails.xsd</a>
*/
- @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 <a href="content/coins.xsd">coins.xsd</a>
* @see <a href="content/coinsImportMe.xsd">coinsImportMe.xsd</a>
*/
- @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 <a href="content/coins.xsd">coins.xsd</a>
* @see <a href="content/coinsImportMe.xsd">coinsImportMe.xsd</a>
*/
- @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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/AuctionItemRepository.java Thu Jan 29 03:54:45 2015 +0000
@@ -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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMErrorHandler.java Wed Jan 28 17:48:59 2015 +0100
+++ /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;
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyDOMOutput.java Wed Jan 28 17:48:59 2015 +0100
+++ /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;
- }
-}
--- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/MyErrorHandler.java Wed Jan 28 17:48:59 2015 +0100
+++ /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;
- }
-
-}
--- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/UserController.java Thu Jan 29 03:54:45 2015 +0000
@@ -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 <a href="content/accountInfo.xml">accountInfo.xml</a>
+ *
+ * @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 <a href="content/accountInfo.xml">accountInfo.xml</a>
+ *
+ * @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 <a href="content/screenName.xml">screenName.xml</a> 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));
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/test/auctionportal/XInclHandler.java Wed Jan 28 17:48:59 2015 +0100
+++ /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("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- }
- }
-
- /**
- * 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("<?").append(target);
- if (data != null && data.length() > 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("</" + raw + ">");
- }
-
- /**
- * 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("<!--" + normalizeAndPrint(ch, start, length) + "-->");
- }
- }
-
- /**
- * 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();
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyCHandler.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/MyErrorHandler.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/parsers/ptests/ParserTestConst.java Thu Jan 29 03:54:45 2015 +0000
@@ -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");
+}
--- a/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/MyContentHandler.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/MyContentHandler.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/TransformerTestConst.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/transform/ptests/TransformerTestConst.java Thu Jan 29 03:54:45 2015 +0000
@@ -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");
}
--- a/jaxp/test/javax/xml/jaxp/libs/javax/xml/xpath/ptests/XPathTestConst.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/libs/javax/xml/xpath/ptests/XPathTestConst.java Thu Jan 29 03:54:45 2015 +0000
@@ -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");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPBaseTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileBaseTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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"));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPFileReadOnlyBaseTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
+ }
+}
--- a/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/JAXPTestUtilities.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Class, Integer> 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<String> 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;
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/jaxp/library/TestPolicy.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Permission> 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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyAttrCHandler.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/MyNSContentHandler.java Thu Jan 29 03:54:45 2015 +0000
@@ -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();
+ }
+}
--- a/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/SAXTestConst.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/libs/org/xml/sax/ptests/SAXTestConst.java Thu Jan 29 03:54:45 2015 +0000
@@ -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");
}
--- a/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/HiBidConstants.java Thu Jan 29 03:54:45 2015 +0000
@@ -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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMErrorHandler.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyDOMOutput.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/MyErrorHandler.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/libs/test/auctionportal/XInclHandler.java Thu Jan 29 03:54:45 2015 +0000
@@ -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("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ }
+ }
+
+ /**
+ * 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("<?").append(target);
+ if (data != null && data.length() > 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("</" + raw + ">");
+ }
+
+ /**
+ * 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("<!--" + normalizeAndPrint(ch, start, length) + "-->");
+ }
+ }
+
+ /**
+ * 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();
+ }
+}
--- a/jaxws/.hgtags Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/.hgtags Thu Jan 29 03:54:45 2015 +0000
@@ -291,3 +291,5 @@
edc13d27dc871be57d7ca77eef77e6d04972fee2 jdk9-b43
2a03baa4d849818ff6d635f110c2813b12fc2326 jdk9-b44
e529374fbe526dbd668e5e98fc047b42b3bc6d33 jdk9-b45
+64ca52b0bda8028636e4ccafbe1107befcdda47d jdk9-b46
+6c17d648d03e4bf4729c3645f8db55d34115e0b7 jdk9-b47
--- a/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/api/Utils.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/api/Utils.java Thu Jan 29 03:54:45 2015 +0000
@@ -38,6 +38,9 @@
/**
* Utils class.
+ *
+ * WARNING: If you are doing any changes don't forget to change other Utils classes in different packages.
+ *
* Has *package private* access to avoid inappropriate usage.
*/
final class Utils {
@@ -51,17 +54,20 @@
static { // we statically initializing REFLECTION_NAVIGATOR property
try {
- Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
- //noinspection unchecked
- final Method getInstance = refNav.getDeclaredMethod("getInstance");
+ final Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
// requires accessClassInPackage privilege
- AccessController.doPrivileged(
- new PrivilegedAction<Object>() {
+ final Method getInstance = AccessController.doPrivileged(
+ new PrivilegedAction<Method>() {
@Override
- public Object run() {
- getInstance.setAccessible(true);
- return null;
+ public Method run() {
+ try {
+ Method getInstance = refNav.getDeclaredMethod("getInstance");
+ getInstance.setAccessible(true);
+ return getInstance;
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
+ }
}
}
);
@@ -69,16 +75,10 @@
//noinspection unchecked
REFLECTION_NAVIGATOR = (Navigator<Type, Class, Field, Method>) getInstance.invoke(null);
} catch (ClassNotFoundException e) {
- e.printStackTrace();
throw new IllegalStateException("Can't find ReflectionNavigator class");
} catch (InvocationTargetException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance throws the exception");
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
} catch (IllegalAccessException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance method is inaccessible");
} catch (SecurityException e) {
LOGGER.log(Level.FINE, "Unable to access ReflectionNavigator.getInstance", e);
--- a/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java Thu Jan 29 03:54:45 2015 +0000
@@ -205,7 +205,15 @@
static {
- QName[] qnames = (System.getProperty(MAP_ANYURI_TO_URI) == null) ? new QName[] {
+ String MAP_ANYURI_TO_URI_VALUE = AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ @Override
+ public String run() {
+ return System.getProperty(MAP_ANYURI_TO_URI);
+ }
+ }
+ );
+ QName[] qnames = (MAP_ANYURI_TO_URI_VALUE == null) ? new QName[] {
createXS("string"),
createXS("anySimpleType"),
createXS("normalizedString"),
@@ -318,7 +326,7 @@
return v.toExternalForm();
}
});
- if (System.getProperty(MAP_ANYURI_TO_URI) == null) {
+ if (MAP_ANYURI_TO_URI_VALUE == null) {
secondaryList.add(
new StringImpl<URI>(URI.class, createXS("string")) {
public URI parse(CharSequence text) throws SAXException {
@@ -782,17 +790,18 @@
}
});
primaryList.add(
- new StringImpl<BigDecimal>(BigDecimal.class,
- createXS("decimal")
+ new StringImpl<BigDecimal>(BigDecimal.class,
+ createXS("decimal")
) {
- public BigDecimal parse(CharSequence text) {
- return DatatypeConverterImpl._parseDecimal(text.toString());
+ public BigDecimal parse(CharSequence text) {
+ return DatatypeConverterImpl._parseDecimal(text.toString());
+ }
+
+ public String print(BigDecimal v) {
+ return DatatypeConverterImpl._printDecimal(v);
+ }
}
-
- public String print(BigDecimal v) {
- return DatatypeConverterImpl._printDecimal(v);
- }
- });
+ );
primaryList.add(
new StringImpl<QName>(QName.class,
createXS("QName")
@@ -820,7 +829,7 @@
w.getNamespaceContext().declareNamespace(v.getNamespaceURI(),v.getPrefix(),false);
}
});
- if (System.getProperty(MAP_ANYURI_TO_URI) != null) {
+ if (MAP_ANYURI_TO_URI_VALUE != null) {
primaryList.add(
new StringImpl<URI>(URI.class, createXS("anyURI")) {
public URI parse(CharSequence text) throws SAXException {
@@ -838,16 +847,17 @@
});
}
primaryList.add(
- new StringImpl<Duration>(Duration.class, createXS("duration")) {
- public String print(Duration duration) {
- return duration.toString();
- }
+ new StringImpl<Duration>(Duration.class, createXS("duration")) {
+ public String print(Duration duration) {
+ return duration.toString();
+ }
- public Duration parse(CharSequence lexical) {
- TODO.checkSpec("JSR222 Issue #42");
- return DatatypeConverterImpl.getDatatypeFactory().newDuration(lexical.toString());
+ public Duration parse(CharSequence lexical) {
+ TODO.checkSpec("JSR222 Issue #42");
+ return DatatypeConverterImpl.getDatatypeFactory().newDuration(lexical.toString());
+ }
}
- });
+ );
primaryList.add(
new StringImpl<Void>(Void.class) {
// 'void' binding isn't defined by the spec, but when the JAX-RPC processes user-defined
--- a/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/model/impl/Utils.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/model/impl/Utils.java Thu Jan 29 03:54:45 2015 +0000
@@ -38,6 +38,9 @@
/**
* Utils class.
+ *
+ * WARNING: If you are doing any changes don't forget to change other Utils classes in different packages.
+ *
* Has *package private* access to avoid inappropriate usage.
*/
final class Utils {
@@ -51,17 +54,20 @@
static { // we statically initializing REFLECTION_NAVIGATOR property
try {
- Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
- //noinspection unchecked
- final Method getInstance = refNav.getDeclaredMethod("getInstance");
+ final Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
// requires accessClassInPackage privilege
- AccessController.doPrivileged(
- new PrivilegedAction<Object>() {
+ final Method getInstance = AccessController.doPrivileged(
+ new PrivilegedAction<Method>() {
@Override
- public Object run() {
- getInstance.setAccessible(true);
- return null;
+ public Method run() {
+ try {
+ Method getInstance = refNav.getDeclaredMethod("getInstance");
+ getInstance.setAccessible(true);
+ return getInstance;
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
+ }
}
}
);
@@ -69,16 +75,10 @@
//noinspection unchecked
REFLECTION_NAVIGATOR = (Navigator<Type, Class, Field, Method>) getInstance.invoke(null);
} catch (ClassNotFoundException e) {
- e.printStackTrace();
throw new IllegalStateException("Can't find ReflectionNavigator class");
} catch (InvocationTargetException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance throws the exception");
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
} catch (IllegalAccessException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance method is inaccessible");
} catch (SecurityException e) {
LOGGER.log(Level.FINE, "Unable to access ReflectionNavigator.getInstance", e);
--- a/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/runtime/Utils.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/runtime/Utils.java Thu Jan 29 03:54:45 2015 +0000
@@ -38,6 +38,9 @@
/**
* Utils class.
+ *
+ * WARNING: If you are doing any changes don't forget to change other Utils classes in different packages.
+ *
* Has *package private* access to avoid inappropriate usage.
*/
final class Utils {
@@ -51,17 +54,20 @@
static { // we statically initializing REFLECTION_NAVIGATOR property
try {
- Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
- //noinspection unchecked
- final Method getInstance = refNav.getDeclaredMethod("getInstance");
+ final Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
// requires accessClassInPackage privilege
- AccessController.doPrivileged(
- new PrivilegedAction<Object>() {
+ final Method getInstance = AccessController.doPrivileged(
+ new PrivilegedAction<Method>() {
@Override
- public Object run() {
- getInstance.setAccessible(true);
- return null;
+ public Method run() {
+ try {
+ Method getInstance = refNav.getDeclaredMethod("getInstance");
+ getInstance.setAccessible(true);
+ return getInstance;
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
+ }
}
}
);
@@ -69,16 +75,10 @@
//noinspection unchecked
REFLECTION_NAVIGATOR = (Navigator<Type, Class, Field, Method>) getInstance.invoke(null);
} catch (ClassNotFoundException e) {
- e.printStackTrace();
throw new IllegalStateException("Can't find ReflectionNavigator class");
} catch (InvocationTargetException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance throws the exception");
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
} catch (IllegalAccessException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance method is inaccessible");
} catch (SecurityException e) {
LOGGER.log(Level.FINE, "Unable to access ReflectionNavigator.getInstance", e);
--- a/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/runtime/property/Utils.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/runtime/property/Utils.java Thu Jan 29 03:54:45 2015 +0000
@@ -38,6 +38,9 @@
/**
* Utils class.
+ *
+ * WARNING: If you are doing any changes don't forget to change other Utils classes in different packages.
+ *
* Has *package private* access to avoid inappropriate usage.
*/
final class Utils {
@@ -51,17 +54,20 @@
static { // we statically initializing REFLECTION_NAVIGATOR property
try {
- Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
- //noinspection unchecked
- final Method getInstance = refNav.getDeclaredMethod("getInstance");
+ final Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
// requires accessClassInPackage privilege
- AccessController.doPrivileged(
- new PrivilegedAction<Object>() {
+ final Method getInstance = AccessController.doPrivileged(
+ new PrivilegedAction<Method>() {
@Override
- public Object run() {
- getInstance.setAccessible(true);
- return null;
+ public Method run() {
+ try {
+ Method getInstance = refNav.getDeclaredMethod("getInstance");
+ getInstance.setAccessible(true);
+ return getInstance;
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
+ }
}
}
);
@@ -69,16 +75,10 @@
//noinspection unchecked
REFLECTION_NAVIGATOR = (Navigator<Type, Class, Field, Method>) getInstance.invoke(null);
} catch (ClassNotFoundException e) {
- e.printStackTrace();
throw new IllegalStateException("Can't find ReflectionNavigator class");
} catch (InvocationTargetException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance throws the exception");
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
} catch (IllegalAccessException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance method is inaccessible");
} catch (SecurityException e) {
LOGGER.log(Level.FINE, "Unable to access ReflectionNavigator.getInstance", e);
--- a/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/runtime/reflect/Utils.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/runtime/reflect/Utils.java Thu Jan 29 03:54:45 2015 +0000
@@ -38,6 +38,9 @@
/**
* Utils class.
+ *
+ * WARNING: If you are doing any changes don't forget to change other Utils classes in different packages.
+ *
* Has *package private* access to avoid inappropriate usage.
*/
final class Utils {
@@ -51,17 +54,20 @@
static { // we statically initializing REFLECTION_NAVIGATOR property
try {
- Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
- //noinspection unchecked
- final Method getInstance = refNav.getDeclaredMethod("getInstance");
+ final Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
// requires accessClassInPackage privilege
- AccessController.doPrivileged(
- new PrivilegedAction<Object>() {
+ final Method getInstance = AccessController.doPrivileged(
+ new PrivilegedAction<Method>() {
@Override
- public Object run() {
- getInstance.setAccessible(true);
- return null;
+ public Method run() {
+ try {
+ Method getInstance = refNav.getDeclaredMethod("getInstance");
+ getInstance.setAccessible(true);
+ return getInstance;
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
+ }
}
}
);
@@ -69,16 +75,10 @@
//noinspection unchecked
REFLECTION_NAVIGATOR = (Navigator<Type, Class, Field, Method>) getInstance.invoke(null);
} catch (ClassNotFoundException e) {
- e.printStackTrace();
throw new IllegalStateException("Can't find ReflectionNavigator class");
} catch (InvocationTargetException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance throws the exception");
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
} catch (IllegalAccessException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance method is inaccessible");
} catch (SecurityException e) {
LOGGER.log(Level.FINE, "Unable to access ReflectionNavigator.getInstance", e);
--- a/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/util/XmlFactory.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/util/XmlFactory.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,8 +25,10 @@
package com.sun.xml.internal.bind.v2.util;
-import com.sun.xml.internal.bind.Util;
import com.sun.xml.internal.bind.v2.Messages;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.XMLConstants;
@@ -43,8 +45,6 @@
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
-import static com.sun.xml.internal.bind.Util.getSystemProperty;
-
/**
* Provides helper methods for creating properly configured XML parser
* factory instances with namespace support turned on and configured for
@@ -68,7 +68,14 @@
*/
private static final String DISABLE_XML_SECURITY = "com.sun.xml.internal.bind.disableXmlSecurity";
- public static final boolean XML_SECURITY_DISABLED = Boolean.parseBoolean(getSystemProperty(DISABLE_XML_SECURITY));
+ private static final boolean XML_SECURITY_DISABLED = AccessController.doPrivileged(
+ new PrivilegedAction<Boolean>() {
+ @Override
+ public Boolean run() {
+ return Boolean.getBoolean(DISABLE_XML_SECURITY);
+ }
+ }
+ );
private static boolean isXMLSecurityDisabled(boolean runtimeSetting) {
return XML_SECURITY_DISABLED || runtimeSetting;
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/model/Utils.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/model/Utils.java Thu Jan 29 03:54:45 2015 +0000
@@ -54,17 +54,20 @@
static { // we statically initializing REFLECTION_NAVIGATOR property
try {
- Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
- //noinspection unchecked
- final Method getInstance = refNav.getDeclaredMethod("getInstance");
+ final Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
// requires accessClassInPackage privilege
- AccessController.doPrivileged(
- new PrivilegedAction<Object>() {
+ final Method getInstance = AccessController.doPrivileged(
+ new PrivilegedAction<Method>() {
@Override
- public Object run() {
- getInstance.setAccessible(true);
- return null;
+ public Method run() {
+ try {
+ Method getInstance = refNav.getDeclaredMethod("getInstance");
+ getInstance.setAccessible(true);
+ return getInstance;
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
+ }
}
}
);
@@ -72,16 +75,10 @@
//noinspection unchecked
REFLECTION_NAVIGATOR = (Navigator<Type, Class, Field, Method>) getInstance.invoke(null);
} catch (ClassNotFoundException e) {
- e.printStackTrace();
throw new IllegalStateException("Can't find ReflectionNavigator class");
} catch (InvocationTargetException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance throws the exception");
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
} catch (IllegalAccessException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance method is inaccessible");
} catch (SecurityException e) {
LOGGER.log(Level.FINE, "Unable to access ReflectionNavigator.getInstance", e);
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/spi/ProviderImpl.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/spi/ProviderImpl.java Thu Jan 29 03:54:45 2015 +0000
@@ -147,19 +147,12 @@
}
public EndpointReference readEndpointReference(final Source eprInfoset) {
- // EPR constructors are private, so we need privilege escalation.
- // this unmarshalling can only access instances of a fixed, known set of classes,
- // so doing that shouldn't introduce security vulnerability.
- return AccessController.doPrivileged(new PrivilegedAction<EndpointReference>() {
- public EndpointReference run() {
- try {
- Unmarshaller unmarshaller = eprjc.get().createUnmarshaller();
- return (EndpointReference) unmarshaller.unmarshal(eprInfoset);
- } catch (JAXBException e) {
- throw new WebServiceException("Error creating Marshaller or marshalling.", e);
- }
- }
- });
+ try {
+ Unmarshaller unmarshaller = eprjc.get().createUnmarshaller();
+ return (EndpointReference) unmarshaller.unmarshal(eprInfoset);
+ } catch (JAXBException e) {
+ throw new WebServiceException("Error creating Marshaller or marshalling.", e);
+ }
}
public <T> T getPort(EndpointReference endpointReference, Class<T> clazz, WebServiceFeature... webServiceFeatures) {
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/spi/db/Utils.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/spi/db/Utils.java Thu Jan 29 03:54:45 2015 +0000
@@ -54,17 +54,20 @@
static { // we statically initializing REFLECTION_NAVIGATOR property
try {
- Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
- //noinspection unchecked
- final Method getInstance = refNav.getDeclaredMethod("getInstance");
+ final Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
// requires accessClassInPackage privilege
- AccessController.doPrivileged(
- new PrivilegedAction<Object>() {
+ final Method getInstance = AccessController.doPrivileged(
+ new PrivilegedAction<Method>() {
@Override
- public Object run() {
- getInstance.setAccessible(true);
- return null;
+ public Method run() {
+ try {
+ Method getInstance = refNav.getDeclaredMethod("getInstance");
+ getInstance.setAccessible(true);
+ return getInstance;
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
+ }
}
}
);
@@ -72,16 +75,10 @@
//noinspection unchecked
REFLECTION_NAVIGATOR = (Navigator<Type, Class, Field, Method>) getInstance.invoke(null);
} catch (ClassNotFoundException e) {
- e.printStackTrace();
throw new IllegalStateException("Can't find ReflectionNavigator class");
} catch (InvocationTargetException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance throws the exception");
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
} catch (IllegalAccessException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance method is inaccessible");
} catch (SecurityException e) {
LOGGER.log(Level.FINE, "Unable to access ReflectionNavigator.getInstance", e);
--- a/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/xml/XmlUtil.java Thu Jan 29 03:54:45 2015 +0000
@@ -63,6 +63,8 @@
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
@@ -84,12 +86,16 @@
private static final Logger LOGGER = Logger.getLogger(XmlUtil.class.getName());
- private static boolean XML_SECURITY_DISABLED;
+ private static final String DISABLE_XML_SECURITY = "com.sun.xml.internal.ws.disableXmlSecurity";
- static {
- String disableXmlSecurity = System.getProperty("com.sun.xml.internal.ws.disableXmlSecurity");
- XML_SECURITY_DISABLED = disableXmlSecurity == null || !Boolean.valueOf(disableXmlSecurity);
- }
+ private static boolean XML_SECURITY_DISABLED = AccessController.doPrivileged(
+ new PrivilegedAction<Boolean>() {
+ @Override
+ public Boolean run() {
+ return Boolean.getBoolean(DISABLE_XML_SECURITY);
+ }
+ }
+ );
public static String getPrefix(String s) {
int i = s.indexOf(':');
--- a/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/model/nav/Utils.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jaxws/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/model/nav/Utils.java Thu Jan 29 03:54:45 2015 +0000
@@ -38,6 +38,9 @@
/**
* Utils class.
+ *
+ * WARNING: If you are doing any changes don't forget to change other Utils classes in different packages.
+ *
* Has *package private* access to avoid inappropriate usage.
*/
final class Utils {
@@ -51,17 +54,20 @@
static { // we statically initializing REFLECTION_NAVIGATOR property
try {
- Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
- //noinspection unchecked
- final Method getInstance = refNav.getDeclaredMethod("getInstance");
+ final Class refNav = Class.forName("com.sun.xml.internal.bind.v2.model.nav.ReflectionNavigator");
// requires accessClassInPackage privilege
- AccessController.doPrivileged(
- new PrivilegedAction<Object>() {
+ final Method getInstance = AccessController.doPrivileged(
+ new PrivilegedAction<Method>() {
@Override
- public Object run() {
- getInstance.setAccessible(true);
- return null;
+ public Method run() {
+ try {
+ Method getInstance = refNav.getDeclaredMethod("getInstance");
+ getInstance.setAccessible(true);
+ return getInstance;
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
+ }
}
}
);
@@ -69,16 +75,10 @@
//noinspection unchecked
REFLECTION_NAVIGATOR = (Navigator<Type, Class, Field, Method>) getInstance.invoke(null);
} catch (ClassNotFoundException e) {
- e.printStackTrace();
throw new IllegalStateException("Can't find ReflectionNavigator class");
} catch (InvocationTargetException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance throws the exception");
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- throw new IllegalStateException("ReflectionNavigator.getInstance can't be found");
} catch (IllegalAccessException e) {
- e.printStackTrace();
throw new IllegalStateException("ReflectionNavigator.getInstance method is inaccessible");
} catch (SecurityException e) {
LOGGER.log(Level.FINE, "Unable to access ReflectionNavigator.getInstance", e);
--- a/jdk/.hgtags Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/.hgtags Thu Jan 29 03:54:45 2015 +0000
@@ -288,3 +288,5 @@
8c6ad41974f9ab6c33d544b088648314963f2a50 jdk9-b43
8cc4dc300041eb70a7a40e4b2431a8f4d4965ea4 jdk9-b44
9acaa4f57b0b9e3757a7b4576ca9418a75ea8287 jdk9-b45
+efedac7f44ed41cea2b1038138047271f55aacba jdk9-b46
+b641c14730ac05d9ec8b4f66e6fca3dc21adb403 jdk9-b47
--- a/jdk/make/Tools.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/Tools.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -34,28 +34,23 @@
include NativeCompilation.gmk
include SetupJavaCompilers.gmk
-# The exception handling of swing beaninfo which have the own tool directory
-ifeq (, $(BUILD_TOOLS_JDK))
- $(eval $(call SetupJavaCompilation,BUILD_TOOLS_JDK, \
- SETUP := GENERATE_OLDBYTECODE, \
- ADD_JAVAC_FLAGS := "-Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes", \
- SRC := $(JDK_TOPDIR)/make/src/classes, \
- BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \
- COPY := boot.modules ext.modules))
-endif
+################################################################################
+
+$(eval $(call SetupJavaCompilation,BUILD_TOOLS_JDK, \
+ SETUP := GENERATE_OLDBYTECODE, \
+ ADD_JAVAC_FLAGS := "-Xbootclasspath/p:$(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes", \
+ SRC := $(JDK_TOPDIR)/make/src/classes, \
+ BIN := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes, \
+ COPY := boot.modules ext.modules))
-$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources/%.template: \
- $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/%.template
- $(call install-file)
-
-BUILD_TOOLS_JDK += $(foreach i, $(wildcard $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/*.template), $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources/$(notdir $i))
+$(eval $(call SetupCopyFiles,COPY_NIMBUS_TEMPLATES, \
+ SRC := $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus, \
+ DEST := $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/generatenimbus/resources, \
+ FILES := $(wildcard $(JDK_TOPDIR)/src/java.desktop/share/classes/javax/swing/plaf/nimbus/*.template)))
-# Resource used by CheckDeps tool
-$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/deps/refs.allowed: \
- $(JDK_TOPDIR)/make/data/checkdeps/refs.allowed
- $(call install-file)
+BUILD_TOOLS_JDK += $(COPY_NIMBUS_TEMPLATES)
-BUILD_TOOLS_JDK += $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes/build/tools/deps/refs.allowed
+################################################################################
# Add a checksum ("jsum") to the end of a text file. Prevents trivial tampering with class lists.
TOOL_ADDJSUM = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
@@ -130,10 +125,6 @@
TOOL_CLDRCONVERTER = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
build.tools.cldrconverter.CLDRConverter
-TOOL_CHECKDEPS = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \
- -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \
- build.tools.deps.CheckDeps
-
TOOL_GENMODULESXML = $(JAVA_SMALL) -Xbootclasspath/p:$(INTERIM_LANGTOOLS_JAR) \
-cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes$(PATH_SEP)$(JDK_OUTPUTDIR)" \
build.tools.module.GenJdepsModulesXml
@@ -161,25 +152,25 @@
# Tools needed on solaris because OBJCOPY is broken.
ifeq ($(OPENJDK_TARGET_OS), solaris)
-$(eval $(call SetupNativeCompilation,ADD_GNU_DEBUGLINK, \
- SRC := $(JDK_TOPDIR)/make/src/native/add_gnu_debuglink, \
- LANG := C, \
- CC := $(BUILD_CC), \
- LDEXE := $(BUILD_LD), \
- LDFLAGS := -lelf, \
- OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/add_gnu_debuglink, \
- OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
- PROGRAM := add_gnu_debuglink))
+ $(eval $(call SetupNativeCompilation,ADD_GNU_DEBUGLINK, \
+ SRC := $(JDK_TOPDIR)/make/src/native/add_gnu_debuglink, \
+ LANG := C, \
+ CC := $(BUILD_CC), \
+ LDEXE := $(BUILD_LD), \
+ LDFLAGS := -lelf, \
+ OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/add_gnu_debuglink, \
+ OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
+ PROGRAM := add_gnu_debuglink))
-$(eval $(call SetupNativeCompilation,FIX_EMPTY_SEC_HDR_FLAGS, \
- SRC := $(JDK_TOPDIR)/make/src/native/fix_empty_sec_hdr_flags, \
- LANG := C, \
- CC := $(BUILD_CC), \
- LDEXE := $(BUILD_LD), \
- LDFLAGS := -lelf, \
- OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \
- OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
- PROGRAM := fix_empty_sec_hdr_flags))
+ $(eval $(call SetupNativeCompilation,FIX_EMPTY_SEC_HDR_FLAGS, \
+ SRC := $(JDK_TOPDIR)/make/src/native/fix_empty_sec_hdr_flags, \
+ LANG := C, \
+ CC := $(BUILD_CC), \
+ LDEXE := $(BUILD_LD), \
+ LDFLAGS := -lelf, \
+ OBJECT_DIR := $(BUILDTOOLS_OUTPUTDIR)/objs/fix_empty_sec_hdr_flags, \
+ OUTPUT_DIR := $(BUILDTOOLS_OUTPUTDIR)/bin, \
+ PROGRAM := fix_empty_sec_hdr_flags))
endif
$(BUILD_TOOLS_JDK): $(BUILD_INTERIM_JIMAGE)
--- a/jdk/make/data/checkdeps/refs.allowed Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#
-# This properties-formatted file contains the names of the non-existent types
-# that are allowed to be referenced from classes in a profiles image.
-#
-# The property key is a type that does not exist. The property value is one or
-# more types that reference the missing type. The property value also encodes
-# the names of the profiles where this reference is allowed.
-
-# jsse.jar is not subsetted by the profiles build. For compact1 and compact2
-# then this means that there are references to Kerberos types that do not
-# exist. These references are harmless.
-#
-javax.security.auth.kerberos.KerberosKey=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
-javax.security.auth.kerberos.KerberosPrincipal=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
-javax.security.auth.kerberos.KerberosTicket=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-javax.security.auth.kerberos.KeyTab=sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
-javax.security.auth.kerberos.ServicePermission=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
-sun.security.jgss.GSSCaller=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
-sun.security.jgss.krb5.Krb5Util=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,sun.security.ssl.krb5.Krb5ProxyImpl,compact1,compact2
-sun.security.jgss.krb5.ServiceCreds=sun.security.ssl.krb5.Krb5ProxyImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-sun.security.krb5.EncryptedData= sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-sun.security.krb5.EncryptionKey=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-sun.security.krb5.internal.crypto.KeyUsage=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-sun.security.krb5.internal.EncTicketPart=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-sun.security.krb5.internal.Krb5=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-sun.security.krb5.internal.Ticket=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-sun.security.krb5.KrbException=sun.security.ssl.krb5.KerberosPreMasterSecret,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-sun.security.krb5.PrincipalName=sun.security.ssl.krb5.Krb5ProxyImpl,sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-sun.security.krb5.Realm=sun.security.ssl.krb5.KerberosClientKeyExchangeImpl,compact1,compact2
-
-# Residual references to java.beans.
-# The RemoveMethods tool does not yet purge the constant pool.
-#
-java.beans.PropertyChangeListener=java.util.logging.LogManager,compact1,compact2,compact3
--- a/jdk/make/gendata/GendataPolicyJars.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/gendata/GendataPolicyJars.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -35,65 +35,62 @@
US_EXPORT_POLICY_JAR_DST := \
$(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/US_export_policy.jar
-ifneq ($(BUILD_CRYPTO), no)
-
- US_EXPORT_POLICY_JAR_LIMITED := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/limited/US_export_policy.jar
- US_EXPORT_POLICY_JAR_UNLIMITED := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy.jar
+US_EXPORT_POLICY_JAR_LIMITED := \
+ $(SUPPORT_OUTPUTDIR)/jce/policy/limited/US_export_policy.jar
+US_EXPORT_POLICY_JAR_UNLIMITED := \
+ $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy.jar
- ifndef OPENJDK
- #
- # In past releases, Oracle JDK has had a separately downloadable set of
- # policy files which has been a nightmare for deployment.
- #
- # Now if we're closed and limited (default for Oracle JDK), create
- # an "unlimited_policy" directory that contains the unlimited policy
- # files. It will be up to the user/deployer to make an informed choice
- # as to whether they are legally entitled to use the unlimited policy
- # file in their environment. Users/deployers simply need to overwrite
- # the files. Consult README.txt (below) for more info.
- #
- UNLIMITED_POLICY_DIR := \
- $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/unlimited_policy
- endif
+ifndef OPENJDK
+ #
+ # In past releases, Oracle JDK has had a separately downloadable set of
+ # policy files which has been a nightmare for deployment.
+ #
+ # Now if we're closed and limited (default for Oracle JDK), create
+ # an "unlimited_policy" directory that contains the unlimited policy
+ # files. It will be up to the user/deployer to make an informed choice
+ # as to whether they are legally entitled to use the unlimited policy
+ # file in their environment. Users/deployers simply need to overwrite
+ # the files. Consult README.txt (below) for more info.
+ #
+ UNLIMITED_POLICY_DIR := \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/unlimited_policy
+endif
- #
- # TODO fix so that SetupArchive does not write files into SRCS
- # then we don't need this extra copying
- #
- # NOTE: We currently do not place restrictions on our limited export
- # policy. This was not a typo. This means we are shipping the same file
- # for both limited and unlimited US_export_policy.jar. Only the local
- # policy file currently has restrictions.
- #
- US_EXPORT_POLICY_JAR_SRC_DIR := \
- $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited
- US_EXPORT_POLICY_JAR_TMP := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy_jar.tmp
+#
+# TODO fix so that SetupArchive does not write files into SRCS
+# then we don't need this extra copying
+#
+# NOTE: We currently do not place restrictions on our limited export
+# policy. This was not a typo. This means we are shipping the same file
+# for both limited and unlimited US_export_policy.jar. Only the local
+# policy file currently has restrictions.
+#
+US_EXPORT_POLICY_JAR_SRC_DIR := \
+ $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited
+US_EXPORT_POLICY_JAR_TMP := \
+ $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/US_export_policy_jar.tmp
- $(US_EXPORT_POLICY_JAR_TMP)/%: $(US_EXPORT_POLICY_JAR_SRC_DIR)/%
+$(US_EXPORT_POLICY_JAR_TMP)/%: $(US_EXPORT_POLICY_JAR_SRC_DIR)/%
$(install-file)
- US_EXPORT_POLICY_JAR_DEPS := \
- $(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy
+US_EXPORT_POLICY_JAR_DEPS := \
+ $(US_EXPORT_POLICY_JAR_TMP)/default_US_export.policy
- $(eval $(call SetupArchive,BUILD_US_EXPORT_POLICY_JAR, \
- $(US_EXPORT_POLICY_JAR_DEPS), \
- SRCS := $(US_EXPORT_POLICY_JAR_TMP), \
- SUFFIXES := .policy, \
- JAR := $(US_EXPORT_POLICY_JAR_UNLIMITED), \
- EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
- SKIP_METAINF := true))
+$(eval $(call SetupArchive,BUILD_US_EXPORT_POLICY_JAR, \
+ $(US_EXPORT_POLICY_JAR_DEPS), \
+ SRCS := $(US_EXPORT_POLICY_JAR_TMP), \
+ SUFFIXES := .policy, \
+ JAR := $(US_EXPORT_POLICY_JAR_UNLIMITED), \
+ EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
+ SKIP_METAINF := true))
- $(US_EXPORT_POLICY_JAR_LIMITED): \
- $(US_EXPORT_POLICY_JAR_UNLIMITED)
- $(ECHO) $(LOG_INFO) \
- Copying unlimited $(patsubst $(OUTPUT_ROOT)/%,%,$@)
- $(install-file)
+$(US_EXPORT_POLICY_JAR_LIMITED): \
+ $(US_EXPORT_POLICY_JAR_UNLIMITED)
+ $(ECHO) $(LOG_INFO) \
+ Copying unlimited $(patsubst $(OUTPUT_ROOT)/%,%,$@)
+ $(install-file)
- TARGETS += $(US_EXPORT_POLICY_JAR_LIMITED) $(US_EXPORT_POLICY_JAR_UNLIMITED)
-endif
+TARGETS += $(US_EXPORT_POLICY_JAR_LIMITED) $(US_EXPORT_POLICY_JAR_UNLIMITED)
ifeq ($(UNLIMITED_CRYPTO), true)
$(US_EXPORT_POLICY_JAR_DST): $(US_EXPORT_POLICY_JAR_UNLIMITED)
@@ -119,57 +116,54 @@
LOCAL_POLICY_JAR_DST := \
$(SUPPORT_OUTPUTDIR)/modules_libs/java.base/security/local_policy.jar
-ifneq ($(BUILD_CRYPTO), no)
+LOCAL_POLICY_JAR_LIMITED := \
+ $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy.jar
+LOCAL_POLICY_JAR_UNLIMITED := \
+ $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy.jar
- LOCAL_POLICY_JAR_LIMITED := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy.jar
- LOCAL_POLICY_JAR_UNLIMITED := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy.jar
+#
+# TODO fix so that SetupArchive does not write files into SRCS
+# then we don't need this extra copying
+#
+LOCAL_POLICY_JAR_LIMITED_TMP := \
+ $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy_jar.tmp
+LOCAL_POLICY_JAR_UNLIMITED_TMP := \
+ $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy_jar.tmp
+
+$(LOCAL_POLICY_JAR_LIMITED_TMP)/%: \
+ $(JDK_TOPDIR)/make/data/cryptopolicy/limited/%
+ $(install-file)
+
+$(LOCAL_POLICY_JAR_UNLIMITED_TMP)/%: \
+ $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited/%
+ $(install-file)
- #
- # TODO fix so that SetupArchive does not write files into SRCS
- # then we don't need this extra copying
- #
- LOCAL_POLICY_JAR_LIMITED_TMP := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/limited/local_policy_jar.tmp
- LOCAL_POLICY_JAR_UNLIMITED_TMP := \
- $(SUPPORT_OUTPUTDIR)/jce/policy/unlimited/local_policy_jar.tmp
+$(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR_LIMITED, \
+ $(LOCAL_POLICY_JAR_LIMITED_TMP)/exempt_local.policy \
+ $(LOCAL_POLICY_JAR_LIMITED_TMP)/default_local.policy, \
+ SRCS := $(LOCAL_POLICY_JAR_LIMITED_TMP), \
+ SUFFIXES := .policy, \
+ JAR := $(LOCAL_POLICY_JAR_LIMITED), \
+ EXTRA_MANIFEST_ATTR := Crypto-Strength: limited, \
+ SKIP_METAINF := true))
- $(LOCAL_POLICY_JAR_LIMITED_TMP)/%: \
- $(JDK_TOPDIR)/make/data/cryptopolicy/limited/%
- $(install-file)
+$(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR_UNLIMITED, \
+ $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/default_local.policy, \
+ SRCS := $(LOCAL_POLICY_JAR_UNLIMITED_TMP), \
+ SUFFIXES := .policy, \
+ JAR := $(LOCAL_POLICY_JAR_UNLIMITED), \
+ EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
+ SKIP_METAINF := true))
- $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/%: \
- $(JDK_TOPDIR)/make/data/cryptopolicy/unlimited/%
+TARGETS += $(LOCAL_POLICY_JAR_LIMITED) $(LOCAL_POLICY_JAR_UNLIMITED)
+
+ifndef OPENJDK
+ ifneq ($(UNLIMITED_CRYPTO), true)
+ $(UNLIMITED_POLICY_DIR)/README.txt: \
+ $(JDK_TOPDIR)/make/closed/data/cryptopolicy/README.txt
$(install-file)
- $(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR_LIMITED, \
- $(LOCAL_POLICY_JAR_LIMITED_TMP)/exempt_local.policy \
- $(LOCAL_POLICY_JAR_LIMITED_TMP)/default_local.policy, \
- SRCS := $(LOCAL_POLICY_JAR_LIMITED_TMP), \
- SUFFIXES := .policy, \
- JAR := $(LOCAL_POLICY_JAR_LIMITED), \
- EXTRA_MANIFEST_ATTR := Crypto-Strength: limited, \
- SKIP_METAINF := true))
-
- $(eval $(call SetupArchive,BUILD_LOCAL_POLICY_JAR_UNLIMITED, \
- $(LOCAL_POLICY_JAR_UNLIMITED_TMP)/default_local.policy, \
- SRCS := $(LOCAL_POLICY_JAR_UNLIMITED_TMP), \
- SUFFIXES := .policy, \
- JAR := $(LOCAL_POLICY_JAR_UNLIMITED), \
- EXTRA_MANIFEST_ATTR := Crypto-Strength: unlimited, \
- SKIP_METAINF := true))
-
- TARGETS += $(LOCAL_POLICY_JAR_LIMITED) $(LOCAL_POLICY_JAR_UNLIMITED)
-
- ifndef OPENJDK
- ifneq ($(UNLIMITED_CRYPTO), true)
- $(UNLIMITED_POLICY_DIR)/README.txt: \
- $(JDK_TOPDIR)/make/closed/data/cryptopolicy/README.txt
- $(install-file)
-
- TARGETS += $(UNLIMITED_POLICY_DIR)/README.txt
- endif
+ TARGETS += $(UNLIMITED_POLICY_DIR)/README.txt
endif
endif
--- a/jdk/make/gensrc/GensrcMisc.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/gensrc/GensrcMisc.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -28,6 +28,13 @@
# string and the runtime name into the Version.java file.
# To be printed by java -version
+# These dependencies should ideally be added to prerequesites for Version.java
+# but skip for now until we have better incremental build for java.
+# $(call DependOnVariable, LAUNCHER_NAME) \
+# $(call DependOnVariable, RELEASE) \
+# $(call DependOnVariable, FULL_VERSION) \
+# $(call DependOnVariable, RUNTIME_VERSION)
+
$(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/misc/Version.java: \
$(JDK_TOPDIR)/src/java.base/share/classes/sun/misc/Version.java.template
$(MKDIR) -p $(@D)
--- a/jdk/make/lib/Awt2dLibraries.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/lib/Awt2dLibraries.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -300,7 +300,6 @@
LIBAWT_XAWT_DIRS := \
$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libawt_xawt \
- $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libjawt \
$(JDK_TOPDIR)/src/java.desktop/share/native/common/awt/debug \
$(JDK_TOPDIR)/src/java.desktop/share/native/common/awt/utility \
$(JDK_TOPDIR)/src/java.desktop/share/native/common/font \
--- a/jdk/make/lib/CoreLibraries.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/lib/CoreLibraries.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -74,8 +74,6 @@
##########################################################################################
-BUILD_LIBVERIFY_SRC := check_code.c check_format.c
-
ifeq ($(OPENJDK_TARGET_OS), solaris)
ifneq ($(OPENJDK_TARGET_CPU), x86_64)
BUILD_LIBVERIFY_REORDER := $(JDK_TOPDIR)/make/mapfiles/libverify/reorder-$(OPENJDK_TARGET_CPU)
@@ -116,10 +114,6 @@
LIBJAVA_SRC_DIRS := $(call FindSrcDirsForLib, java.base, java)
-ifeq ($(OPENJDK_TARGET_OS), macosx)
- LIBJAVA_EXCLUDE_FILES += $(JDK_TOPDIR)/src/java.base/unix/native/libjava/HostLocaleProviderAdapter_md.c
-endif
-
LIBJAVA_CFLAGS := $(addprefix -I, $(LIBJAVA_SRC_DIRS)) \
-I$(JDK_TOPDIR)/src/java.base/share/native/libfdlibm \
-I$(SUPPORT_OUTPUTDIR)/headers/java.base \
@@ -134,9 +128,7 @@
LIBJAVA_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"'
endif
-ifneq ($(OPENJDK_TARGET_OS), macosx)
- LIBJAVA_EXCLUDE_FILES += java_props_macosx.c
-else
+ifeq ($(OPENJDK_TARGET_OS), macosx)
BUILD_LIBJAVA_java_props_md.c_CFLAGS := -x objective-c
BUILD_LIBJAVA_java_props_macosx.c_CFLAGS := -x objective-c
endif
@@ -151,8 +143,6 @@
LIBRARY := java, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBJAVA_SRC_DIRS), \
- EXCLUDES := fdlibm/src zip prefs, \
- EXCLUDE_FILES := $(LIBJAVA_EXCLUDE_FILES), \
LANG := C, \
OPTIMIZATION := HIGH, \
CFLAGS := $(CFLAGS_JDKLIB) \
@@ -247,19 +237,10 @@
##########################################################################################
-BUILD_LIBJLI_SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/native/libjli \
- $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjli
+LIBJLI_SRC_DIRS := $(call FindSrcDirsForLib, java.base, jli)
LIBJLI_CFLAGS := $(CFLAGS_JDKLIB)
-BUILD_LIBJLI_FILES := \
- java.c \
- splashscreen_stubs.c \
- parse_manifest.c \
- version_comp.c \
- wildcard.c \
- jli_util.c
-
ifeq ($(JVM_VARIANT_ZERO), true)
ERGO_FAMILY := zero
else
@@ -269,68 +250,55 @@
ERGO_FAMILY := $(OPENJDK_TARGET_CPU_ARCH)
endif
endif
+LIBJLI_ALL_ERGO := $(wildcard $(addsuffix /ergo_*.c, $(LIBJLI_SRC_DIRS)))
+LIBJLI_EXCLUDE_ERGO := $(filter-out %/ergo_$(ERGO_FAMILY).c, $(LIBJLI_ALL_ERGO))
+# If all specialized ergo files are excluded, use generic ergo
+ifeq ($(LIBJLI_ALL_ERGO), $(LIBJLI_EXCLUDE_ERGO))
+ LIBJLI_CFLAGS += -DUSE_GENERIC_ERGO
+endif
+LIBJLI_EXCLUDE_FILES += $(notdir $(LIBJLI_EXCLUDE_ERGO))
ifeq ($(OPENJDK_TARGET_OS), macosx)
- BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/macosx/native/libjli
- BUILD_LIBJLI_FILES += java_md_common.c java_md_macosx.c
+ LIBJLI_EXCLUDE_FILES += java_md_solinux.c ergo.c
BUILD_LIBJLI_java_md_macosx.c_CFLAGS := -x objective-c
BUILD_LIBJLI_STATIC_java_md_macosx.c_CFLAGS := -x objective-c
+
+ LIBJLI_CFLAGS += -DPACKAGE_PATH=\"$(PACKAGE_PATH)\"
endif
ifeq ($(OPENJDK_TARGET_OS), windows)
- BUILD_LIBJLI_FILES += java_md.c \
- cmdtoargs.c
# Staticically link with c runtime on windows.
LIBJLI_CFLAGS := $(filter-out -MD, $(LIBJLI_CFLAGS))
-else ifneq ($(OPENJDK_TARGET_OS), macosx)
-
- BUILD_LIBJLI_FILES += java_md_common.c
- BUILD_LIBJLI_FILES += java_md_solinux.c ergo.c
-
- ERGO_ARCH_FILE = ergo_$(ERGO_FAMILY).c
-
- # if the architecture specific ergo file exists then
- # use it, else use the generic definitions from ergo.c
- ifneq ($(wildcard $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjli/$(ERGO_ARCH_FILE)), )
- BUILD_LIBJLI_FILES += $(ERGO_ARCH_FILE)
- else # !ERGO_ARCH_FILE
- LIBJLI_CFLAGS += -DUSE_GENERIC_ERGO
- endif # ERGO_ARCH_FILE
-endif #WINDOWS
-
-LIBJLI_CFLAGS += $(foreach dir, $(BUILD_LIBJLI_SRC_DIRS), -I$(dir))
-
-# Append defines depending on target platform
-LIBJLI_CFLAGS += $(OPENJDK_TARGET_CPU_JLI_CFLAGS)
-
-ifeq ($(OPENJDK_TARGET_OS), macosx)
- LIBJLI_CFLAGS += -DPACKAGE_PATH=\"$(PACKAGE_PATH)\"
-endif
-
-ifneq ($(USE_EXTERNAL_LIBZ), true)
- BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/share/native/libzip/zlib-1.2.8
- LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS)
- BUILD_LIBJLI_FILES += \
- inflate.c \
- inftrees.c \
- inffast.c \
- zadler32.c \
- zcrc32.c \
- zutil.c
-endif
-
-ifeq ($(OPENJDK_TARGET_OS), windows)
LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)
else
LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)/jli
endif
+LIBJLI_CFLAGS += $(addprefix -I, $(LIBJLI_SRC_DIRS))
+
+# Append defines depending on target platform
+LIBJLI_CFLAGS += $(OPENJDK_TARGET_CPU_JLI_CFLAGS)
+
+ifneq ($(USE_EXTERNAL_LIBZ), true)
+ LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS)
+ LIBJLI_EXTRA_FILES += \
+ $(addprefix $(JDK_TOPDIR)/src/java.base/share/native/libzip/zlib-1.2.8/, \
+ inflate.c \
+ inftrees.c \
+ inffast.c \
+ zadler32.c \
+ zcrc32.c \
+ zutil.c \
+ )
+endif
+
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI, \
LIBRARY := jli, \
OUTPUT_DIR := $(LIBJLI_OUTPUT_DIR), \
- SRC := $(BUILD_LIBJLI_SRC_DIRS), \
- INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \
+ SRC := $(LIBJLI_SRC_DIRS), \
+ EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
+ EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
LANG := C, \
OPTIMIZATION := HIGH, \
CFLAGS := $(LIBJLI_CFLAGS), \
@@ -376,8 +344,9 @@
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
STATIC_LIBRARY := jli_static, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
- SRC := $(BUILD_LIBJLI_SRC_DIRS), \
- INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \
+ SRC := $(LIBJLI_SRC_DIRS), \
+ EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
+ EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
LANG := C, \
OPTIMIZATION := HIGH, \
CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \
@@ -395,8 +364,9 @@
$(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
LIBRARY := jli_static, \
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
- SRC := $(BUILD_LIBJLI_SRC_DIRS), \
- INCLUDE_FILES := $(BUILD_LIBJLI_FILES), \
+ SRC := $(LIBJLI_SRC_DIRS), \
+ EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
+ EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
LANG := C, \
OPTIMIZATION := HIGH, \
CFLAGS := $(CFLAGS_JDKLIB) $(LIBJLI_CFLAGS), \
@@ -411,16 +381,17 @@
else ifeq ($(OPENJDK_TARGET_OS), aix)
# AIX also requires a static libjli because the compiler doesn't support '-rpath'
- $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC,\
- STATIC_LIBRARY:=jli_static,\
- OUTPUT_DIR:=$(SUPPORT_OUTPUTDIR)/native/$(MODULE),\
- SRC:=$(BUILD_LIBJLI_SRC_DIRS),\
- INCLUDE_FILES:=$(BUILD_LIBJLI_FILES),\
- LANG:=C,\
- OPTIMIZATION:=HIGH, \
- CFLAGS:=$(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS),\
- ARFLAGS:=$(ARFLAGS),\
- OBJECT_DIR:=$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static))
+ $(eval $(call SetupNativeCompilation,BUILD_LIBJLI_STATIC, \
+ STATIC_LIBRARY := jli_static, \
+ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE), \
+ SRC := $(LIBJLI_SRC_DIRS), \
+ EXCLUDE_FILES := $(LIBJLI_EXCLUDE_FILES), \
+ EXTRA_FILES := $(LIBJLI_EXTRA_FILES), \
+ LANG := C, \
+ OPTIMIZATION := HIGH, \
+ CFLAGS := $(STATIC_LIBRARY_FLAGS) $(LIBJLI_CFLAGS), \
+ ARFLAGS := $(ARFLAGS), \
+ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static))
TARGETS += $(BUILD_LIBJLI_STATIC)
--- a/jdk/make/lib/Lib-jdk.attach.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/lib/Lib-jdk.attach.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -31,7 +31,7 @@
$(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \
LIBRARY := attach, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(JDK_TOPDIR)/src/jdk.attach/$(OPENJDK_TARGET_OS)/native/libattach, \
+ SRC := $(call FindSrcDirsForLib, jdk.attach, attach), \
LANG := C, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \
--- a/jdk/make/lib/Lib-jdk.security.auth.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/lib/Lib-jdk.security.auth.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -28,9 +28,7 @@
################################################################################
LIBJAAS_MAPFILE :=
-ifneq ($(OPENJDK_TARGET_OS), solaris)
- LIBJAAS_EXCLUDE_FILES := Solaris.c
-else
+ifeq ($(OPENJDK_TARGET_OS), solaris)
# only on solaris...wonder why
LIBJAAS_MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjaas/mapfile-vers
endif
@@ -43,7 +41,7 @@
$(eval $(call SetupNativeCompilation,BUILD_LIBJAAS, \
LIBRARY := $(LIBJAAS_NAME), \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(JDK_TOPDIR)/src/jdk.security.auth/$(OPENJDK_TARGET_OS_TYPE)/native/libjaas, \
+ SRC := $(call FindSrcDirsForLib, jdk.security.auth, jaas), \
LANG := C, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/jdk.security.auth, \
@@ -53,7 +51,6 @@
LDFLAGS_windows := netapi32.lib user32.lib mpr.lib advapi32.lib, \
LDFLAGS_SUFFIX_windows := $(LDFLAGS_JDKLIB_SUFFIX), \
LDFLAGS_SUFFIX_solaris := -lc, \
- EXCLUDE_FILES := $(LIBJAAS_EXCLUDE_FILES), \
VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=$(LIBJAAS_NAME).dll" \
--- a/jdk/make/lib/NetworkingLibraries.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/lib/NetworkingLibraries.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -23,39 +23,16 @@
# questions.
#
-LIBNET_SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/native/libnet \
- $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libnet
-LIBNET_CFLAGS += -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
- $(LIBJAVA_HEADER_FLAGS)
-
-LIBNET_CFLAGS += $(foreach dir, $(LIBNET_SRC_DIRS), -I$(dir))
-
-LIBNET_EXCLUDE_FILES :=
-ifneq ($(OPENJDK_TARGET_OS), solaris)
- LIBNET_EXCLUDE_FILES += solaris_close.c
-endif
-
-ifneq ($(OPENJDK_TARGET_OS), linux)
- LIBNET_EXCLUDE_FILES += linux_close.c
-endif
-
-ifneq ($(OPENJDK_TARGET_OS), macosx)
- LIBNET_EXCLUDE_FILES += bsd_close.c
-endif
-
-ifeq ($(OPENJDK_TARGET_OS), aix)
- LIBNET_SRC_DIRS += $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libnet/java/net/
-endif
+LIBNET_SRC_DIRS := $(call FindSrcDirsForLib, java.base, net)
$(eval $(call SetupNativeCompilation,BUILD_LIBNET, \
LIBRARY := net, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(LIBNET_SRC_DIRS), \
- EXCLUDE_FILES := $(LIBNET_EXCLUDE_FILES), \
LANG := C, \
OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) \
- $(LIBNET_CFLAGS), \
+ CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
+ $(LIBJAVA_HEADER_FLAGS) $(addprefix -I, $(LIBNET_SRC_DIRS)), \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libnet/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
--- a/jdk/make/lib/NioLibraries.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/lib/NioLibraries.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -65,7 +65,6 @@
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
SRC := $(BUILD_LIBNIO_SRC), \
EXCLUDE_FILES := $(BUILD_LIBNIO_EXFILES), \
- EXCLUDES := sctp, \
LANG := C, \
OPTIMIZATION := HIGH, \
CFLAGS := $(CFLAGS_JDKLIB) \
--- a/jdk/make/mapfiles/libjava/mapfile-vers Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -214,10 +214,10 @@
Java_java_lang_Throwable_fillInStackTrace;
Java_java_lang_Throwable_getStackTraceDepth;
Java_java_lang_Throwable_getStackTraceElement;
- Java_java_lang_UNIXProcess_init;
- Java_java_lang_UNIXProcess_waitForProcessExit;
- Java_java_lang_UNIXProcess_forkAndExec;
- Java_java_lang_UNIXProcess_destroyProcess;
+ Java_java_lang_ProcessImpl_init;
+ Java_java_lang_ProcessImpl_waitForProcessExit;
+ Java_java_lang_ProcessImpl_forkAndExec;
+ Java_java_lang_ProcessImpl_destroyProcess;
Java_java_nio_Bits_copyFromShortArray;
Java_java_nio_Bits_copyToShortArray;
Java_java_nio_Bits_copyFromIntArray;
--- a/jdk/make/src/classes/build/tools/deps/CheckDeps.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +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. 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 build.tools.deps;
-
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.charset.StandardCharsets;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Enumeration;
-import java.util.Properties;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-
-import com.sun.tools.classfile.ClassFile;
-import com.sun.tools.classfile.Dependencies;
-import com.sun.tools.classfile.Dependency;
-
-/**
- * A simple tool to check the JAR files in a JRE image to ensure that there
- * aren't any references to types that do not exist. The tool is intended to
- * be used in the JDK "profiles" build to help ensure that the profile
- * definitions are kept up to date.
- */
-
-public class CheckDeps {
-
- // classfile API for finding dependencies
- static final Dependency.Finder finder = Dependencies.getClassDependencyFinder();
-
- // "known types", found in rt.jar or other JAR files
- static final Set<String> knownTypes = new HashSet<>();
-
- // References to unknown types. The map key is the unknown type, the
- // map value is the set of classes that reference it.
- static final Map<String,Set<String>> unknownRefs = new HashMap<>();
-
- // The property name is the name of an unknown type that is allowed to be
- // references. The property value is a comma separated list of the types
- // that are allowed to reference it. The list also includes the names of
- // the profiles that the reference is allowed.
- static final Properties allowedBadRefs = new Properties();
-
- /**
- * Returns the class name for the given class file. In the case of inner
- * classes then the enclosing class is returned in order to keep the
- * rules simple.
- */
- static String toClassName(String s) {
- int i = s.indexOf('$');
- if (i > 0)
- s = s.substring(0, i);
- return s.replace("/", ".");
- }
-
- /**
- * Analyze the dependencies of all classes in the given JAR file. The
- * method updates knownTypes and unknownRefs as part of the analysis.
- */
- static void analyzeDependencies(Path jarpath) throws Exception {
- System.out.format("Analyzing %s%n", jarpath);
- try (JarFile jf = new JarFile(jarpath.toFile())) {
- Enumeration<JarEntry> entries = jf.entries();
- while (entries.hasMoreElements()) {
- JarEntry e = entries.nextElement();
- String name = e.getName();
- if (name.endsWith(".class")) {
- ClassFile cf = ClassFile.read(jf.getInputStream(e));
- for (Dependency d : finder.findDependencies(cf)) {
- String origin = toClassName(d.getOrigin().getName());
- String target = toClassName(d.getTarget().getName());
-
- // origin is now known
- unknownRefs.remove(origin);
- knownTypes.add(origin);
-
- // if the target is not known then record the reference
- if (!knownTypes.contains(target)) {
- Set<String> refs = unknownRefs.get(target);
- if (refs == null) {
- // first time seeing this unknown type
- refs = new HashSet<>();
- unknownRefs.put(target, refs);
- }
- refs.add(origin);
- }
- }
- }
- }
- }
- }
-
- /**
- * We have closure (no references to types that do not exist) if
- * unknownRefs is empty. When unknownRefs is not empty then it should
- * only contain references that are allowed to be present (these are
- * loaded from the refs.allowed properties file).
- *
- * @param the profile that is being tested, this determines the exceptions
- * in {@code allowedBadRefs} that apply.
- *
- * @return {@code true} if there are no missing types or the only references
- * to missing types are described by {@code allowedBadRefs}.
- */
- static boolean checkClosure(String profile) {
- // process the references to types that do not exist.
- boolean fail = false;
- for (Map.Entry<String,Set<String>> entry: unknownRefs.entrySet()) {
- String target = entry.getKey();
- for (String origin: entry.getValue()) {
- // check if origin -> target allowed
- String value = allowedBadRefs.getProperty(target);
- if (value == null) {
- System.err.format("%s -> %s (unknown type)%n", origin, target);
- fail = true;
- } else {
- // target is known, check if the origin is one that we
- // expect and that the exception applies to the profile.
- boolean found = false;
- boolean applicable = false;
- for (String s: value.split(",")) {
- s = s.trim();
- if (s.equals(origin))
- found = true;
- if (s.equals(profile))
- applicable = true;
- }
- if (!found || !applicable) {
- if (!found) {
- System.err.format("%s -> %s (not allowed)%n", origin, target);
- } else {
- System.err.format("%s -> %s (reference not applicable to %s)%n",
- origin, target, profile);
- }
- fail = true;
- }
- }
-
- }
- }
-
- return !fail;
- }
-
- static void fail(URL url) throws Exception {
- System.err.println("One or more unexpected references encountered");
- if (url != null)
- System.err.format("Check %s is up to date%n", Paths.get(url.toURI()));
- System.exit(-1);
- }
-
- public static void main(String[] args) throws Exception {
- // load properties file so that we know what missing types that are
- // allowed to be referenced.
- URL url = CheckDeps.class.getResource("refs.allowed");
- if (url != null) {
- try (InputStream in = url.openStream()) {
- allowedBadRefs.load(new InputStreamReader(in, StandardCharsets.UTF_8));
- }
- }
-
- if (args.length != 2) {
- System.err.println("Usage: java CheckDeps <image> <profile>");
- System.exit(-1);
- }
-
- String image = args[0];
- String profile = args[1];
-
- // process JAR files on boot class path
- Path lib = Paths.get(image, "lib");
- try (DirectoryStream<Path> stream = Files.newDirectoryStream(lib, "*.jar")) {
- for (Path jarpath: stream) {
- analyzeDependencies(jarpath);
- }
- }
-
- // classes on boot class path should not reference other types
- boolean okay = checkClosure(profile);
- if (!okay)
- fail(url);
-
- // process JAR files in the extensions directory
- try (DirectoryStream<Path> stream = Files.newDirectoryStream(lib.resolve("ext"), "*.jar")) {
- for (Path jarpath: stream) {
- analyzeDependencies(jarpath);
- }
- }
-
- // re-check to ensure that the extensions doesn't reference types that
- // do not exist.
- okay = checkClosure(profile);
- if (!okay)
- fail(url);
- }
-}
--- a/jdk/make/src/classes/build/tools/module/ext.modules Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/make/src/classes/build/tools/module/ext.modules Thu Jan 29 03:54:45 2015 +0000
@@ -6,4 +6,4 @@
jdk.naming.dns
jdk.scripting.nashorn
jdk.zipfs
-oracle.accessbridge
+jdk.accessbridge
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/aix/native/libnet/aix_close.c Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file contains implementations of NET_... functions. The NET_.. functions are
+ * wrappers for common file- and socket functions plus provisions for non-blocking IO.
+ *
+ * (basically, the layers remember all file descriptors waiting for a particular fd;
+ * all threads waiting on a certain fd can be woken up by sending them a signal; this
+ * is done e.g. when the fd is closed.)
+ *
+ * This was originally copied from the linux_close.c implementation.
+ *
+ * Side Note: This coding needs initialization. Under Linux this is done
+ * automatically via __attribute((constructor)), on AIX this is done manually
+ * (see aix_close_init).
+ *
+ */
+
+/*
+ AIX needs a workaround for I/O cancellation, see:
+ http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/close.htm
+ ...
+ The close subroutine is blocked until all subroutines which use the file
+ descriptor return to usr space. For example, when a thread is calling close
+ and another thread is calling select with the same file descriptor, the
+ close subroutine does not return until the select call returns.
+ ...
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/poll.h>
+
+/*
+ * Stack allocated by thread when doing blocking operation
+ */
+typedef struct threadEntry {
+ pthread_t thr; /* this thread */
+ struct threadEntry *next; /* next thread */
+ int intr; /* interrupted */
+} threadEntry_t;
+
+/*
+ * Heap allocated during initialized - one entry per fd
+ */
+typedef struct {
+ pthread_mutex_t lock; /* fd lock */
+ threadEntry_t *threads; /* threads blocked on fd */
+} fdEntry_t;
+
+/*
+ * Signal to unblock thread
+ */
+static int sigWakeup = (SIGRTMAX - 1);
+
+/*
+ * The fd table and the number of file descriptors
+ */
+static fdEntry_t *fdTable = NULL;
+static int fdCount = 0;
+
+/*
+ * Null signal handler
+ */
+static void sig_wakeup(int sig) {
+}
+
+/*
+ * Initialization routine (executed when library is loaded)
+ * Allocate fd tables and sets up signal handler.
+ *
+ * On AIX we don't have __attribute((constructor)) so we need to initialize
+ * manually (from JNI_OnLoad() in 'src/share/native/java/net/net_util.c')
+ */
+void aix_close_init() {
+ struct rlimit nbr_files;
+ sigset_t sigset;
+ struct sigaction sa;
+
+ /* Check already initialized */
+ if (fdCount > 0 && fdTable != NULL) {
+ return;
+ }
+
+ /*
+ * Allocate table based on the maximum number of
+ * file descriptors.
+ */
+ if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
+ fprintf(stderr, "library initialization failed - "
+ "unable to get max # of allocated fds\n");
+ abort();
+ }
+ fdCount = nbr_files.rlim_max;
+ /*
+ * We have a conceptual problem here, when the number of files is
+ * unlimited. As a kind of workaround, we ensure the table is big
+ * enough for handle even a large number of files. Since SAP itself
+ * recommends a limit of 32000 files, we just use 64000 as 'infinity'.
+ */
+ if (nbr_files.rlim_max == RLIM_INFINITY) {
+ fdCount = 64000;
+ }
+ fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+ if (fdTable == NULL) {
+ fprintf(stderr, "library initialization failed - "
+ "unable to allocate file descriptor table - out of memory");
+ abort();
+ }
+
+ {
+ int i;
+ for (i=0; i < fdCount; i++) {
+ pthread_mutex_init(&fdTable[i].lock, NULL);
+ }
+ }
+
+ /*
+ * Setup the signal handler
+ */
+ sa.sa_handler = sig_wakeup;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sigaction(sigWakeup, &sa, NULL);
+
+ sigemptyset(&sigset);
+ sigaddset(&sigset, sigWakeup);
+ sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+}
+
+/*
+ * Return the fd table for this fd or NULL is fd out
+ * of range.
+ */
+static inline fdEntry_t *getFdEntry(int fd)
+{
+ if (fd < 0 || fd >= fdCount) {
+ return NULL;
+ }
+ return &fdTable[fd];
+}
+
+/*
+ * Start a blocking operation :-
+ * Insert thread onto thread list for the fd.
+ */
+static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self)
+{
+ self->thr = pthread_self();
+ self->intr = 0;
+
+ pthread_mutex_lock(&(fdEntry->lock));
+ {
+ self->next = fdEntry->threads;
+ fdEntry->threads = self;
+ }
+ pthread_mutex_unlock(&(fdEntry->lock));
+}
+
+/*
+ * End a blocking operation :-
+ * Remove thread from thread list for the fd
+ * If fd has been interrupted then set errno to EBADF
+ */
+static inline void endOp
+ (fdEntry_t *fdEntry, threadEntry_t *self)
+{
+ int orig_errno = errno;
+ pthread_mutex_lock(&(fdEntry->lock));
+ {
+ threadEntry_t *curr, *prev=NULL;
+ curr = fdEntry->threads;
+ while (curr != NULL) {
+ if (curr == self) {
+ if (curr->intr) {
+ orig_errno = EBADF;
+ }
+ if (prev == NULL) {
+ fdEntry->threads = curr->next;
+ } else {
+ prev->next = curr->next;
+ }
+ break;
+ }
+ prev = curr;
+ curr = curr->next;
+ }
+ }
+ pthread_mutex_unlock(&(fdEntry->lock));
+ errno = orig_errno;
+}
+
+/*
+ * Close or dup2 a file descriptor ensuring that all threads blocked on
+ * the file descriptor are notified via a wakeup signal.
+ *
+ * fd1 < 0 => close(fd2)
+ * fd1 >= 0 => dup2(fd1, fd2)
+ *
+ * Returns -1 with errno set if operation fails.
+ */
+static int closefd(int fd1, int fd2) {
+ int rv, orig_errno;
+ fdEntry_t *fdEntry = getFdEntry(fd2);
+ if (fdEntry == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ /*
+ * Lock the fd to hold-off additional I/O on this fd.
+ */
+ pthread_mutex_lock(&(fdEntry->lock));
+
+ {
+ /* On fast machines we see that we enter dup2 before the
+ * accepting thread had a chance to get and process the signal.
+ * So in case we woke a thread up, give it some time to cope.
+ * Also see https://bugs.openjdk.java.net/browse/JDK-8006395 */
+ int num_woken = 0;
+
+ /*
+ * Send a wakeup signal to all threads blocked on this
+ * file descriptor.
+ */
+ threadEntry_t *curr = fdEntry->threads;
+ while (curr != NULL) {
+ curr->intr = 1;
+ pthread_kill( curr->thr, sigWakeup );
+ num_woken ++;
+ curr = curr->next;
+ }
+
+ if (num_woken > 0) {
+ usleep(num_woken * 50);
+ }
+
+ /*
+ * And close/dup the file descriptor
+ * (restart if interrupted by signal)
+ */
+ do {
+ if (fd1 < 0) {
+ rv = close(fd2);
+ } else {
+ rv = dup2(fd1, fd2);
+ }
+ } while (rv == -1 && errno == EINTR);
+ }
+
+ /*
+ * Unlock without destroying errno
+ */
+ orig_errno = errno;
+ pthread_mutex_unlock(&(fdEntry->lock));
+ errno = orig_errno;
+
+ return rv;
+}
+
+/*
+ * Wrapper for dup2 - same semantics as dup2 system call except
+ * that any threads blocked in an I/O system call on fd2 will be
+ * preempted and return -1/EBADF;
+ */
+int NET_Dup2(int fd, int fd2) {
+ if (fd < 0) {
+ errno = EBADF;
+ return -1;
+ }
+ return closefd(fd, fd2);
+}
+
+/*
+ * Wrapper for close - same semantics as close system call
+ * except that any threads blocked in an I/O on fd will be
+ * preempted and the I/O system call will return -1/EBADF.
+ */
+int NET_SocketClose(int fd) {
+ return closefd(-1, fd);
+}
+
+/************** Basic I/O operations here ***************/
+
+/*
+ * Macro to perform a blocking IO operation. Restarts
+ * automatically if interrupted by signal (other than
+ * our wakeup signal)
+ */
+#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
+ int ret; \
+ threadEntry_t self; \
+ fdEntry_t *fdEntry = getFdEntry(FD); \
+ if (fdEntry == NULL) { \
+ errno = EBADF; \
+ return -1; \
+ } \
+ do { \
+ startOp(fdEntry, &self); \
+ ret = FUNC; \
+ endOp(fdEntry, &self); \
+ } while (ret == -1 && errno == EINTR); \
+ return ret; \
+}
+
+int NET_Read(int s, void* buf, size_t len) {
+ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
+}
+
+int NET_ReadV(int s, const struct iovec * vector, int count) {
+ BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
+}
+
+int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
+ struct sockaddr *from, int *fromlen) {
+ socklen_t socklen = *fromlen;
+ BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) );
+ *fromlen = socklen;
+}
+
+int NET_Send(int s, void *msg, int len, unsigned int flags) {
+ BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
+}
+
+int NET_WriteV(int s, const struct iovec * vector, int count) {
+ BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) );
+}
+
+int NET_SendTo(int s, const void *msg, int len, unsigned int
+ flags, const struct sockaddr *to, int tolen) {
+ BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) );
+}
+
+int NET_Accept(int s, struct sockaddr *addr, int *addrlen) {
+ socklen_t socklen = *addrlen;
+ BLOCKING_IO_RETURN_INT( s, accept(s, addr, &socklen) );
+ *addrlen = socklen;
+}
+
+int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
+ int crc = -1, prc = -1;
+ threadEntry_t self;
+ fdEntry_t* fdEntry = getFdEntry(s);
+
+ if (fdEntry == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ /* On AIX, when the system call connect() is interrupted, the connection
+ * is not aborted and it will be established asynchronously by the kernel.
+ * Hence, no need to restart connect() when EINTR is received
+ */
+ startOp(fdEntry, &self);
+ crc = connect(s, addr, addrlen);
+ endOp(fdEntry, &self);
+
+ if (crc == -1 && errno == EINTR) {
+ struct pollfd s_pollfd;
+ int sockopt_arg = 0;
+ socklen_t len;
+
+ s_pollfd.fd = s;
+ s_pollfd.events = POLLOUT | POLLERR;
+
+ /* poll the file descriptor */
+ do {
+ startOp(fdEntry, &self);
+ prc = poll(&s_pollfd, 1, -1);
+ endOp(fdEntry, &self);
+ } while (prc == -1 && errno == EINTR);
+
+ if (prc < 0)
+ return prc;
+
+ len = sizeof(sockopt_arg);
+
+ /* Check whether the connection has been established */
+ if (getsockopt(s, SOL_SOCKET, SO_ERROR, &sockopt_arg, &len) == -1)
+ return -1;
+
+ if (sockopt_arg != 0 ) {
+ errno = sockopt_arg;
+ return -1;
+ }
+ } else {
+ return crc;
+ }
+
+ /* At this point, fd is connected. Set successful return code */
+ return 0;
+}
+
+int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
+ BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
+}
+
+/*
+ * Wrapper for poll(s, timeout).
+ * Auto restarts with adjusted timeout if interrupted by
+ * signal other than our wakeup signal.
+ */
+int NET_Timeout(int s, long timeout) {
+ long prevtime = 0, newtime;
+ struct timeval t;
+ fdEntry_t *fdEntry = getFdEntry(s);
+
+ /*
+ * Check that fd hasn't been closed.
+ */
+ if (fdEntry == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ /*
+ * Pick up current time as may need to adjust timeout
+ */
+ if (timeout > 0) {
+ gettimeofday(&t, NULL);
+ prevtime = t.tv_sec * 1000 + t.tv_usec / 1000;
+ }
+
+ for(;;) {
+ struct pollfd pfd;
+ int rv;
+ threadEntry_t self;
+
+ /*
+ * Poll the fd. If interrupted by our wakeup signal
+ * errno will be set to EBADF.
+ */
+ pfd.fd = s;
+ pfd.events = POLLIN | POLLERR;
+
+ startOp(fdEntry, &self);
+ rv = poll(&pfd, 1, timeout);
+ endOp(fdEntry, &self);
+
+ /*
+ * If interrupted then adjust timeout. If timeout
+ * has expired return 0 (indicating timeout expired).
+ */
+ if (rv < 0 && errno == EINTR) {
+ if (timeout > 0) {
+ gettimeofday(&t, NULL);
+ newtime = t.tv_sec * 1000 + t.tv_usec / 1000;
+ timeout -= newtime - prevtime;
+ if (timeout <= 0) {
+ return 0;
+ }
+ prevtime = newtime;
+ }
+ } else {
+ return rv;
+ }
+
+ }
+}
--- a/jdk/src/java.base/aix/native/libnet/java/net/aix_close.c Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,491 +0,0 @@
-/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * This file contains implementations of NET_... functions. The NET_.. functions are
- * wrappers for common file- and socket functions plus provisions for non-blocking IO.
- *
- * (basically, the layers remember all file descriptors waiting for a particular fd;
- * all threads waiting on a certain fd can be woken up by sending them a signal; this
- * is done e.g. when the fd is closed.)
- *
- * This was originally copied from the linux_close.c implementation.
- *
- * Side Note: This coding needs initialization. Under Linux this is done
- * automatically via __attribute((constructor)), on AIX this is done manually
- * (see aix_close_init).
- *
- */
-
-/*
- AIX needs a workaround for I/O cancellation, see:
- http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/close.htm
- ...
- The close subroutine is blocked until all subroutines which use the file
- descriptor return to usr space. For example, when a thread is calling close
- and another thread is calling select with the same file descriptor, the
- close subroutine does not return until the select call returns.
- ...
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/poll.h>
-
-/*
- * Stack allocated by thread when doing blocking operation
- */
-typedef struct threadEntry {
- pthread_t thr; /* this thread */
- struct threadEntry *next; /* next thread */
- int intr; /* interrupted */
-} threadEntry_t;
-
-/*
- * Heap allocated during initialized - one entry per fd
- */
-typedef struct {
- pthread_mutex_t lock; /* fd lock */
- threadEntry_t *threads; /* threads blocked on fd */
-} fdEntry_t;
-
-/*
- * Signal to unblock thread
- */
-static int sigWakeup = (SIGRTMAX - 1);
-
-/*
- * The fd table and the number of file descriptors
- */
-static fdEntry_t *fdTable = NULL;
-static int fdCount = 0;
-
-/*
- * Null signal handler
- */
-static void sig_wakeup(int sig) {
-}
-
-/*
- * Initialization routine (executed when library is loaded)
- * Allocate fd tables and sets up signal handler.
- *
- * On AIX we don't have __attribute((constructor)) so we need to initialize
- * manually (from JNI_OnLoad() in 'src/share/native/java/net/net_util.c')
- */
-void aix_close_init() {
- struct rlimit nbr_files;
- sigset_t sigset;
- struct sigaction sa;
-
- /* Check already initialized */
- if (fdCount > 0 && fdTable != NULL) {
- return;
- }
-
- /*
- * Allocate table based on the maximum number of
- * file descriptors.
- */
- if (-1 == getrlimit(RLIMIT_NOFILE, &nbr_files)) {
- fprintf(stderr, "library initialization failed - "
- "unable to get max # of allocated fds\n");
- abort();
- }
- fdCount = nbr_files.rlim_max;
- /*
- * We have a conceptual problem here, when the number of files is
- * unlimited. As a kind of workaround, we ensure the table is big
- * enough for handle even a large number of files. Since SAP itself
- * recommends a limit of 32000 files, we just use 64000 as 'infinity'.
- */
- if (nbr_files.rlim_max == RLIM_INFINITY) {
- fdCount = 64000;
- }
- fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
- if (fdTable == NULL) {
- fprintf(stderr, "library initialization failed - "
- "unable to allocate file descriptor table - out of memory");
- abort();
- }
-
- {
- int i;
- for (i=0; i < fdCount; i++) {
- pthread_mutex_init(&fdTable[i].lock, NULL);
- }
- }
-
- /*
- * Setup the signal handler
- */
- sa.sa_handler = sig_wakeup;
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sigaction(sigWakeup, &sa, NULL);
-
- sigemptyset(&sigset);
- sigaddset(&sigset, sigWakeup);
- sigprocmask(SIG_UNBLOCK, &sigset, NULL);
-}
-
-/*
- * Return the fd table for this fd or NULL is fd out
- * of range.
- */
-static inline fdEntry_t *getFdEntry(int fd)
-{
- if (fd < 0 || fd >= fdCount) {
- return NULL;
- }
- return &fdTable[fd];
-}
-
-/*
- * Start a blocking operation :-
- * Insert thread onto thread list for the fd.
- */
-static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self)
-{
- self->thr = pthread_self();
- self->intr = 0;
-
- pthread_mutex_lock(&(fdEntry->lock));
- {
- self->next = fdEntry->threads;
- fdEntry->threads = self;
- }
- pthread_mutex_unlock(&(fdEntry->lock));
-}
-
-/*
- * End a blocking operation :-
- * Remove thread from thread list for the fd
- * If fd has been interrupted then set errno to EBADF
- */
-static inline void endOp
- (fdEntry_t *fdEntry, threadEntry_t *self)
-{
- int orig_errno = errno;
- pthread_mutex_lock(&(fdEntry->lock));
- {
- threadEntry_t *curr, *prev=NULL;
- curr = fdEntry->threads;
- while (curr != NULL) {
- if (curr == self) {
- if (curr->intr) {
- orig_errno = EBADF;
- }
- if (prev == NULL) {
- fdEntry->threads = curr->next;
- } else {
- prev->next = curr->next;
- }
- break;
- }
- prev = curr;
- curr = curr->next;
- }
- }
- pthread_mutex_unlock(&(fdEntry->lock));
- errno = orig_errno;
-}
-
-/*
- * Close or dup2 a file descriptor ensuring that all threads blocked on
- * the file descriptor are notified via a wakeup signal.
- *
- * fd1 < 0 => close(fd2)
- * fd1 >= 0 => dup2(fd1, fd2)
- *
- * Returns -1 with errno set if operation fails.
- */
-static int closefd(int fd1, int fd2) {
- int rv, orig_errno;
- fdEntry_t *fdEntry = getFdEntry(fd2);
- if (fdEntry == NULL) {
- errno = EBADF;
- return -1;
- }
-
- /*
- * Lock the fd to hold-off additional I/O on this fd.
- */
- pthread_mutex_lock(&(fdEntry->lock));
-
- {
- /* On fast machines we see that we enter dup2 before the
- * accepting thread had a chance to get and process the signal.
- * So in case we woke a thread up, give it some time to cope.
- * Also see https://bugs.openjdk.java.net/browse/JDK-8006395 */
- int num_woken = 0;
-
- /*
- * Send a wakeup signal to all threads blocked on this
- * file descriptor.
- */
- threadEntry_t *curr = fdEntry->threads;
- while (curr != NULL) {
- curr->intr = 1;
- pthread_kill( curr->thr, sigWakeup );
- num_woken ++;
- curr = curr->next;
- }
-
- if (num_woken > 0) {
- usleep(num_woken * 50);
- }
-
- /*
- * And close/dup the file descriptor
- * (restart if interrupted by signal)
- */
- do {
- if (fd1 < 0) {
- rv = close(fd2);
- } else {
- rv = dup2(fd1, fd2);
- }
- } while (rv == -1 && errno == EINTR);
- }
-
- /*
- * Unlock without destroying errno
- */
- orig_errno = errno;
- pthread_mutex_unlock(&(fdEntry->lock));
- errno = orig_errno;
-
- return rv;
-}
-
-/*
- * Wrapper for dup2 - same semantics as dup2 system call except
- * that any threads blocked in an I/O system call on fd2 will be
- * preempted and return -1/EBADF;
- */
-int NET_Dup2(int fd, int fd2) {
- if (fd < 0) {
- errno = EBADF;
- return -1;
- }
- return closefd(fd, fd2);
-}
-
-/*
- * Wrapper for close - same semantics as close system call
- * except that any threads blocked in an I/O on fd will be
- * preempted and the I/O system call will return -1/EBADF.
- */
-int NET_SocketClose(int fd) {
- return closefd(-1, fd);
-}
-
-/************** Basic I/O operations here ***************/
-
-/*
- * Macro to perform a blocking IO operation. Restarts
- * automatically if interrupted by signal (other than
- * our wakeup signal)
- */
-#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
- int ret; \
- threadEntry_t self; \
- fdEntry_t *fdEntry = getFdEntry(FD); \
- if (fdEntry == NULL) { \
- errno = EBADF; \
- return -1; \
- } \
- do { \
- startOp(fdEntry, &self); \
- ret = FUNC; \
- endOp(fdEntry, &self); \
- } while (ret == -1 && errno == EINTR); \
- return ret; \
-}
-
-int NET_Read(int s, void* buf, size_t len) {
- BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
-}
-
-int NET_ReadV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
-}
-
-int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
- struct sockaddr *from, int *fromlen) {
- socklen_t socklen = *fromlen;
- BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, &socklen) );
- *fromlen = socklen;
-}
-
-int NET_Send(int s, void *msg, int len, unsigned int flags) {
- BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
-}
-
-int NET_WriteV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) );
-}
-
-int NET_SendTo(int s, const void *msg, int len, unsigned int
- flags, const struct sockaddr *to, int tolen) {
- BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) );
-}
-
-int NET_Accept(int s, struct sockaddr *addr, int *addrlen) {
- socklen_t socklen = *addrlen;
- BLOCKING_IO_RETURN_INT( s, accept(s, addr, &socklen) );
- *addrlen = socklen;
-}
-
-int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
- int crc = -1, prc = -1;
- threadEntry_t self;
- fdEntry_t* fdEntry = getFdEntry(s);
-
- if (fdEntry == NULL) {
- errno = EBADF;
- return -1;
- }
-
- /* On AIX, when the system call connect() is interrupted, the connection
- * is not aborted and it will be established asynchronously by the kernel.
- * Hence, no need to restart connect() when EINTR is received
- */
- startOp(fdEntry, &self);
- crc = connect(s, addr, addrlen);
- endOp(fdEntry, &self);
-
- if (crc == -1 && errno == EINTR) {
- struct pollfd s_pollfd;
- int sockopt_arg = 0;
- socklen_t len;
-
- s_pollfd.fd = s;
- s_pollfd.events = POLLOUT | POLLERR;
-
- /* poll the file descriptor */
- do {
- startOp(fdEntry, &self);
- prc = poll(&s_pollfd, 1, -1);
- endOp(fdEntry, &self);
- } while (prc == -1 && errno == EINTR);
-
- if (prc < 0)
- return prc;
-
- len = sizeof(sockopt_arg);
-
- /* Check whether the connection has been established */
- if (getsockopt(s, SOL_SOCKET, SO_ERROR, &sockopt_arg, &len) == -1)
- return -1;
-
- if (sockopt_arg != 0 ) {
- errno = sockopt_arg;
- return -1;
- }
- } else {
- return crc;
- }
-
- /* At this point, fd is connected. Set successful return code */
- return 0;
-}
-
-int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
- BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
-}
-
-/*
- * Wrapper for poll(s, timeout).
- * Auto restarts with adjusted timeout if interrupted by
- * signal other than our wakeup signal.
- */
-int NET_Timeout(int s, long timeout) {
- long prevtime = 0, newtime;
- struct timeval t;
- fdEntry_t *fdEntry = getFdEntry(s);
-
- /*
- * Check that fd hasn't been closed.
- */
- if (fdEntry == NULL) {
- errno = EBADF;
- return -1;
- }
-
- /*
- * Pick up current time as may need to adjust timeout
- */
- if (timeout > 0) {
- gettimeofday(&t, NULL);
- prevtime = t.tv_sec * 1000 + t.tv_usec / 1000;
- }
-
- for(;;) {
- struct pollfd pfd;
- int rv;
- threadEntry_t self;
-
- /*
- * Poll the fd. If interrupted by our wakeup signal
- * errno will be set to EBADF.
- */
- pfd.fd = s;
- pfd.events = POLLIN | POLLERR;
-
- startOp(fdEntry, &self);
- rv = poll(&pfd, 1, timeout);
- endOp(fdEntry, &self);
-
- /*
- * If interrupted then adjust timeout. If timeout
- * has expired return 0 (indicating timeout expired).
- */
- if (rv < 0 && errno == EINTR) {
- if (timeout > 0) {
- gettimeofday(&t, NULL);
- newtime = t.tv_sec * 1000 + t.tv_usec / 1000;
- timeout -= newtime - prevtime;
- if (timeout <= 0) {
- return 0;
- }
- prevtime = newtime;
- }
- } else {
- return rv;
- }
-
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/linux/native/libnet/linux_close.c Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/poll.h>
+
+/*
+ * Stack allocated by thread when doing blocking operation
+ */
+typedef struct threadEntry {
+ pthread_t thr; /* this thread */
+ struct threadEntry *next; /* next thread */
+ int intr; /* interrupted */
+} threadEntry_t;
+
+/*
+ * Heap allocated during initialized - one entry per fd
+ */
+typedef struct {
+ pthread_mutex_t lock; /* fd lock */
+ threadEntry_t *threads; /* threads blocked on fd */
+} fdEntry_t;
+
+/*
+ * Signal to unblock thread
+ */
+static int sigWakeup = (__SIGRTMAX - 2);
+
+/*
+ * The fd table and the number of file descriptors
+ */
+static fdEntry_t *fdTable;
+static int fdCount;
+
+/*
+ * Null signal handler
+ */
+static void sig_wakeup(int sig) {
+}
+
+/*
+ * Initialization routine (executed when library is loaded)
+ * Allocate fd tables and sets up signal handler.
+ */
+static void __attribute((constructor)) init() {
+ struct rlimit nbr_files;
+ sigset_t sigset;
+ struct sigaction sa;
+
+ /*
+ * Allocate table based on the maximum number of
+ * file descriptors.
+ */
+ getrlimit(RLIMIT_NOFILE, &nbr_files);
+ fdCount = nbr_files.rlim_max;
+ fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+ if (fdTable == NULL) {
+ fprintf(stderr, "library initialization failed - "
+ "unable to allocate file descriptor table - out of memory");
+ abort();
+ }
+
+ /*
+ * Setup the signal handler
+ */
+ sa.sa_handler = sig_wakeup;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sigaction(sigWakeup, &sa, NULL);
+
+ sigemptyset(&sigset);
+ sigaddset(&sigset, sigWakeup);
+ sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+}
+
+/*
+ * Return the fd table for this fd or NULL is fd out
+ * of range.
+ */
+static inline fdEntry_t *getFdEntry(int fd)
+{
+ if (fd < 0 || fd >= fdCount) {
+ return NULL;
+ }
+ return &fdTable[fd];
+}
+
+/*
+ * Start a blocking operation :-
+ * Insert thread onto thread list for the fd.
+ */
+static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self)
+{
+ self->thr = pthread_self();
+ self->intr = 0;
+
+ pthread_mutex_lock(&(fdEntry->lock));
+ {
+ self->next = fdEntry->threads;
+ fdEntry->threads = self;
+ }
+ pthread_mutex_unlock(&(fdEntry->lock));
+}
+
+/*
+ * End a blocking operation :-
+ * Remove thread from thread list for the fd
+ * If fd has been interrupted then set errno to EBADF
+ */
+static inline void endOp
+ (fdEntry_t *fdEntry, threadEntry_t *self)
+{
+ int orig_errno = errno;
+ pthread_mutex_lock(&(fdEntry->lock));
+ {
+ threadEntry_t *curr, *prev=NULL;
+ curr = fdEntry->threads;
+ while (curr != NULL) {
+ if (curr == self) {
+ if (curr->intr) {
+ orig_errno = EBADF;
+ }
+ if (prev == NULL) {
+ fdEntry->threads = curr->next;
+ } else {
+ prev->next = curr->next;
+ }
+ break;
+ }
+ prev = curr;
+ curr = curr->next;
+ }
+ }
+ pthread_mutex_unlock(&(fdEntry->lock));
+ errno = orig_errno;
+}
+
+/*
+ * Close or dup2 a file descriptor ensuring that all threads blocked on
+ * the file descriptor are notified via a wakeup signal.
+ *
+ * fd1 < 0 => close(fd2)
+ * fd1 >= 0 => dup2(fd1, fd2)
+ *
+ * Returns -1 with errno set if operation fails.
+ */
+static int closefd(int fd1, int fd2) {
+ int rv, orig_errno;
+ fdEntry_t *fdEntry = getFdEntry(fd2);
+ if (fdEntry == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ /*
+ * Lock the fd to hold-off additional I/O on this fd.
+ */
+ pthread_mutex_lock(&(fdEntry->lock));
+
+ {
+ /*
+ * And close/dup the file descriptor
+ * (restart if interrupted by signal)
+ */
+ do {
+ if (fd1 < 0) {
+ rv = close(fd2);
+ } else {
+ rv = dup2(fd1, fd2);
+ }
+ } while (rv == -1 && errno == EINTR);
+
+ /*
+ * Send a wakeup signal to all threads blocked on this
+ * file descriptor.
+ */
+ threadEntry_t *curr = fdEntry->threads;
+ while (curr != NULL) {
+ curr->intr = 1;
+ pthread_kill( curr->thr, sigWakeup );
+ curr = curr->next;
+ }
+ }
+
+ /*
+ * Unlock without destroying errno
+ */
+ orig_errno = errno;
+ pthread_mutex_unlock(&(fdEntry->lock));
+ errno = orig_errno;
+
+ return rv;
+}
+
+/*
+ * Wrapper for dup2 - same semantics as dup2 system call except
+ * that any threads blocked in an I/O system call on fd2 will be
+ * preempted and return -1/EBADF;
+ */
+int NET_Dup2(int fd, int fd2) {
+ if (fd < 0) {
+ errno = EBADF;
+ return -1;
+ }
+ return closefd(fd, fd2);
+}
+
+/*
+ * Wrapper for close - same semantics as close system call
+ * except that any threads blocked in an I/O on fd will be
+ * preempted and the I/O system call will return -1/EBADF.
+ */
+int NET_SocketClose(int fd) {
+ return closefd(-1, fd);
+}
+
+/************** Basic I/O operations here ***************/
+
+/*
+ * Macro to perform a blocking IO operation. Restarts
+ * automatically if interrupted by signal (other than
+ * our wakeup signal)
+ */
+#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
+ int ret; \
+ threadEntry_t self; \
+ fdEntry_t *fdEntry = getFdEntry(FD); \
+ if (fdEntry == NULL) { \
+ errno = EBADF; \
+ return -1; \
+ } \
+ do { \
+ startOp(fdEntry, &self); \
+ ret = FUNC; \
+ endOp(fdEntry, &self); \
+ } while (ret == -1 && errno == EINTR); \
+ return ret; \
+}
+
+int NET_Read(int s, void* buf, size_t len) {
+ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
+}
+
+int NET_ReadV(int s, const struct iovec * vector, int count) {
+ BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
+}
+
+int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
+ struct sockaddr *from, socklen_t *fromlen) {
+ BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, fromlen) );
+}
+
+int NET_Send(int s, void *msg, int len, unsigned int flags) {
+ BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
+}
+
+int NET_WriteV(int s, const struct iovec * vector, int count) {
+ BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) );
+}
+
+int NET_SendTo(int s, const void *msg, int len, unsigned int
+ flags, const struct sockaddr *to, int tolen) {
+ BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) );
+}
+
+int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) {
+ BLOCKING_IO_RETURN_INT( s, accept(s, addr, addrlen) );
+}
+
+int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
+ BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
+}
+
+int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
+ BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
+}
+
+/*
+ * Wrapper for poll(s, timeout).
+ * Auto restarts with adjusted timeout if interrupted by
+ * signal other than our wakeup signal.
+ */
+int NET_Timeout(int s, long timeout) {
+ long prevtime = 0, newtime;
+ struct timeval t;
+ fdEntry_t *fdEntry = getFdEntry(s);
+
+ /*
+ * Check that fd hasn't been closed.
+ */
+ if (fdEntry == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ /*
+ * Pick up current time as may need to adjust timeout
+ */
+ if (timeout > 0) {
+ gettimeofday(&t, NULL);
+ prevtime = t.tv_sec * 1000 + t.tv_usec / 1000;
+ }
+
+ for(;;) {
+ struct pollfd pfd;
+ int rv;
+ threadEntry_t self;
+
+ /*
+ * Poll the fd. If interrupted by our wakeup signal
+ * errno will be set to EBADF.
+ */
+ pfd.fd = s;
+ pfd.events = POLLIN | POLLERR;
+
+ startOp(fdEntry, &self);
+ rv = poll(&pfd, 1, timeout);
+ endOp(fdEntry, &self);
+
+ /*
+ * If interrupted then adjust timeout. If timeout
+ * has expired return 0 (indicating timeout expired).
+ */
+ if (rv < 0 && errno == EINTR) {
+ if (timeout > 0) {
+ gettimeofday(&t, NULL);
+ newtime = t.tv_sec * 1000 + t.tv_usec / 1000;
+ timeout -= newtime - prevtime;
+ if (timeout <= 0) {
+ return 0;
+ }
+ prevtime = newtime;
+ }
+ } else {
+ return rv;
+ }
+
+ }
+}
--- a/jdk/src/java.base/macosx/classes/java/lang/ClassLoaderHelper.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/macosx/classes/java/lang/ClassLoaderHelper.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,11 @@
private ClassLoaderHelper() {}
/**
+ * Indicates, whether PATH env variable is allowed to contain quoted entries.
+ */
+ static final boolean allowsQuotedPathElements = false;
+
+ /**
* Returns an alternate path name for the given file
* such that if the original pathname did not exist, then the
* file may be located at the alternate location.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/macosx/native/libjava/java_props_macosx.c Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <dlfcn.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <Security/AuthSession.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <Foundation/Foundation.h>
+
+#include "java_props_macosx.h"
+
+
+// need dlopen/dlsym trick to avoid pulling in JavaRuntimeSupport before libjava.dylib is loaded
+static void *getJRSFramework() {
+ static void *jrsFwk = NULL;
+ if (jrsFwk == NULL) {
+ jrsFwk = dlopen("/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport", RTLD_LAZY | RTLD_LOCAL);
+ }
+ return jrsFwk;
+}
+
+char *getPosixLocale(int cat) {
+ char *lc = setlocale(cat, NULL);
+ if ((lc == NULL) || (strcmp(lc, "C") == 0)) {
+ lc = getenv("LANG");
+ }
+ if (lc == NULL) return NULL;
+ return strdup(lc);
+}
+
+#define LOCALEIDLENGTH 128
+char *getMacOSXLocale(int cat) {
+ switch (cat) {
+ case LC_MESSAGES:
+ {
+ void *jrsFwk = getJRSFramework();
+ if (jrsFwk == NULL) return NULL;
+
+ char *(*JRSCopyPrimaryLanguage)() = dlsym(jrsFwk, "JRSCopyPrimaryLanguage");
+ char *primaryLanguage = JRSCopyPrimaryLanguage ? JRSCopyPrimaryLanguage() : NULL;
+ if (primaryLanguage == NULL) return NULL;
+
+ char *(*JRSCopyCanonicalLanguageForPrimaryLanguage)(char *) = dlsym(jrsFwk, "JRSCopyCanonicalLanguageForPrimaryLanguage");
+ char *canonicalLanguage = JRSCopyCanonicalLanguageForPrimaryLanguage ? JRSCopyCanonicalLanguageForPrimaryLanguage(primaryLanguage) : NULL;
+ free (primaryLanguage);
+
+ return canonicalLanguage;
+ }
+ break;
+ default:
+ {
+ char localeString[LOCALEIDLENGTH];
+ if (CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()),
+ localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) {
+ return strdup(localeString);
+ }
+ }
+ break;
+ }
+
+ return NULL;
+}
+
+char *setupMacOSXLocale(int cat) {
+ char * ret = getMacOSXLocale(cat);
+
+ if (cat == LC_MESSAGES && ret != NULL) {
+ void *jrsFwk = getJRSFramework();
+ if (jrsFwk != NULL) {
+ void (*JRSSetDefaultLocalization)(char *) = dlsym(jrsFwk, "JRSSetDefaultLocalization");
+ if (JRSSetDefaultLocalization) JRSSetDefaultLocalization(ret);
+ }
+ }
+
+ if (ret == NULL) {
+ return getPosixLocale(cat);
+ } else {
+ return ret;
+ }
+}
+
+int isInAquaSession() {
+ // environment variable to bypass the aqua session check
+ char *ev = getenv("AWT_FORCE_HEADFUL");
+ if (ev && (strncasecmp(ev, "true", 4) == 0)) {
+ // if "true" then tell the caller we're in an Aqua session without actually checking
+ return 1;
+ }
+ // Is the WindowServer available?
+ SecuritySessionId session_id;
+ SessionAttributeBits session_info;
+ OSStatus status = SessionGetInfo(callerSecuritySession, &session_id, &session_info);
+ if (status == noErr) {
+ if (session_info & sessionHasGraphicAccess) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void setOSNameAndVersion(java_props_t *sprops) {
+ /* Don't rely on JRSCopyOSName because there's no guarantee the value will
+ * remain the same, or even if the JRS functions will continue to be part of
+ * Mac OS X. So hardcode os_name, and fill in os_version if we can.
+ */
+ sprops->os_name = strdup("Mac OS X");
+
+ void *jrsFwk = getJRSFramework();
+ if (jrsFwk != NULL) {
+ char *(*copyOSVersion)() = dlsym(jrsFwk, "JRSCopyOSVersion");
+ if (copyOSVersion != NULL) {
+ sprops->os_version = copyOSVersion();
+ return;
+ }
+ }
+ sprops->os_version = strdup("Unknown");
+}
+
+
+static Boolean getProxyInfoForProtocol(CFDictionaryRef inDict, CFStringRef inEnabledKey, CFStringRef inHostKey, CFStringRef inPortKey, CFStringRef *outProxyHost, int *ioProxyPort) {
+ /* See if the proxy is enabled. */
+ CFNumberRef cf_enabled = CFDictionaryGetValue(inDict, inEnabledKey);
+ if (cf_enabled == NULL) {
+ return false;
+ }
+
+ int isEnabled = false;
+ if (!CFNumberGetValue(cf_enabled, kCFNumberIntType, &isEnabled)) {
+ return isEnabled;
+ }
+
+ if (!isEnabled) return false;
+ *outProxyHost = CFDictionaryGetValue(inDict, inHostKey);
+
+ // If cf_host is null, that means the checkbox is set,
+ // but no host was entered. We'll treat that as NOT ENABLED.
+ // If cf_port is null or cf_port isn't a number, that means
+ // no port number was entered. Treat this as ENABLED with the
+ // protocol's default port.
+ if (*outProxyHost == NULL) {
+ return false;
+ }
+
+ if (CFStringGetLength(*outProxyHost) == 0) {
+ return false;
+ }
+
+ int newPort = 0;
+ CFNumberRef cf_port = NULL;
+ if ((cf_port = CFDictionaryGetValue(inDict, inPortKey)) != NULL &&
+ CFNumberGetValue(cf_port, kCFNumberIntType, &newPort) &&
+ newPort > 0) {
+ *ioProxyPort = newPort;
+ } else {
+ // bad port or no port - leave *ioProxyPort unchanged
+ }
+
+ return true;
+}
+
+static char *createUTF8CString(const CFStringRef theString) {
+ if (theString == NULL) return NULL;
+
+ const CFIndex stringLength = CFStringGetLength(theString);
+ const CFIndex bufSize = CFStringGetMaximumSizeForEncoding(stringLength, kCFStringEncodingUTF8) + 1;
+ char *returnVal = (char *)malloc(bufSize);
+
+ if (CFStringGetCString(theString, returnVal, bufSize, kCFStringEncodingUTF8)) {
+ return returnVal;
+ }
+
+ free(returnVal);
+ return NULL;
+}
+
+// Return TRUE if str is a syntactically valid IP address.
+// Using inet_pton() instead of inet_aton() for IPv6 support.
+// len is only a hint; cstr must still be nul-terminated
+static int looksLikeIPAddress(char *cstr, size_t len) {
+ if (len == 0 || (len == 1 && cstr[0] == '.')) return FALSE;
+
+ char dst[16]; // big enough for INET6
+ return (1 == inet_pton(AF_INET, cstr, dst) ||
+ 1 == inet_pton(AF_INET6, cstr, dst));
+}
+
+
+
+// Convert Mac OS X proxy exception entry to Java syntax.
+// See Radar #3441134 for details.
+// Returns NULL if this exception should be ignored by Java.
+// May generate a string with multiple exceptions separated by '|'.
+static char * createConvertedException(CFStringRef cf_original) {
+ // This is done with char* instead of CFString because inet_pton()
+ // needs a C string.
+ char *c_exception = createUTF8CString(cf_original);
+ if (!c_exception) return NULL;
+
+ int c_len = strlen(c_exception);
+
+ // 1. sanitize exception prefix
+ if (c_len >= 1 && 0 == strncmp(c_exception, ".", 1)) {
+ memmove(c_exception, c_exception+1, c_len);
+ c_len -= 1;
+ } else if (c_len >= 2 && 0 == strncmp(c_exception, "*.", 2)) {
+ memmove(c_exception, c_exception+2, c_len-1);
+ c_len -= 2;
+ }
+
+ // 2. pre-reject other exception wildcards
+ if (strchr(c_exception, '*')) {
+ free(c_exception);
+ return NULL;
+ }
+
+ // 3. no IP wildcarding
+ if (looksLikeIPAddress(c_exception, c_len)) {
+ return c_exception;
+ }
+
+ // 4. allow domain suffixes
+ // c_exception is now "str\0" - change to "str|*.str\0"
+ c_exception = reallocf(c_exception, c_len+3+c_len+1);
+ if (!c_exception) return NULL;
+
+ strncpy(c_exception+c_len, "|*.", 3);
+ strncpy(c_exception+c_len+3, c_exception, c_len);
+ c_exception[c_len+3+c_len] = '\0';
+ return c_exception;
+}
+
+/*
+ * Method for fetching the user.home path and storing it in the property list.
+ * For signed .apps running in the Mac App Sandbox, user.home is set to the
+ * app's sandbox container.
+ */
+void setUserHome(java_props_t *sprops) {
+ if (sprops == NULL) { return; }
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ sprops->user_home = createUTF8CString((CFStringRef)NSHomeDirectory());
+ [pool drain];
+}
+
+/*
+ * Method for fetching proxy info and storing it in the property list.
+ */
+void setProxyProperties(java_props_t *sProps) {
+ if (sProps == NULL) return;
+
+ char buf[16]; /* Used for %d of an int - 16 is plenty */
+ CFStringRef
+ cf_httpHost = NULL,
+ cf_httpsHost = NULL,
+ cf_ftpHost = NULL,
+ cf_socksHost = NULL,
+ cf_gopherHost = NULL;
+ int
+ httpPort = 80, // Default proxy port values
+ httpsPort = 443,
+ ftpPort = 21,
+ socksPort = 1080,
+ gopherPort = 70;
+
+ CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL);
+ if (dict == NULL) return;
+
+ /* Read the proxy exceptions list */
+ CFArrayRef cf_list = CFDictionaryGetValue(dict, kSCPropNetProxiesExceptionsList);
+
+ CFMutableStringRef cf_exceptionList = NULL;
+ if (cf_list != NULL) {
+ CFIndex len = CFArrayGetCount(cf_list), idx;
+
+ cf_exceptionList = CFStringCreateMutable(NULL, 0);
+ for (idx = (CFIndex)0; idx < len; idx++) {
+ CFStringRef cf_ehost;
+ if ((cf_ehost = CFArrayGetValueAtIndex(cf_list, idx))) {
+ /* Convert this exception from Mac OS X syntax to Java syntax.
+ See Radar #3441134 for details. This may generate a string
+ with multiple Java exceptions separated by '|'. */
+ char *c_exception = createConvertedException(cf_ehost);
+ if (c_exception) {
+ /* Append the host to the list of exclusions. */
+ if (CFStringGetLength(cf_exceptionList) > 0) {
+ CFStringAppendCString(cf_exceptionList, "|", kCFStringEncodingMacRoman);
+ }
+ CFStringAppendCString(cf_exceptionList, c_exception, kCFStringEncodingMacRoman);
+ free(c_exception);
+ }
+ }
+ }
+ }
+
+ if (cf_exceptionList != NULL) {
+ if (CFStringGetLength(cf_exceptionList) > 0) {
+ sProps->exceptionList = createUTF8CString(cf_exceptionList);
+ }
+ CFRelease(cf_exceptionList);
+ }
+
+#define CHECK_PROXY(protocol, PROTOCOL) \
+ sProps->protocol##ProxyEnabled = \
+ getProxyInfoForProtocol(dict, kSCPropNetProxies##PROTOCOL##Enable, \
+ kSCPropNetProxies##PROTOCOL##Proxy, \
+ kSCPropNetProxies##PROTOCOL##Port, \
+ &cf_##protocol##Host, &protocol##Port); \
+ if (sProps->protocol##ProxyEnabled) { \
+ sProps->protocol##Host = createUTF8CString(cf_##protocol##Host); \
+ snprintf(buf, sizeof(buf), "%d", protocol##Port); \
+ sProps->protocol##Port = malloc(strlen(buf) + 1); \
+ strcpy(sProps->protocol##Port, buf); \
+ }
+
+ CHECK_PROXY(http, HTTP);
+ CHECK_PROXY(https, HTTPS);
+ CHECK_PROXY(ftp, FTP);
+ CHECK_PROXY(socks, SOCKS);
+ CHECK_PROXY(gopher, Gopher);
+
+#undef CHECK_PROXY
+
+ CFRelease(dict);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/macosx/native/libjava/java_props_macosx.h Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "java_props.h"
+
+char *setupMacOSXLocale(int cat);
+void setOSNameAndVersion(java_props_t *sprops);
+void setUserHome(java_props_t *sprops);
+void setProxyProperties(java_props_t *sProps);
+int isInAquaSession();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/macosx/native/libnet/bsd_close.c Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/poll.h>
+
+/*
+ * Stack allocated by thread when doing blocking operation
+ */
+typedef struct threadEntry {
+ pthread_t thr; /* this thread */
+ struct threadEntry *next; /* next thread */
+ int intr; /* interrupted */
+} threadEntry_t;
+
+/*
+ * Heap allocated during initialized - one entry per fd
+ */
+typedef struct {
+ pthread_mutex_t lock; /* fd lock */
+ threadEntry_t *threads; /* threads blocked on fd */
+} fdEntry_t;
+
+/*
+ * Signal to unblock thread
+ */
+static int sigWakeup = SIGIO;
+
+/*
+ * The fd table and the number of file descriptors
+ */
+static fdEntry_t *fdTable;
+static int fdCount;
+
+/*
+ * This limit applies if getlimit() returns unlimited.
+ * Unfortunately, this means if someone wants a higher limit
+ * then they have to set an explicit limit, higher than this,
+ * which is probably counter-intuitive.
+ */
+#define MAX_FD_COUNT 4096
+
+/*
+ * Null signal handler
+ */
+static void sig_wakeup(int sig) {
+}
+
+/*
+ * Initialization routine (executed when library is loaded)
+ * Allocate fd tables and sets up signal handler.
+ */
+static void __attribute((constructor)) init() {
+ struct rlimit nbr_files;
+ sigset_t sigset;
+ struct sigaction sa;
+ int i;
+
+ /*
+ * Allocate table based on the maximum number of
+ * file descriptors.
+ */
+ getrlimit(RLIMIT_NOFILE, &nbr_files);
+ if (nbr_files.rlim_max == RLIM_INFINITY) {
+ fdCount = MAX_FD_COUNT;
+ } else {
+ fdCount = nbr_files.rlim_max;
+ }
+ fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
+ if (fdTable == NULL) {
+ fprintf(stderr, "library initialization failed - "
+ "unable to allocate file descriptor table - out of memory");
+ abort();
+ }
+ for (i=0; i<fdCount; i++) {
+ pthread_mutex_init(&fdTable[i].lock, NULL);
+ }
+
+ /*
+ * Setup the signal handler
+ */
+ sa.sa_handler = sig_wakeup;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sigaction(sigWakeup, &sa, NULL);
+
+ sigemptyset(&sigset);
+ sigaddset(&sigset, sigWakeup);
+ sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+}
+
+/*
+ * Return the fd table for this fd or NULL is fd out
+ * of range.
+ */
+static inline fdEntry_t *getFdEntry(int fd)
+{
+ if (fd < 0 || fd >= fdCount) {
+ return NULL;
+ }
+ return &fdTable[fd];
+}
+
+/*
+ * Start a blocking operation :-
+ * Insert thread onto thread list for the fd.
+ */
+static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self)
+{
+ self->thr = pthread_self();
+ self->intr = 0;
+
+ pthread_mutex_lock(&(fdEntry->lock));
+ {
+ self->next = fdEntry->threads;
+ fdEntry->threads = self;
+ }
+ pthread_mutex_unlock(&(fdEntry->lock));
+}
+
+/*
+ * End a blocking operation :-
+ * Remove thread from thread list for the fd
+ * If fd has been interrupted then set errno to EBADF
+ */
+static inline void endOp
+ (fdEntry_t *fdEntry, threadEntry_t *self)
+{
+ int orig_errno = errno;
+ pthread_mutex_lock(&(fdEntry->lock));
+ {
+ threadEntry_t *curr, *prev=NULL;
+ curr = fdEntry->threads;
+ while (curr != NULL) {
+ if (curr == self) {
+ if (curr->intr) {
+ orig_errno = EBADF;
+ }
+ if (prev == NULL) {
+ fdEntry->threads = curr->next;
+ } else {
+ prev->next = curr->next;
+ }
+ break;
+ }
+ prev = curr;
+ curr = curr->next;
+ }
+ }
+ pthread_mutex_unlock(&(fdEntry->lock));
+ errno = orig_errno;
+}
+
+/*
+ * Close or dup2 a file descriptor ensuring that all threads blocked on
+ * the file descriptor are notified via a wakeup signal.
+ *
+ * fd1 < 0 => close(fd2)
+ * fd1 >= 0 => dup2(fd1, fd2)
+ *
+ * Returns -1 with errno set if operation fails.
+ */
+static int closefd(int fd1, int fd2) {
+ int rv, orig_errno;
+ fdEntry_t *fdEntry = getFdEntry(fd2);
+ if (fdEntry == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ /*
+ * Lock the fd to hold-off additional I/O on this fd.
+ */
+ pthread_mutex_lock(&(fdEntry->lock));
+
+ {
+ /*
+ * Send a wakeup signal to all threads blocked on this
+ * file descriptor.
+ */
+ threadEntry_t *curr = fdEntry->threads;
+ while (curr != NULL) {
+ curr->intr = 1;
+ pthread_kill( curr->thr, sigWakeup );
+ curr = curr->next;
+ }
+
+ /*
+ * And close/dup the file descriptor
+ * (restart if interrupted by signal)
+ */
+ do {
+ if (fd1 < 0) {
+ rv = close(fd2);
+ } else {
+ rv = dup2(fd1, fd2);
+ }
+ } while (rv == -1 && errno == EINTR);
+
+ }
+
+ /*
+ * Unlock without destroying errno
+ */
+ orig_errno = errno;
+ pthread_mutex_unlock(&(fdEntry->lock));
+ errno = orig_errno;
+
+ return rv;
+}
+
+/*
+ * Wrapper for dup2 - same semantics as dup2 system call except
+ * that any threads blocked in an I/O system call on fd2 will be
+ * preempted and return -1/EBADF;
+ */
+int NET_Dup2(int fd, int fd2) {
+ if (fd < 0) {
+ errno = EBADF;
+ return -1;
+ }
+ return closefd(fd, fd2);
+}
+
+/*
+ * Wrapper for close - same semantics as close system call
+ * except that any threads blocked in an I/O on fd will be
+ * preempted and the I/O system call will return -1/EBADF.
+ */
+int NET_SocketClose(int fd) {
+ return closefd(-1, fd);
+}
+
+/************** Basic I/O operations here ***************/
+
+/*
+ * Macro to perform a blocking IO operation. Restarts
+ * automatically if interrupted by signal (other than
+ * our wakeup signal)
+ */
+#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
+ int ret; \
+ threadEntry_t self; \
+ fdEntry_t *fdEntry = getFdEntry(FD); \
+ if (fdEntry == NULL) { \
+ errno = EBADF; \
+ return -1; \
+ } \
+ do { \
+ startOp(fdEntry, &self); \
+ ret = FUNC; \
+ endOp(fdEntry, &self); \
+ } while (ret == -1 && errno == EINTR); \
+ return ret; \
+}
+
+int NET_Read(int s, void* buf, size_t len) {
+ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
+}
+
+int NET_ReadV(int s, const struct iovec * vector, int count) {
+ BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
+}
+
+int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
+ struct sockaddr *from, socklen_t *fromlen) {
+ BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, fromlen) );
+}
+
+int NET_Send(int s, void *msg, int len, unsigned int flags) {
+ BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
+}
+
+int NET_WriteV(int s, const struct iovec * vector, int count) {
+ BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) );
+}
+
+int NET_SendTo(int s, const void *msg, int len, unsigned int
+ flags, const struct sockaddr *to, int tolen) {
+ BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) );
+}
+
+int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) {
+ BLOCKING_IO_RETURN_INT( s, accept(s, addr, addrlen) );
+}
+
+int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
+ BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
+}
+
+int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
+ BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
+}
+
+/*
+ * Wrapper for select(s, timeout). We are using select() on Mac OS due to Bug 7131399.
+ * Auto restarts with adjusted timeout if interrupted by
+ * signal other than our wakeup signal.
+ */
+int NET_Timeout(int s, long timeout) {
+ long prevtime = 0, newtime;
+ struct timeval t, *tp = &t;
+ fd_set fds;
+ fd_set* fdsp = NULL;
+ int allocated = 0;
+ threadEntry_t self;
+ fdEntry_t *fdEntry = getFdEntry(s);
+
+ /*
+ * Check that fd hasn't been closed.
+ */
+ if (fdEntry == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ /*
+ * Pick up current time as may need to adjust timeout
+ */
+ if (timeout > 0) {
+ /* Timed */
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ prevtime = now.tv_sec * 1000 + now.tv_usec / 1000;
+ t.tv_sec = timeout / 1000;
+ t.tv_usec = (timeout % 1000) * 1000;
+ } else if (timeout < 0) {
+ /* Blocking */
+ tp = 0;
+ } else {
+ /* Poll */
+ t.tv_sec = 0;
+ t.tv_usec = 0;
+ }
+
+ if (s < FD_SETSIZE) {
+ fdsp = &fds;
+ FD_ZERO(fdsp);
+ } else {
+ int length = (howmany(s+1, NFDBITS)) * sizeof(int);
+ fdsp = (fd_set *) calloc(1, length);
+ if (fdsp == NULL) {
+ return -1; // errno will be set to ENOMEM
+ }
+ allocated = 1;
+ }
+ FD_SET(s, fdsp);
+
+ for(;;) {
+ int rv;
+
+ /*
+ * call select on the fd. If interrupted by our wakeup signal
+ * errno will be set to EBADF.
+ */
+
+ startOp(fdEntry, &self);
+ rv = select(s+1, fdsp, 0, 0, tp);
+ endOp(fdEntry, &self);
+
+ /*
+ * If interrupted then adjust timeout. If timeout
+ * has expired return 0 (indicating timeout expired).
+ */
+ if (rv < 0 && errno == EINTR) {
+ if (timeout > 0) {
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ newtime = now.tv_sec * 1000 + now.tv_usec / 1000;
+ timeout -= newtime - prevtime;
+ if (timeout <= 0) {
+ if (allocated != 0)
+ free(fdsp);
+ return 0;
+ }
+ prevtime = newtime;
+ t.tv_sec = timeout / 1000;
+ t.tv_usec = (timeout % 1000) * 1000;
+ }
+ } else {
+ if (allocated != 0)
+ free(fdsp);
+ return rv;
+ }
+
+ }
+}
--- a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,9 @@
import sun.misc.FloatingDecimal;
import java.util.Arrays;
+import java.util.Spliterator;
+import java.util.stream.IntStream;
+import java.util.stream.StreamSupport;
/**
* A mutable sequence of characters.
@@ -292,7 +295,7 @@
if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
throw new IndexOutOfBoundsException();
}
- return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex);
+ return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
}
/**
@@ -1432,6 +1435,34 @@
public abstract String toString();
/**
+ * {@inheritDoc}
+ * @since 1.9
+ */
+ @Override
+ public IntStream chars() {
+ // Reuse String-based spliterator. This requires a supplier to
+ // capture the value and count when the terminal operation is executed
+ return StreamSupport.intStream(
+ () -> new String.IntCharArraySpliterator(value, 0, count, 0),
+ Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED,
+ false);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @since 1.9
+ */
+ @Override
+ public IntStream codePoints() {
+ // Reuse String-based spliterator. This requires a supplier to
+ // capture the value and count when the terminal operation is executed
+ return StreamSupport.intStream(
+ () -> new String.CodePointsSpliterator(value, 0, count, 0),
+ Spliterator.ORDERED,
+ false);
+ }
+
+ /**
* Needed by {@code String} for the contentEquals method.
*/
final char[] getValue() {
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Thu Jan 29 03:54:45 2015 +0000
@@ -149,7 +149,8 @@
* {@code getName}. If this {@code Class} object represents a
* primitive type, this method returns the name of the primitive type. If
* this {@code Class} object represents void this method returns
- * "void".
+ * "void". If this {@code Class} object represents an array type,
+ * this method returns "class " followed by {@code getName}.
*
* @return a string representation of this class object.
*/
@@ -174,6 +175,12 @@
* occur in canonical order. If there are no type parameters, the
* type parameter list is elided.
*
+ * For an array type, the string starts with the type name,
+ * followed by an angle-bracketed comma-separated list of the
+ * type's type parameters, if any, followed by a sequence of
+ * {@code []} characters, one set of brackets per dimension of
+ * the array.
+ *
* <p>Note that since information about the runtime representation
* of a type is being generated, modifiers not present on the
* originating source code or illegal on the originating source
@@ -189,29 +196,39 @@
return toString();
} else {
StringBuilder sb = new StringBuilder();
-
- // Class modifiers are a superset of interface modifiers
- int modifiers = getModifiers() & Modifier.classModifiers();
- if (modifiers != 0) {
- sb.append(Modifier.toString(modifiers));
+ Class<?> component = this;
+ int arrayDepth = 0;
+
+ if (isArray()) {
+ do {
+ arrayDepth++;
+ component = component.getComponentType();
+ } while (component.isArray());
+ sb.append(component.getName());
+ } else {
+ // Class modifiers are a superset of interface modifiers
+ int modifiers = getModifiers() & Modifier.classModifiers();
+ if (modifiers != 0) {
+ sb.append(Modifier.toString(modifiers));
+ sb.append(' ');
+ }
+
+ if (isAnnotation()) {
+ sb.append('@');
+ }
+ if (isInterface()) { // Note: all annotation types are interfaces
+ sb.append("interface");
+ } else {
+ if (isEnum())
+ sb.append("enum");
+ else
+ sb.append("class");
+ }
sb.append(' ');
- }
-
- if (isAnnotation()) {
- sb.append('@');
+ sb.append(getName());
}
- if (isInterface()) { // Note: all annotation types are interfaces
- sb.append("interface");
- } else {
- if (isEnum())
- sb.append("enum");
- else
- sb.append("class");
- }
- sb.append(' ');
- sb.append(getName());
-
- TypeVariable<?>[] typeparms = getTypeParameters();
+
+ TypeVariable<?>[] typeparms = component.getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
sb.append('<');
@@ -224,6 +241,9 @@
sb.append('>');
}
+ for (int i = 0; i < arrayDepth; i++)
+ sb.append("[]");
+
return sb.toString();
}
}
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1360,7 +1360,10 @@
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- checkClassLoaderPermission(this, Reflection.getCallerClass());
+ // Check access to the parent class loader
+ // If the caller's class loader is same as this class loader,
+ // permission check is performed.
+ checkClassLoaderPermission(parent, Reflection.getCallerClass());
}
return parent;
}
@@ -1503,6 +1506,11 @@
return caller.getClassLoader0();
}
+ /*
+ * Checks RuntimePermission("getClassLoader") permission
+ * if caller's class loader is not null and caller's class loader
+ * is not the same as or an ancestor of the given cl argument.
+ */
static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
@@ -1747,35 +1755,54 @@
private static String usr_paths[];
private static String sys_paths[];
- private static String[] initializePath(String propname) {
- String ldpath = System.getProperty(propname, "");
- String ps = File.pathSeparator;
- int ldlen = ldpath.length();
- int i, j, n;
- // Count the separators in the path
- i = ldpath.indexOf(ps);
- n = 0;
- while (i >= 0) {
- n++;
- i = ldpath.indexOf(ps, i + 1);
+ private static String[] initializePath(String propName) {
+ String ldPath = System.getProperty(propName, "");
+ int ldLen = ldPath.length();
+ char ps = File.pathSeparatorChar;
+ int psCount = 0;
+
+ if (ClassLoaderHelper.allowsQuotedPathElements &&
+ ldPath.indexOf('\"') >= 0) {
+ // First, remove quotes put around quoted parts of paths.
+ // Second, use a quotation mark as a new path separator.
+ // This will preserve any quoted old path separators.
+ char[] buf = new char[ldLen];
+ int bufLen = 0;
+ for (int i = 0; i < ldLen; ++i) {
+ char ch = ldPath.charAt(i);
+ if (ch == '\"') {
+ while (++i < ldLen &&
+ (ch = ldPath.charAt(i)) != '\"') {
+ buf[bufLen++] = ch;
+ }
+ } else {
+ if (ch == ps) {
+ psCount++;
+ ch = '\"';
+ }
+ buf[bufLen++] = ch;
+ }
+ }
+ ldPath = new String(buf, 0, bufLen);
+ ldLen = bufLen;
+ ps = '\"';
+ } else {
+ for (int i = ldPath.indexOf(ps); i >= 0;
+ i = ldPath.indexOf(ps, i + 1)) {
+ psCount++;
+ }
}
- // allocate the array of paths - n :'s = n + 1 path elements
- String[] paths = new String[n + 1];
-
- // Fill the array with paths from the ldpath
- n = i = 0;
- j = ldpath.indexOf(ps);
- while (j >= 0) {
- if (j - i > 0) {
- paths[n++] = ldpath.substring(i, j);
- } else if (j - i == 0) {
- paths[n++] = ".";
- }
- i = j + 1;
- j = ldpath.indexOf(ps, i);
+ String[] paths = new String[psCount + 1];
+ int pathStart = 0;
+ for (int j = 0; j < psCount; ++j) {
+ int pathEnd = ldPath.indexOf(ps, pathStart);
+ paths[j] = (pathStart < pathEnd) ?
+ ldPath.substring(pathStart, pathEnd) : ".";
+ pathStart = pathEnd + 1;
}
- paths[n] = ldpath.substring(i, ldlen);
+ paths[psCount] = (pathStart < ldLen) ?
+ ldPath.substring(pathStart, ldLen) : ".";
return paths;
}
--- a/jdk/src/java.base/share/classes/java/lang/String.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/String.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,14 @@
import java.util.Formatter;
import java.util.Locale;
import java.util.Objects;
+import java.util.Spliterator;
import java.util.StringJoiner;
+import java.util.function.IntConsumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
+import java.util.stream.IntStream;
+import java.util.stream.StreamSupport;
/**
* The {@code String} class represents character strings. All
@@ -2894,6 +2898,180 @@
return this;
}
+ static class IntCharArraySpliterator implements Spliterator.OfInt {
+ private final char[] array;
+ private int index; // current index, modified on advance/split
+ private final int fence; // one past last index
+ private final int cs;
+
+ IntCharArraySpliterator(char[] array, int acs) {
+ this(array, 0, array.length, acs);
+ }
+
+ IntCharArraySpliterator(char[] array, int origin, int fence, int acs) {
+ this.array = array;
+ this.index = origin;
+ this.fence = fence;
+ this.cs = acs | Spliterator.ORDERED | Spliterator.SIZED
+ | Spliterator.SUBSIZED;
+ }
+
+ @Override
+ public OfInt trySplit() {
+ int lo = index, mid = (lo + fence) >>> 1;
+ return (lo >= mid)
+ ? null
+ : new IntCharArraySpliterator(array, lo, index = mid, cs);
+ }
+
+ @Override
+ public void forEachRemaining(IntConsumer action) {
+ char[] a; int i, hi; // hoist accesses and checks from loop
+ if (action == null)
+ throw new NullPointerException();
+ if ((a = array).length >= (hi = fence) &&
+ (i = index) >= 0 && i < (index = hi)) {
+ do { action.accept(a[i]); } while (++i < hi);
+ }
+ }
+
+ @Override
+ public boolean tryAdvance(IntConsumer action) {
+ if (action == null)
+ throw new NullPointerException();
+ if (index >= 0 && index < fence) {
+ action.accept(array[index++]);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public long estimateSize() { return (long)(fence - index); }
+
+ @Override
+ public int characteristics() {
+ return cs;
+ }
+ }
+
+ /**
+ * Returns a stream of {@code int} zero-extending the {@code char} values
+ * from this sequence. Any char which maps to a <a
+ * href="{@docRoot}/java/lang/Character.html#unicode">surrogate code
+ * point</a> is passed through uninterpreted.
+ *
+ * @return an IntStream of char values from this sequence
+ * @since 1.9
+ */
+ @Override
+ public IntStream chars() {
+ return StreamSupport.intStream(
+ new IntCharArraySpliterator(value, Spliterator.IMMUTABLE), false);
+ }
+
+ static class CodePointsSpliterator implements Spliterator.OfInt {
+ private final char[] array;
+ private int index; // current index, modified on advance/split
+ private final int fence; // one past last index
+ private final int cs;
+
+ CodePointsSpliterator(char[] array, int acs) {
+ this(array, 0, array.length, acs);
+ }
+
+ CodePointsSpliterator(char[] array, int origin, int fence, int acs) {
+ this.array = array;
+ this.index = origin;
+ this.fence = fence;
+ this.cs = acs | Spliterator.ORDERED;
+ }
+
+ @Override
+ public OfInt trySplit() {
+ int lo = index, mid = (lo + fence) >>> 1;
+ if (lo >= mid)
+ return null;
+
+ int midOneLess;
+ // If the mid-point intersects a surrogate pair
+ if (Character.isLowSurrogate(array[mid]) &&
+ Character.isHighSurrogate(array[midOneLess = (mid -1)])) {
+ // If there is only one pair it cannot be split
+ if (lo >= midOneLess)
+ return null;
+ // Shift the mid-point to align with the surrogate pair
+ return new CodePointsSpliterator(array, lo, index = midOneLess, cs);
+ }
+ return new CodePointsSpliterator(array, lo, index = mid, cs);
+ }
+
+ @Override
+ public void forEachRemaining(IntConsumer action) {
+ char[] a; int i, hi; // hoist accesses and checks from loop
+ if (action == null)
+ throw new NullPointerException();
+ if ((a = array).length >= (hi = fence) &&
+ (i = index) >= 0 && i < (index = hi)) {
+ do {
+ i = advance(a, i, hi, action);
+ } while (i < hi);
+ }
+ }
+
+ @Override
+ public boolean tryAdvance(IntConsumer action) {
+ if (action == null)
+ throw new NullPointerException();
+ if (index >= 0 && index < fence) {
+ index = advance(array, index, fence, action);
+ return true;
+ }
+ return false;
+ }
+
+ // Advance one code point from the index, i, and return the next
+ // index to advance from
+ private static int advance(char[] a, int i, int hi, IntConsumer action) {
+ char c1 = a[i++];
+ int cp = c1;
+ if (Character.isHighSurrogate(c1) && i < hi) {
+ char c2 = a[i];
+ if (Character.isLowSurrogate(c2)) {
+ i++;
+ cp = Character.toCodePoint(c1, c2);
+ }
+ }
+ action.accept(cp);
+ return i;
+ }
+
+ @Override
+ public long estimateSize() { return (long)(fence - index); }
+
+ @Override
+ public int characteristics() {
+ return cs;
+ }
+ }
+
+ /**
+ * Returns a stream of code point values from this sequence. Any surrogate
+ * pairs encountered in the sequence are combined as if by {@linkplain
+ * Character#toCodePoint Character.toCodePoint} and the result is passed
+ * to the stream. Any other code units, including ordinary BMP characters,
+ * unpaired surrogates, and undefined code units, are zero-extended to
+ * {@code int} values which are then passed to the stream.
+ *
+ * @return an IntStream of Unicode code points from this sequence
+ * @since 1.9
+ */
+ @Override
+ public IntStream codePoints() {
+ return StreamSupport.intStream(
+ new CodePointsSpliterator(value, Spliterator.IMMUTABLE), false);
+ }
+
/**
* Converts this string to a new character array.
*
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Class<? extends Annotation>, Annotation> declaredAnnotations;
+ private transient volatile Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
- private synchronized Map<Class<? extends Annotation>, 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<Class<? extends Annotation>, Annotation> declaredAnnotations() {
+ Map<Class<? extends Annotation>, 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;
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Class<? extends Annotation>, Annotation> declaredAnnotations;
+ private transient volatile Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
- private synchronized Map<Class<? extends Annotation>, 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<Class<? extends Annotation>, Annotation> declaredAnnotations() {
+ Map<Class<? extends Annotation>, 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();
--- a/jdk/src/java.base/share/classes/java/net/MulticastSocket.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/net/MulticastSocket.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -569,7 +569,7 @@
public NetworkInterface getNetworkInterface() throws SocketException {
NetworkInterface ni
= (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
- if (ni.getIndex() == 0) {
+ if ((ni.getIndex() == 0) || (ni.getIndex() == -1)) {
InetAddress[] addrs = new InetAddress[1];
addrs[0] = InetAddress.anyLocalAddress();
return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
--- a/jdk/src/java.base/share/classes/java/net/URI.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/net/URI.java Thu Jan 29 03:54:45 2015 +0000
@@ -2637,6 +2637,11 @@
private static final long H_URIC_NO_SLASH
= H_UNRESERVED | H_ESCAPED | highMask(";?:@&=+$,");
+ // scope_id = alpha | digit | "_" | "."
+ private static final long L_SCOPE_ID
+ = L_ALPHANUM | lowMask("_.");
+ private static final long H_SCOPE_ID
+ = H_ALPHANUM | highMask("_.");
// -- Escaping and encoding --
@@ -3226,7 +3231,7 @@
if (r+1 == q) {
fail ("scope id expected");
}
- checkChars (r+1, q, L_ALPHANUM, H_ALPHANUM,
+ checkChars (r+1, q, L_SCOPE_ID, H_SCOPE_ID,
"scope id");
} else {
parseIPv6Reference(p, q);
--- a/jdk/src/java.base/share/classes/java/nio/channels/Channels.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/nio/channels/Channels.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -579,12 +579,13 @@
* charset and writes the resulting bytes to the given channel.
*
* <p> An invocation of this method of the form
- * <p>
+ *
* <pre> {@code
* Channels.newWriter(ch, csname)
* } </pre>
+ *
* behaves in exactly the same way as the expression
- * <p>
+ *
* <pre> {@code
* Channels.newWriter(ch, Charset.forName(csName).newEncoder(), -1)
* } </pre>
--- a/jdk/src/java.base/share/classes/java/util/Formatter.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/util/Formatter.java Thu Jan 29 03:54:45 2015 +0000
@@ -1836,7 +1836,7 @@
* <p> The maximum number of arguments is limited by the maximum dimension of a
* Java array as defined by
* <cite>The Java™ Virtual Machine Specification</cite>.
- * If the argument index is does not correspond to an
+ * If the argument index does not correspond to an
* available argument, then a {@link MissingFormatArgumentException} is thrown.
*
* <p> If there are more arguments than format specifiers, the extra arguments
--- a/jdk/src/java.base/share/classes/java/util/Hashtable.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/util/Hashtable.java Thu Jan 29 03:54:45 2015 +0000
@@ -1137,10 +1137,10 @@
Entry<Object, Object> entryStack = null;
synchronized (this) {
- // Write out the length, threshold, loadfactor
+ // Write out the threshold and loadFactor
s.defaultWriteObject();
- // Write out length, count of elements
+ // Write out the length and count of elements
s.writeInt(table.length);
s.writeInt(count);
@@ -1169,22 +1169,33 @@
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException
{
- // Read in the length, threshold, and loadfactor
+ // Read in the threshold and loadFactor
s.defaultReadObject();
+ // Validate loadFactor (ignore threshold - it will be re-computed)
+ if (loadFactor <= 0 || Float.isNaN(loadFactor))
+ throw new StreamCorruptedException("Illegal Load: " + loadFactor);
+
// Read the original length of the array and number of elements
int origlength = s.readInt();
int elements = s.readInt();
- // Compute new size with a bit of room 5% to grow but
- // no larger than the original size. Make the length
+ // Validate # of elements
+ if (elements < 0)
+ throw new StreamCorruptedException("Illegal # of Elements: " + elements);
+
+ // Clamp original length to be more than elements / loadFactor
+ // (this is the invariant enforced with auto-growth)
+ origlength = Math.max(origlength, (int)(elements / loadFactor) + 1);
+
+ // Compute new length with a bit of room 5% + 3 to grow but
+ // no larger than the clamped original length. Make the length
// odd if it's large enough, this helps distribute the entries.
// Guard against the length ending up zero, that's not valid.
- int length = (int)(elements * loadFactor) + (elements / 20) + 3;
+ int length = (int)((elements + elements / 20) / loadFactor) + 3;
if (length > elements && (length & 1) == 0)
length--;
- if (origlength > 0 && length > origlength)
- length = origlength;
+ length = Math.min(length, origlength);
table = new Entry<?,?>[length];
threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
count = 0;
@@ -1195,7 +1206,7 @@
K key = (K)s.readObject();
@SuppressWarnings("unchecked")
V value = (V)s.readObject();
- // synch could be eliminated for performance
+ // sync is eliminated for performance
reconstitutionPut(table, key, value);
}
}
@@ -1207,9 +1218,9 @@
*
* <p>This differs from the regular put method in several ways. No
* checking for rehashing is necessary since the number of elements
- * initially in the table is known. The modCount is not incremented
- * because we are creating a new instance. Also, no return value
- * is needed.
+ * initially in the table is known. The modCount is not incremented and
+ * there's no synchronization because we are creating a new instance.
+ * Also, no return value is needed.
*/
private void reconstitutionPut(Entry<?,?>[] tab, K key, V value)
throws StreamCorruptedException
--- a/jdk/src/java.base/share/classes/java/util/Spliterator.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/util/Spliterator.java Thu Jan 29 03:54:45 2015 +0000
@@ -125,7 +125,7 @@
* are encountered.
*
* @apiNote
- * <p>Spliterators, like {@code Iterators}s, are for traversing the elements of
+ * <p>Spliterators, like {@code Iterator}s, are for traversing the elements of
* a source. The {@code Spliterator} API was designed to support efficient
* parallel traversal in addition to sequential traversal, by supporting
* decomposition as well as single-element iteration. In addition, the
@@ -553,6 +553,12 @@
* sub-split size is known and additions or removals to the source are not
* reflected when traversing.
*
+ * <p>A top-level Spliterator should not report both {@code CONCURRENT} and
+ * {@code IMMUTABLE}, since they are mutually exclusive. Such a Spliterator
+ * is inconsistent and no guarantees can be made about any computation using
+ * that Spliterator. Sub-spliterators may report {@code IMMUTABLE} if
+ * additions or removals to the source are not reflected when traversing.
+ *
* @apiNote Most concurrent collections maintain a consistency policy
* guaranteeing accuracy with respect to elements present at the point of
* Spliterator construction, but possibly not reflecting subsequent
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Thu Jan 29 03:54:45 2015 +0000
@@ -978,7 +978,15 @@
}
try {
@SuppressWarnings("unchecked") T t = (T) r;
- return f.apply(t).toCompletableFuture();
+ CompletableFuture<V> g = f.apply(t).toCompletableFuture();
+ Object s = g.result;
+ if (s != null)
+ return new CompletableFuture<V>(encodeRelay(s));
+ CompletableFuture<V> d = new CompletableFuture<V>();
+ UniRelay<V> copy = new UniRelay<V>(d, g);
+ g.push(copy);
+ copy.tryFire(SYNC);
+ return d;
} catch (Throwable ex) {
return new CompletableFuture<V>(encodeThrowable(ex));
}
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu Jan 29 03:54:45 2015 +0000
@@ -337,6 +337,7 @@
/* try auth without calling Authenticator. Used for transparent NTLM authentication */
private boolean tryTransparentNTLMServer = true;
private boolean tryTransparentNTLMProxy = true;
+ private boolean useProxyResponseCode = false;
/* Used by Windows specific code */
private Object authObj;
@@ -2239,6 +2240,15 @@
if (tryTransparentNTLMProxy) {
tryTransparentNTLMProxy =
NTLMAuthenticationProxy.supportsTransparentAuth;
+ /* If the platform supports transparent authentication
+ * then normally it's ok to do transparent auth to a proxy
+ * because we generally trust proxies (chosen by the user)
+ * But not in the case of 305 response where the server
+ * chose it. */
+ if (tryTransparentNTLMProxy && useProxyResponseCode) {
+ tryTransparentNTLMProxy = false;
+ }
+
}
a = null;
if (tryTransparentNTLMProxy) {
@@ -2610,6 +2620,10 @@
requests.set(0, method + " " + getRequestURI()+" " +
httpVersion, null);
connected = true;
+ // need to remember this in case NTLM proxy authentication gets
+ // used. We can't use transparent authentication when user
+ // doesn't know about proxy.
+ useProxyResponseCode = true;
} else {
// maintain previous headers, just change the name
// of the file we're getting
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java Thu Jan 29 03:54:45 2015 +0000
@@ -192,22 +192,6 @@
return userAgent;
}
- // should remove once HttpClient.newHttpProxy is putback
- private static Proxy newHttpProxy(String proxyHost, int proxyPort) {
- InetSocketAddress saddr = null;
- final String phost = proxyHost;
- final int pport = proxyPort < 0 ? httpsPortNumber : proxyPort;
- try {
- saddr = java.security.AccessController.doPrivileged(new
- java.security.PrivilegedExceptionAction<InetSocketAddress>() {
- public InetSocketAddress run() {
- return new InetSocketAddress(phost, pport);
- }});
- } catch (java.security.PrivilegedActionException pae) {
- }
- return new Proxy(Proxy.Type.HTTP, saddr);
- }
-
// CONSTRUCTOR, FACTORY
@@ -251,7 +235,7 @@
throws IOException {
this(sf, url,
(proxyHost == null? null:
- HttpsClient.newHttpProxy(proxyHost, proxyPort)),
+ HttpClient.newHttpProxy(proxyHost, proxyPort, "https")),
connectTimeout);
}
@@ -261,6 +245,11 @@
HttpsClient(SSLSocketFactory sf, URL url, Proxy proxy,
int connectTimeout)
throws IOException {
+ PlatformLogger logger = HttpURLConnection.getHttpLogger();
+ if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
+ logger.finest("Creating new HttpsClient with url:" + url + " and proxy:" + proxy +
+ " with connect timeout:" + connectTimeout);
+ }
this.proxy = proxy;
setSSLSocketFactory(sf);
this.proxyDisabled = true;
@@ -317,7 +306,7 @@
return HttpsClient.New(sf, url, hv,
(proxyHost == null? null :
- HttpsClient.newHttpProxy(proxyHost, proxyPort)),
+ HttpClient.newHttpProxy(proxyHost, proxyPort, "https")),
useCache, connectTimeout, httpuc);
}
@@ -329,6 +318,11 @@
if (p == null) {
p = Proxy.NO_PROXY;
}
+ PlatformLogger logger = HttpURLConnection.getHttpLogger();
+ if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
+ logger.finest("Looking for HttpClient for URL " + url +
+ " and proxy value of " + p);
+ }
HttpsClient ret = null;
if (useCache) {
/* see if one's already around */
@@ -342,14 +336,13 @@
if (ret != null) {
if ((ret.proxy != null && ret.proxy.equals(p)) ||
- (ret.proxy == null && p == null)) {
+ (ret.proxy == null && p == Proxy.NO_PROXY)) {
synchronized (ret) {
ret.cachedHttpClient = true;
assert ret.inCache;
ret.inCache = false;
if (httpuc != null && ret.needsTunneling())
httpuc.setTunnelState(TUNNELING);
- PlatformLogger logger = HttpURLConnection.getHttpLogger();
if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
logger.finest("KeepAlive stream retrieved from the cache, " + ret);
}
@@ -360,6 +353,9 @@
// This should be fine as it is very rare that a connection
// to the same host will not use the same proxy.
synchronized(ret) {
+ if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
+ logger.finest("Not returning this connection to cache: " + ret);
+ }
ret.inCache = false;
ret.closeServer();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/FileInputStreamPool.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,159 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.provider;
+
+import java.io.*;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * A pool of {@code InputStream}s opened from distinct files. Only a single
+ * instance is ever opened from the same file. This is used to read special
+ * infinite files like {@code /dev/random} where the current file pointer is not
+ * relevant, so multiple readers can share the same file descriptor and
+ * consequently the same {@code InputStream}.
+ */
+class FileInputStreamPool {
+
+ /**
+ * a pool of: StreamRef -> UnclosableInputStream -> FileInputStream(s)
+ */
+ private static final ConcurrentMap<File, StreamRef> pool =
+ new ConcurrentHashMap<>();
+
+ /**
+ * a reference queue of cleared StreamRef(s)
+ */
+ private static final ReferenceQueue<UnclosableInputStream> refQueue =
+ new ReferenceQueue<>();
+
+ /**
+ * This method opens an underlying {@link java.io.FileInputStream} for a
+ * given {@code file} and returns a wrapper over it. The wrapper is shared
+ * among multiple readers of the same {@code file} and ignores
+ * {@link java.io.InputStream#close()} requests. The underlying stream is
+ * closed when all references to the wrapper are relinquished.
+ *
+ * @param file the file to be opened for reading.
+ * @return a shared {@link java.io.InputStream} instance opened from given
+ * file.
+ * @throws FileNotFoundException if the file does not exist, is a directory
+ * rather than a regular file, or for some
+ * other reason cannot be opened for reading.
+ * @throws SecurityException if a security manager exists and its
+ * <code>checkRead</code> method denies read
+ * access to the file.
+ */
+ static InputStream getInputStream(File file) throws IOException {
+
+ // expunge any cleared references
+ StreamRef oldRref;
+ while ((oldRref = (StreamRef) refQueue.poll()) != null) {
+ pool.remove(oldRref.file, oldRref);
+ }
+
+ // canonicalize the path
+ // (this also checks the read permission on the file if SecurityManager
+ // is present, so no checking is needed later when we just return the
+ // already opened stream)
+ File cfile = file.getCanonicalFile();
+
+ // check if it exists in pool
+ oldRref = pool.get(cfile);
+ UnclosableInputStream oldStream = (oldRref == null)
+ ? null
+ : oldRref.get();
+ StreamRef newRef = null;
+ UnclosableInputStream newStream = null;
+
+ // retry loop
+ while (true) {
+ if (oldStream != null) {
+ // close our optimistically opened stream 1st (if we opened it)
+ if (newStream != null) {
+ try {
+ newStream.getWrappedStream().close();
+ } catch (IOException ignore) {
+ // can't do anything here
+ }
+ }
+ // return it
+ return oldStream;
+ } else {
+ // we need to open new stream optimistically (if not already)
+ if (newStream == null) {
+ newStream = new UnclosableInputStream(
+ new FileInputStream(cfile));
+ newRef = new StreamRef(cfile, newStream, refQueue);
+ }
+ // either try to install newRef or replace oldRef with newRef
+ if (oldRref == null) {
+ oldRref = pool.putIfAbsent(cfile, newRef);
+ } else {
+ oldRref = pool.replace(cfile, oldRref, newRef)
+ ? null
+ : pool.get(cfile);
+ }
+ if (oldRref == null) {
+ // success
+ return newStream;
+ } else {
+ // lost race
+ oldStream = oldRref.get();
+ // another loop
+ }
+ }
+ }
+ }
+
+ private static class StreamRef extends WeakReference<UnclosableInputStream> {
+ final File file;
+
+ StreamRef(File file,
+ UnclosableInputStream stream,
+ ReferenceQueue<UnclosableInputStream> refQueue) {
+ super(stream, refQueue);
+ this.file = file;
+ }
+ }
+
+ private static final class UnclosableInputStream extends FilterInputStream {
+ UnclosableInputStream(InputStream in) {
+ super(in);
+ }
+
+ @Override
+ public void close() throws IOException {
+ // Ignore close attempts since underlying InputStream is shared.
+ }
+
+ InputStream getWrappedStream() {
+ return in;
+ }
+ }
+}
--- a/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java Thu Jan 29 03:54:45 2015 +0000
@@ -504,9 +504,10 @@
@Override
public InputStream run() throws IOException {
/*
- * return a FileInputStream for file URLs and
- * avoid buffering. The openStream() call wraps
- * InputStream in a BufferedInputStream which
+ * return a shared InputStream for file URLs and
+ * avoid buffering.
+ * The URL.openStream() call wraps InputStream in a
+ * BufferedInputStream which
* can buffer up to 8K bytes. This read is a
* performance issue for entropy sources which
* can be slow to replenish.
@@ -514,7 +515,8 @@
if (device.getProtocol().equalsIgnoreCase("file")) {
File deviceFile =
SunEntries.getDeviceFile(device);
- return new FileInputStream(deviceFile);
+ return FileInputStreamPool
+ .getInputStream(deviceFile);
} else {
return device.openStream();
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ClientHandshaker.java Thu Jan 29 03:54:45 2015 +0000
@@ -345,6 +345,13 @@
break;
case HandshakeMessage.ht_finished:
+ // A ChangeCipherSpec record must have been received prior to
+ // reception of the Finished message (RFC 5246, 7.4.9).
+ if (!receivedChangeCipherSpec()) {
+ fatalSE(Alerts.alert_handshake_failure,
+ "Received Finished message before ChangeCipherSpec");
+ }
+
this.serverFinished(
new Finished(protocolVersion, input, cipherSuite));
break;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -243,6 +243,7 @@
protocolVersion = ProtocolVersion.valueOf(s.getInt8(), s.getInt8());
clnt_random = new RandomCookie(s);
sessionId = new SessionId(s.getBytes8());
+ sessionId.checkLength(protocolVersion);
cipherSuites = new CipherSuiteList(s);
compression_methods = s.getBytes8();
if (messageLength() != messageLength) {
@@ -355,6 +356,7 @@
input.getInt8());
svr_random = new RandomCookie(input);
sessionId = new SessionId(input.getBytes8());
+ sessionId.checkLength(protocolVersion);
cipherSuite = CipherSuite.valueOf(input.getInt8(), input.getInt8());
compression_method = (byte)input.getInt8();
if (messageLength() != messageLength) {
--- a/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/Handshaker.java Thu Jan 29 03:54:45 2015 +0000
@@ -95,8 +95,6 @@
Collection<SignatureAndHashAlgorithm> peerSupportedSignAlgs;
/*
-
- /*
* List of active protocols
*
* Active protocols is a subset of enabled protocols, and will
@@ -114,10 +112,8 @@
private CipherSuiteList activeCipherSuites;
// The server name indication and matchers
- List<SNIServerName> serverNames =
- Collections.<SNIServerName>emptyList();
- Collection<SNIMatcher> sniMatchers =
- Collections.<SNIMatcher>emptyList();
+ List<SNIServerName> serverNames = Collections.<SNIServerName>emptyList();
+ Collection<SNIMatcher> sniMatchers = Collections.<SNIMatcher>emptyList();
private boolean isClient;
private boolean needCertVerify;
@@ -139,12 +135,16 @@
// current key exchange. Never null, initially K_NULL
KeyExchange keyExchange;
- /* True if this session is being resumed (fast handshake) */
+ // True if this session is being resumed (fast handshake)
boolean resumingSession;
- /* True if it's OK to start a new SSL session */
+ // True if it's OK to start a new SSL session
boolean enableNewSession;
+ // True if session keys have been calculated and the caller may receive
+ // and process a ChangeCipherSpec message
+ private boolean sessKeysCalculated;
+
// Whether local cipher suites preference should be honored during
// handshaking?
//
@@ -253,6 +253,7 @@
this.serverVerifyData = serverVerifyData;
enableNewSession = true;
invalidated = false;
+ sessKeysCalculated = false;
setCipherSuite(CipherSuite.C_NULL);
setEnabledProtocols(enabledProtocols);
@@ -359,6 +360,14 @@
}
}
+ final boolean receivedChangeCipherSpec() {
+ if (conn != null) {
+ return conn.receivedChangeCipherSpec();
+ } else {
+ return engine.receivedChangeCipherSpec();
+ }
+ }
+
String getEndpointIdentificationAlgorithmSE() {
SSLParameters paras;
if (conn != null) {
@@ -491,7 +500,9 @@
if (activeProtocols.collection().isEmpty() ||
activeProtocols.max.v == ProtocolVersion.NONE.v) {
- throw new SSLHandshakeException("No appropriate protocol");
+ throw new SSLHandshakeException(
+ "No appropriate protocol (protocol is disabled or " +
+ "cipher suites are inappropriate)");
}
if (activeCipherSuites == null) {
@@ -676,6 +687,17 @@
continue;
}
+ if (!algorithmConstraints.permits(
+ EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
+ protocol.name, null)) {
+ if (debug != null && Debug.isOn("verbose")) {
+ System.out.println(
+ "Ignoring disabled protocol: " + protocol);
+ }
+
+ continue;
+ }
+
boolean found = false;
for (CipherSuite suite : enabledCipherSuites.collection()) {
if (suite.isAvailable() && suite.obsoleted > protocol.v &&
@@ -1081,7 +1103,6 @@
calculateConnectionKeys(master);
}
-
/*
* Calculate the master secret from its various components. This is
* used for key exchange by all cipher suites.
@@ -1226,6 +1247,10 @@
throw new ProviderException(e);
}
+ // Mark a flag that allows outside entities (like SSLSocket/SSLEngine)
+ // determine if a ChangeCipherSpec message could be processed.
+ sessKeysCalculated = true;
+
//
// Dump the connection keys as they're generated.
//
@@ -1280,6 +1305,15 @@
}
}
+ /**
+ * Return whether or not the Handshaker has derived session keys for
+ * this handshake. This is used for determining readiness to process
+ * an incoming ChangeCipherSpec message.
+ */
+ boolean sessionKeysCalculated() {
+ return sessKeysCalculated;
+ }
+
private static void printHex(HexDumpEncoder dump, byte[] bytes) {
if (bytes == null) {
System.out.println("(key bytes not available)");
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ProtocolVersion.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ProtocolVersion.java Thu Jan 29 03:54:45 2015 +0000
@@ -25,6 +25,9 @@
package sun.security.ssl;
+import java.util.*;
+import java.security.CryptoPrimitive;
+
/**
* Type safe enum for an SSL/TLS protocol version. Instances are obtained
* using the static factory methods or by referencing the static members
@@ -86,6 +89,11 @@
// Default version for hello messages (SSLv2Hello)
final static ProtocolVersion DEFAULT_HELLO = FIPS ? TLS10 : SSL30;
+ // Available protocols
+ //
+ // Including all supported protocols except the disabled ones.
+ final static Set<ProtocolVersion> availableProtocols;
+
// version in 16 bit MSB format as it appears in records and
// messages, i.e. 0x0301 for TLS 1.0
public final int v;
@@ -96,6 +104,25 @@
// name used in JSSE (e.g. TLSv1 for TLS 1.0)
final String name;
+ // Initialize the available protocols.
+ static {
+ Set<ProtocolVersion> protocols = new HashSet<>(5);
+
+ ProtocolVersion[] pvs = new ProtocolVersion[] {
+ SSL20Hello, SSL30, TLS10, TLS11, TLS12};
+ EnumSet<CryptoPrimitive> cryptoPrimitives =
+ EnumSet.<CryptoPrimitive>of(CryptoPrimitive.KEY_AGREEMENT);
+ for (ProtocolVersion p : pvs) {
+ if (SSLAlgorithmConstraints.DEFAULT_SSL_ONLY.permits(
+ cryptoPrimitives, p.name, null)) {
+ protocols.add(p);
+ }
+ }
+
+ availableProtocols =
+ Collections.<ProtocolVersion>unmodifiableSet(protocols);
+ }
+
// private
private ProtocolVersion(int v, String name) {
this.v = v;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLAlgorithmConstraints.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLAlgorithmConstraints.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -55,6 +55,14 @@
private boolean enabledX509DisabledAlgConstraints = true;
+ // the default algorithm constraints
+ final static AlgorithmConstraints DEFAULT =
+ new SSLAlgorithmConstraints(null);
+
+ // the default SSL only algorithm constraints
+ final static AlgorithmConstraints DEFAULT_SSL_ONLY =
+ new SSLAlgorithmConstraints((SSLSocket)null, false);
+
SSLAlgorithmConstraints(AlgorithmConstraints algorithmConstraints) {
userAlgConstraints = algorithmConstraints;
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -52,10 +52,6 @@
private X509TrustManager trustManager;
private SecureRandom secureRandom;
- // The default algrithm constraints
- private AlgorithmConstraints defaultAlgorithmConstraints =
- new SSLAlgorithmConstraints(null);
-
// supported and default protocols
private ProtocolList defaultServerProtocolList;
private ProtocolList defaultClientProtocolList;
@@ -350,7 +346,7 @@
if (suite.isAvailable() &&
suite.obsoleted > protocols.min.v &&
suite.supported <= protocols.max.v) {
- if (defaultAlgorithmConstraints.permits(
+ if (SSLAlgorithmConstraints.DEFAULT.permits(
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
suite.name, null)) {
suites.add(suite);
@@ -431,11 +427,16 @@
*/
private abstract static class AbstractSSLContext extends SSLContextImpl {
// parameters
- private final static SSLParameters defaultServerSSLParams;
- private final static SSLParameters supportedSSLParams;
+ private static final SSLParameters defaultServerSSLParams;
+ private static final SSLParameters supportedSSLParams;
static {
+ // supported SSL parameters
supportedSSLParams = new SSLParameters();
+
+ // candidates for available protocols
+ ProtocolVersion[] candidates;
+
if (SunJSSE.isFIPS()) {
supportedSSLParams.setProtocols(new String[] {
ProtocolVersion.TLS10.name,
@@ -443,7 +444,11 @@
ProtocolVersion.TLS12.name
});
- defaultServerSSLParams = supportedSSLParams;
+ candidates = new ProtocolVersion[] {
+ ProtocolVersion.TLS10,
+ ProtocolVersion.TLS11,
+ ProtocolVersion.TLS12
+ };
} else {
supportedSSLParams.setProtocols(new String[] {
ProtocolVersion.SSL20Hello.name,
@@ -453,8 +458,18 @@
ProtocolVersion.TLS12.name
});
- defaultServerSSLParams = supportedSSLParams;
+ candidates = new ProtocolVersion[] {
+ ProtocolVersion.SSL20Hello,
+ ProtocolVersion.SSL30,
+ ProtocolVersion.TLS10,
+ ProtocolVersion.TLS11,
+ ProtocolVersion.TLS12
+ };
}
+
+ defaultServerSSLParams = new SSLParameters();
+ defaultServerSSLParams.setProtocols(
+ getAvailableProtocols(candidates));
}
@Override
@@ -466,6 +481,22 @@
SSLParameters getSupportedSSLParams() {
return supportedSSLParams;
}
+
+ static String[] getAvailableProtocols(
+ ProtocolVersion[] protocolCandidates) {
+
+ List<String> availableProtocols = Collections.<String>emptyList();
+ if (protocolCandidates != null && protocolCandidates.length != 0) {
+ availableProtocols = new ArrayList<>(protocolCandidates.length);
+ for (ProtocolVersion p : protocolCandidates) {
+ if (ProtocolVersion.availableProtocols.contains(p)) {
+ availableProtocols.add(p.name);
+ }
+ }
+ }
+
+ return availableProtocols.toArray(new String[0]);
+ }
}
/*
@@ -474,21 +505,25 @@
* @see SSLContext
*/
public static final class TLS10Context extends AbstractSSLContext {
- private final static SSLParameters defaultClientSSLParams;
+ private static final SSLParameters defaultClientSSLParams;
static {
- defaultClientSSLParams = new SSLParameters();
+ // candidates for available protocols
+ ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- defaultClientSSLParams.setProtocols(new String[] {
- ProtocolVersion.TLS10.name
- });
+ candidates = new ProtocolVersion[] {
+ ProtocolVersion.TLS10
+ };
+ } else {
+ candidates = new ProtocolVersion[] {
+ ProtocolVersion.SSL30,
+ ProtocolVersion.TLS10
+ };
+ }
- } else {
- defaultClientSSLParams.setProtocols(new String[] {
- ProtocolVersion.SSL30.name,
- ProtocolVersion.TLS10.name
- });
- }
+ defaultClientSSLParams = new SSLParameters();
+ defaultClientSSLParams.setProtocols(
+ getAvailableProtocols(candidates));
}
@Override
@@ -503,23 +538,27 @@
* @see SSLContext
*/
public static final class TLS11Context extends AbstractSSLContext {
- private final static SSLParameters defaultClientSSLParams;
+ private static final SSLParameters defaultClientSSLParams;
static {
- defaultClientSSLParams = new SSLParameters();
+ // candidates for available protocols
+ ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- defaultClientSSLParams.setProtocols(new String[] {
- ProtocolVersion.TLS10.name,
- ProtocolVersion.TLS11.name
- });
+ candidates = new ProtocolVersion[] {
+ ProtocolVersion.TLS10,
+ ProtocolVersion.TLS11
+ };
+ } else {
+ candidates = new ProtocolVersion[] {
+ ProtocolVersion.SSL30,
+ ProtocolVersion.TLS10,
+ ProtocolVersion.TLS11
+ };
+ }
- } else {
- defaultClientSSLParams.setProtocols(new String[] {
- ProtocolVersion.SSL30.name,
- ProtocolVersion.TLS10.name,
- ProtocolVersion.TLS11.name
- });
- }
+ defaultClientSSLParams = new SSLParameters();
+ defaultClientSSLParams.setProtocols(
+ getAvailableProtocols(candidates));
}
@Override
@@ -534,25 +573,29 @@
* @see SSLContext
*/
public static final class TLS12Context extends AbstractSSLContext {
- private final static SSLParameters defaultClientSSLParams;
+ private static final SSLParameters defaultClientSSLParams;
static {
- defaultClientSSLParams = new SSLParameters();
+ // candidates for available protocols
+ ProtocolVersion[] candidates;
if (SunJSSE.isFIPS()) {
- defaultClientSSLParams.setProtocols(new String[] {
- ProtocolVersion.TLS10.name,
- ProtocolVersion.TLS11.name,
- ProtocolVersion.TLS12.name
- });
+ candidates = new ProtocolVersion[] {
+ ProtocolVersion.TLS10,
+ ProtocolVersion.TLS11,
+ ProtocolVersion.TLS12
+ };
+ } else {
+ candidates = new ProtocolVersion[] {
+ ProtocolVersion.SSL30,
+ ProtocolVersion.TLS10,
+ ProtocolVersion.TLS11,
+ ProtocolVersion.TLS12
+ };
+ }
- } else {
- defaultClientSSLParams.setProtocols(new String[] {
- ProtocolVersion.SSL30.name,
- ProtocolVersion.TLS10.name,
- ProtocolVersion.TLS11.name,
- ProtocolVersion.TLS12.name
- });
- }
+ defaultClientSSLParams = new SSLParameters();
+ defaultClientSSLParams.setProtocols(
+ getAvailableProtocols(candidates));
}
@Override
@@ -567,8 +610,8 @@
* @see SSLContext
*/
private static class CustomizedSSLContext extends AbstractSSLContext {
- private final static String PROPERTY_NAME = "jdk.tls.client.protocols";
- private final static SSLParameters defaultClientSSLParams;
+ private static final String PROPERTY_NAME = "jdk.tls.client.protocols";
+ private static final SSLParameters defaultClientSSLParams;
private static IllegalArgumentException reservedException = null;
// Don't want a java.lang.LinkageError for illegal system property.
@@ -578,60 +621,74 @@
// the provider service. Instead, let's handle the initialization
// exception in constructor.
static {
+ // candidates for available protocols
+ ProtocolVersion[] candidates;
+
String property = AccessController.doPrivileged(
new GetPropertyAction(PROPERTY_NAME));
- defaultClientSSLParams = new SSLParameters();
if (property == null || property.length() == 0) {
// the default enabled client TLS protocols
if (SunJSSE.isFIPS()) {
- defaultClientSSLParams.setProtocols(new String[] {
- ProtocolVersion.TLS10.name,
- ProtocolVersion.TLS11.name,
- ProtocolVersion.TLS12.name
- });
-
+ candidates = new ProtocolVersion[] {
+ ProtocolVersion.TLS10,
+ ProtocolVersion.TLS11,
+ ProtocolVersion.TLS12
+ };
} else {
- defaultClientSSLParams.setProtocols(new String[] {
- ProtocolVersion.SSL30.name,
- ProtocolVersion.TLS10.name,
- ProtocolVersion.TLS11.name,
- ProtocolVersion.TLS12.name
- });
+ candidates = new ProtocolVersion[] {
+ ProtocolVersion.SSL30,
+ ProtocolVersion.TLS10,
+ ProtocolVersion.TLS11,
+ ProtocolVersion.TLS12
+ };
}
} else {
// remove double quote marks from beginning/end of the property
- if (property.charAt(0) == '"' &&
+ if (property.length() > 1 && property.charAt(0) == '"' &&
property.charAt(property.length() - 1) == '"') {
property = property.substring(1, property.length() - 1);
}
- String[] protocols = property.split(",");
+ String[] protocols = null;
+ if (property != null && property.length() != 0) {
+ protocols = property.split(",");
+ } else {
+ reservedException = new IllegalArgumentException(
+ "No protocol specified in " +
+ PROPERTY_NAME + " system property");
+ protocols = new String[0];
+ }
+
+ candidates = new ProtocolVersion[protocols.length];
for (int i = 0; i < protocols.length; i++) {
protocols[i] = protocols[i].trim();
// Is it a supported protocol name?
try {
- ProtocolVersion.valueOf(protocols[i]);
+ candidates[i] = ProtocolVersion.valueOf(protocols[i]);
} catch (IllegalArgumentException iae) {
reservedException = new IllegalArgumentException(
- PROPERTY_NAME + ": " + protocols[i] +
- " is not a standard SSL protocol name", iae);
+ PROPERTY_NAME + ": " + protocols[i] +
+ " is not a standard SSL/TLS protocol name", iae);
+ break;
}
}
if ((reservedException == null) && SunJSSE.isFIPS()) {
- for (String protocol : protocols) {
- if (ProtocolVersion.SSL20Hello.name.equals(protocol) ||
- ProtocolVersion.SSL30.name.equals(protocol)) {
+ for (ProtocolVersion protocolVersion : candidates) {
+ if (ProtocolVersion.SSL20Hello.v == protocolVersion.v ||
+ ProtocolVersion.SSL30.v == protocolVersion.v) {
reservedException = new IllegalArgumentException(
- PROPERTY_NAME + ": " + protocol +
+ PROPERTY_NAME + ": " + protocolVersion +
" is not FIPS compliant");
}
}
}
+ }
- if (reservedException == null) {
- defaultClientSSLParams.setProtocols(protocols);
- }
+ defaultClientSSLParams = new SSLParameters();
+ if (reservedException == null) {
+ defaultClientSSLParams.setProtocols(
+ getAvailableProtocols(candidates));
}
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -212,6 +212,11 @@
static final byte clauth_required = 2;
/*
+ * Flag indicating that the engine has received a ChangeCipherSpec message.
+ */
+ private boolean receivedCCS;
+
+ /*
* Flag indicating if the next record we receive MUST be a Finished
* message. Temporarily set during the handshake to ensure that
* a change cipher spec message is followed by a finished message.
@@ -372,6 +377,7 @@
*/
roleIsServer = true;
connectionState = cs_START;
+ receivedCCS = false;
// default server name indication
serverNames =
@@ -1021,6 +1027,7 @@
if (handshaker.invalidated) {
handshaker = null;
+ receivedCCS = false;
// if state is cs_RENEGOTIATE, revert it to cs_DATA
if (connectionState == cs_RENEGOTIATE) {
connectionState = cs_DATA;
@@ -1039,6 +1046,7 @@
}
handshaker = null;
connectionState = cs_DATA;
+ receivedCCS = false;
// No handshakeListeners here. That's a
// SSLSocket thing.
@@ -1078,13 +1086,25 @@
case Record.ct_change_cipher_spec:
if ((connectionState != cs_HANDSHAKE
&& connectionState != cs_RENEGOTIATE)
- || inputRecord.available() != 1
- || inputRecord.read() != 1) {
+ || !handshaker.sessionKeysCalculated()
+ || receivedCCS) {
+ // For the CCS message arriving in the wrong state
fatal(Alerts.alert_unexpected_message,
- "illegal change cipher spec msg, state = "
- + connectionState);
+ "illegal change cipher spec msg, conn state = "
+ + connectionState + ", handshake state = "
+ + handshaker.state);
+ } else if (inputRecord.available() != 1
+ || inputRecord.read() != 1) {
+ // For structural/content issues with the CCS
+ fatal(Alerts.alert_unexpected_message,
+ "Malformed change cipher spec msg");
}
+ // Once we've received CCS, update the flag.
+ // If the remote endpoint sends it again in this handshake
+ // we won't process it.
+ receivedCCS = true;
+
//
// The first message after a change_cipher_spec
// record MUST be a "Finished" handshake record,
@@ -2121,6 +2141,14 @@
}
/**
+ * Returns a boolean indicating whether the ChangeCipherSpec message
+ * has been received for this handshake.
+ */
+ boolean receivedChangeCipherSpec() {
+ return receivedCCS;
+ }
+
+ /**
* Returns a printable representation of this end of the connection.
*/
@Override
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -172,6 +172,12 @@
private volatile int connectionState;
/*
+ * Flag indicating that the engine's handshaker has done the necessary
+ * steps so the engine may process a ChangeCipherSpec message.
+ */
+ private boolean receivedCCS;
+
+ /*
* Flag indicating if the next record we receive MUST be a Finished
* message. Temporarily set during the handshake to ensure that
* a change cipher spec message is followed by a finished message.
@@ -587,6 +593,7 @@
*/
roleIsServer = isServer;
connectionState = cs_START;
+ receivedCCS = false;
/*
* default read and write side cipher and MAC support
@@ -1045,6 +1052,7 @@
if (handshaker.invalidated) {
handshaker = null;
+ receivedCCS = false;
// if state is cs_RENEGOTIATE, revert it to cs_DATA
if (connectionState == cs_RENEGOTIATE) {
connectionState = cs_DATA;
@@ -1060,6 +1068,7 @@
handshakeSession = null;
handshaker = null;
connectionState = cs_DATA;
+ receivedCCS = false;
//
// Tell folk about handshake completion, but do
@@ -1107,13 +1116,24 @@
case Record.ct_change_cipher_spec:
if ((connectionState != cs_HANDSHAKE
&& connectionState != cs_RENEGOTIATE)
- || r.available() != 1
- || r.read() != 1) {
+ || !handshaker.sessionKeysCalculated()
+ || receivedCCS) {
+ // For the CCS message arriving in the wrong state
fatal(Alerts.alert_unexpected_message,
- "illegal change cipher spec msg, state = "
- + connectionState);
+ "illegal change cipher spec msg, conn state = "
+ + connectionState + ", handshake state = "
+ + handshaker.state);
+ } else if (r.available() != 1 || r.read() != 1) {
+ // For structural/content issues with the CCS
+ fatal(Alerts.alert_unexpected_message,
+ "Malformed change cipher spec msg");
}
+ // Once we've received CCS, update the flag.
+ // If the remote endpoint sends it again in this handshake
+ // we won't process it.
+ receivedCCS = true;
+
//
// The first message after a change_cipher_spec
// record MUST be a "Finished" handshake record,
@@ -2590,6 +2610,14 @@
}
/**
+ * Returns a boolean indicating whether the ChangeCipherSpec message
+ * has been received for this handshake.
+ */
+ boolean receivedChangeCipherSpec() {
+ return receivedCCS;
+ }
+
+ /**
* Returns a printable representation of this end of the connection.
*/
@Override
--- a/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java Thu Jan 29 03:54:45 2015 +0000
@@ -287,6 +287,13 @@
break;
case HandshakeMessage.ht_finished:
+ // A ChangeCipherSpec record must have been received prior to
+ // reception of the Finished message (RFC 5246, 7.4.9).
+ if (!receivedChangeCipherSpec()) {
+ fatalSE(Alerts.alert_handshake_failure,
+ "Received Finished message before ChangeCipherSpec");
+ }
+
this.clientFinished(
new Finished(protocolVersion, input, cipherSuite));
break;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SessionId.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SessionId.java Thu Jan 29 03:54:45 2015 +0000
@@ -27,6 +27,7 @@
package sun.security.ssl;
import java.security.SecureRandom;
+import javax.net.ssl.SSLProtocolException;
/**
* Encapsulates an SSL session ID. SSL Session IDs are not reused by
@@ -41,6 +42,7 @@
final
class SessionId
{
+ static int MAX_LENGTH = 32;
private byte sessionId []; // max 32 bytes
/** Constructs a new session ID ... perhaps for a rejoinable session */
@@ -114,4 +116,19 @@
}
return true;
}
+
+ /**
+ * Checks the length of the session ID to make sure it sits within
+ * the range called out in the specification
+ */
+ void checkLength(ProtocolVersion pv) throws SSLProtocolException {
+ // As of today all versions of TLS have a 32-byte maximum length.
+ // In the future we can do more here to support protocol versions
+ // that may have longer max lengths.
+ if (sessionId.length > MAX_LENGTH) {
+ throw new SSLProtocolException("Invalid session ID length (" +
+ sessionId.length + " bytes)");
+ }
+ }
+
}
--- a/jdk/src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java Thu Jan 29 03:54:45 2015 +0000
@@ -156,12 +156,18 @@
}
if (isLongForm(lenByte)) {
lenByte &= LEN_MASK;
- if (lenByte > 4)
+ if (lenByte > 4) {
throw new IOException("Too much data");
- if ((dataSize - dataPos) < (lenByte + 1))
+ }
+ if ((dataSize - dataPos) < (lenByte + 1)) {
throw new IOException("Too little data");
- for (int i = 0; i < lenByte; i++)
+ }
+ for (int i = 0; i < lenByte; i++) {
curLen = (curLen << 8) + (data[dataPos++] & 0xff);
+ }
+ if (curLen < 0) {
+ throw new IOException("Invalid length bytes");
+ }
} else {
curLen = (lenByte & LEN_MASK);
}
@@ -188,10 +194,15 @@
}
if (isLongForm(lenByte)) {
lenByte &= LEN_MASK;
- for (int i = 0; i < lenByte; i++)
+ for (int i = 0; i < lenByte; i++) {
curLen = (curLen << 8) + (data[dataPos++] & 0xff);
- } else
+ }
+ if (curLen < 0) {
+ throw new IOException("Invalid length bytes");
+ }
+ } else {
curLen = (lenByte & LEN_MASK);
+ }
writeLength(curLen);
writeValue(curLen);
}
--- a/jdk/src/java.base/share/classes/sun/security/util/DerInputStream.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/classes/sun/security/util/DerInputStream.java Thu Jan 29 03:54:45 2015 +0000
@@ -577,6 +577,10 @@
value <<= 8;
value += 0x0ff & in.read();
}
+ if (value < 0) {
+ throw new IOException("DerInputStream.getLength(): "
+ + "Invalid length bytes");
+ }
}
return value;
}
--- a/jdk/src/java.base/share/conf/security/java.security Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/share/conf/security/java.security Thu Jan 29 03:54:45 2015 +0000
@@ -512,8 +512,12 @@
#
# In some environments, certain algorithms or key lengths may be undesirable
# when using SSL/TLS. This section describes the mechanism for disabling
-# algorithms during SSL/TLS security parameters negotiation, including cipher
-# suites selection, peer authentication and key exchange mechanisms.
+# algorithms during SSL/TLS security parameters negotiation, including
+# protocol version negotiation, cipher suites selection, peer authentication
+# and key exchange mechanisms.
+#
+# Disabled algorithms will not be negotiated for SSL/TLS connections, even
+# if they are enabled explicitly in an application.
#
# For PKI-based peer authentication and key exchange mechanisms, this list
# of disabled algorithms will also be checked during certification path
@@ -528,4 +532,5 @@
# It is not guaranteed to be examined and used by other implementations.
#
# Example:
-# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+# jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
+jdk.tls.disabledAlgorithms=SSLv3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/solaris/native/libnet/solaris_close.c Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,117 @@
+/*
+ * 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. 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.
+ */
+
+#include <errno.h>
+#include <sys/socket.h>
+#include <stropts.h>
+#include <unistd.h>
+
+/* Support for restartable system calls on Solaris. */
+
+#define RESTARTABLE_RETURN_INT(_cmd) do { \
+ int _result; \
+ if (1) { \
+ do { \
+ _result = _cmd; \
+ } while((_result == -1) && (errno == EINTR)); \
+ return _result; \
+ } \
+} while(0)
+
+int NET_Read(int s, void* buf, size_t len) {
+ RESTARTABLE_RETURN_INT(recv(s, buf, len, 0));
+}
+
+int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
+ struct sockaddr *from, socklen_t *fromlen) {
+ RESTARTABLE_RETURN_INT(recvfrom(s, buf, len, flags, from, fromlen));
+}
+
+int NET_ReadV(int s, const struct iovec * vector, int count) {
+ RESTARTABLE_RETURN_INT(readv(s, vector, count));
+}
+
+int NET_WriteV(int s, const struct iovec * vector, int count) {
+ RESTARTABLE_RETURN_INT(writev(s, vector, count));
+}
+
+int NET_Send(int s, void *msg, int len, unsigned int flags) {
+ RESTARTABLE_RETURN_INT(send(s, msg, len, flags));
+}
+
+int NET_SendTo(int s, const void *msg, int len, unsigned int flags,
+ const struct sockaddr *to, int tolen) {
+ RESTARTABLE_RETURN_INT(sendto(s, msg, len, flags, to, tolen));
+}
+
+int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
+ RESTARTABLE_RETURN_INT(connect(s, addr, addrlen));
+}
+
+int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) {
+ RESTARTABLE_RETURN_INT(accept(s, addr, addrlen));
+}
+
+int NET_SocketClose(int fd) {
+ return close(fd);
+}
+
+int NET_Dup2(int fd, int fd2) {
+ return dup2(fd, fd2);
+}
+
+int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
+ RESTARTABLE_RETURN_INT(poll(ufds, nfds, timeout));
+}
+
+int NET_Timeout(int s, long timeout) {
+ int result;
+ struct timeval t;
+ long prevtime, newtime;
+ struct pollfd pfd;
+ pfd.fd = s;
+ pfd.events = POLLIN;
+
+ if (timeout > 0) {
+ gettimeofday(&t, NULL);
+ prevtime = (t.tv_sec * 1000) + t.tv_usec / 1000;
+ }
+
+ for(;;) {
+ result = poll(&pfd, 1, timeout);
+ if (result < 0 && errno == EINTR) {
+ if (timeout > 0) {
+ gettimeofday(&t, NULL);
+ newtime = (t.tv_sec * 1000) + t.tv_usec /1000;
+ timeout -= newtime - prevtime;
+ if (timeout <= 0)
+ return 0;
+ prevtime = newtime;
+ }
+ } else {
+ return result;
+ }
+ }
+}
--- a/jdk/src/java.base/unix/classes/java/lang/ClassLoaderHelper.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/unix/classes/java/lang/ClassLoaderHelper.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,11 @@
private ClassLoaderHelper() {}
/**
+ * Indicates, whether PATH env variable is allowed to contain quoted entries.
+ */
+ static final boolean allowsQuotedPathElements = false;
+
+ /**
* Returns an alternate path name for the given file
* such that if the original pathname did not exist, then the
* file may be located at the alternate location.
--- a/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/unix/classes/java/lang/ProcessImpl.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, 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,24 +25,156 @@
package java.lang;
-import java.io.IOException;
+import java.lang.ProcessBuilder.Redirect;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.lang.ProcessBuilder.Redirect;
-import java.lang.ProcessBuilder.Redirect;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.security.AccessController;
+import static java.security.AccessController.doPrivileged;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
/**
- * This class is for the exclusive use of ProcessBuilder.start() to
- * create new processes.
+ * This java.lang.Process subclass in the UNIX environment is for the exclusive use of
+ * ProcessBuilder.start() to create new processes.
*
+ * @author Mario Wolczko and Ross Knippel.
+ * @author Konstantin Kladko (ported to Linux and Bsd)
* @author Martin Buchholz
+ * @author Volker Simonis (ported to AIX)
* @since 1.5
*/
-final class ProcessImpl {
+final class ProcessImpl extends Process {
private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
- private ProcessImpl() {} // Not instantiable
+ private final int pid;
+ private int exitcode;
+ private boolean hasExited;
+
+ private /* final */ OutputStream stdin;
+ private /* final */ InputStream stdout;
+ private /* final */ InputStream stderr;
+
+ // only used on Solaris
+ private /* final */ DeferredCloseInputStream stdout_inner_stream;
+
+ private static enum LaunchMechanism {
+ // order IS important!
+ FORK,
+ POSIX_SPAWN,
+ VFORK
+ }
+
+ private static enum Platform {
+
+ LINUX(LaunchMechanism.VFORK, LaunchMechanism.FORK),
+
+ BSD(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
+
+ SOLARIS(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
+
+ AIX(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK);
+
+ final LaunchMechanism defaultLaunchMechanism;
+ final Set<LaunchMechanism> validLaunchMechanisms;
+
+ Platform(LaunchMechanism ... launchMechanisms) {
+ this.defaultLaunchMechanism = launchMechanisms[0];
+ this.validLaunchMechanisms =
+ EnumSet.copyOf(Arrays.asList(launchMechanisms));
+ }
+
+ @SuppressWarnings("fallthrough")
+ private String helperPath(String javahome, String osArch) {
+ switch (this) {
+ case SOLARIS:
+ if (osArch.equals("x86")) { osArch = "i386"; }
+ else if (osArch.equals("x86_64")) { osArch = "amd64"; }
+ // fall through...
+ case LINUX:
+ case AIX:
+ return javahome + "/lib/" + osArch + "/jspawnhelper";
+
+ case BSD:
+ return javahome + "/lib/jspawnhelper";
+
+ default:
+ throw new AssertionError("Unsupported platform: " + this);
+ }
+ }
+
+ String helperPath() {
+ return AccessController.doPrivileged(
+ (PrivilegedAction<String>) () ->
+ helperPath(System.getProperty("java.home"),
+ System.getProperty("os.arch"))
+ );
+ }
+
+ LaunchMechanism launchMechanism() {
+ return AccessController.doPrivileged(
+ (PrivilegedAction<LaunchMechanism>) () -> {
+ String s = System.getProperty(
+ "jdk.lang.Process.launchMechanism");
+ LaunchMechanism lm;
+ if (s == null) {
+ lm = defaultLaunchMechanism;
+ s = lm.name().toLowerCase(Locale.ENGLISH);
+ } else {
+ try {
+ lm = LaunchMechanism.valueOf(
+ s.toUpperCase(Locale.ENGLISH));
+ } catch (IllegalArgumentException e) {
+ lm = null;
+ }
+ }
+ if (lm == null || !validLaunchMechanisms.contains(lm)) {
+ throw new Error(
+ s + " is not a supported " +
+ "process launch mechanism on this platform."
+ );
+ }
+ return lm;
+ }
+ );
+ }
+
+ static Platform get() {
+ String osName = AccessController.doPrivileged(
+ (PrivilegedAction<String>) () -> System.getProperty("os.name")
+ );
+
+ if (osName.equals("Linux")) { return LINUX; }
+ if (osName.contains("OS X")) { return BSD; }
+ if (osName.equals("SunOS")) { return SOLARIS; }
+ if (osName.equals("AIX")) { return AIX; }
+
+ throw new Error(osName + " is not a supported OS platform.");
+ }
+ }
+
+ private static final Platform platform = Platform.get();
+ private static final LaunchMechanism launchMechanism = platform.launchMechanism();
+ private static final byte[] helperpath = toCString(platform.helperPath());
+
+ /* this is for the reaping thread */
+ private native int waitForProcessExit(int pid);
private static byte[] toCString(String s) {
if (s == null)
@@ -50,8 +182,8 @@
byte[] bytes = s.getBytes();
byte[] result = new byte[bytes.length + 1];
System.arraycopy(bytes, 0,
- result, 0,
- bytes.length);
+ result, 0,
+ bytes.length);
result[result.length-1] = (byte)0;
return result;
}
@@ -62,7 +194,7 @@
String dir,
ProcessBuilder.Redirect[] redirects,
boolean redirectErrorStream)
- throws IOException
+ throws IOException
{
assert cmdarray != null && cmdarray.length > 0;
@@ -112,7 +244,7 @@
std_fds[1] = 1;
else {
f1 = new FileOutputStream(redirects[1].file(),
- redirects[1].append());
+ redirects[1].append());
std_fds[1] = fdAccess.get(f1.getFD());
}
@@ -122,18 +254,18 @@
std_fds[2] = 2;
else {
f2 = new FileOutputStream(redirects[2].file(),
- redirects[2].append());
+ redirects[2].append());
std_fds[2] = fdAccess.get(f2.getFD());
}
}
- return new UNIXProcess
- (toCString(cmdarray[0]),
- argBlock, args.length,
- envBlock, envc[0],
- toCString(dir),
- std_fds,
- redirectErrorStream);
+ return new ProcessImpl
+ (toCString(cmdarray[0]),
+ argBlock, args.length,
+ envBlock, envc[0],
+ toCString(dir),
+ std_fds,
+ redirectErrorStream);
} finally {
// In theory, close() can throw IOException
// (although it is rather unlikely to happen here)
@@ -144,4 +276,654 @@
}
}
}
+
+
+ /**
+ * Creates a process. Depending on the {@code mode} flag, this is done by
+ * one of the following mechanisms:
+ * <pre>
+ * 1 - fork(2) and exec(2)
+ * 2 - posix_spawn(3P)
+ * 3 - vfork(2) and exec(2)
+ *
+ * (4 - clone(2) and exec(2) - obsolete and currently disabled in native code)
+ * </pre>
+ * @param fds an array of three file descriptors.
+ * Indexes 0, 1, and 2 correspond to standard input,
+ * standard output and standard error, respectively. On
+ * input, a value of -1 means to create a pipe to connect
+ * child and parent processes. On output, a value which
+ * is not -1 is the parent pipe fd corresponding to the
+ * pipe which has been created. An element of this array
+ * is -1 on input if and only if it is <em>not</em> -1 on
+ * output.
+ * @return the pid of the subprocess
+ */
+ private native int forkAndExec(int mode, byte[] helperpath,
+ byte[] prog,
+ byte[] argBlock, int argc,
+ byte[] envBlock, int envc,
+ byte[] dir,
+ int[] fds,
+ boolean redirectErrorStream)
+ throws IOException;
+
+ /**
+ * The thread pool of "process reaper" daemon threads.
+ */
+ private static final Executor processReaperExecutor =
+ doPrivileged((PrivilegedAction<Executor>) () -> {
+
+ ThreadGroup tg = Thread.currentThread().getThreadGroup();
+ while (tg.getParent() != null) tg = tg.getParent();
+ ThreadGroup systemThreadGroup = tg;
+
+ ThreadFactory threadFactory = grimReaper -> {
+ // Our thread stack requirement is quite modest.
+ Thread t = new Thread(systemThreadGroup, grimReaper,
+ "process reaper", 32768);
+ t.setDaemon(true);
+ // A small attempt (probably futile) to avoid priority inversion
+ t.setPriority(Thread.MAX_PRIORITY);
+ return t;
+ };
+
+ return Executors.newCachedThreadPool(threadFactory);
+ });
+
+ private ProcessImpl(final byte[] prog,
+ final byte[] argBlock, final int argc,
+ final byte[] envBlock, final int envc,
+ final byte[] dir,
+ final int[] fds,
+ final boolean redirectErrorStream)
+ throws IOException {
+
+ pid = forkAndExec(launchMechanism.ordinal() + 1,
+ helperpath,
+ prog,
+ argBlock, argc,
+ envBlock, envc,
+ dir,
+ fds,
+ redirectErrorStream);
+
+ try {
+ doPrivileged((PrivilegedExceptionAction<Void>) () -> {
+ initStreams(fds);
+ return null;
+ });
+ } catch (PrivilegedActionException ex) {
+ throw (IOException) ex.getException();
+ }
+ }
+
+ static FileDescriptor newFileDescriptor(int fd) {
+ FileDescriptor fileDescriptor = new FileDescriptor();
+ fdAccess.set(fileDescriptor, fd);
+ return fileDescriptor;
+ }
+
+ void initStreams(int[] fds) throws IOException {
+ switch (platform) {
+ case LINUX:
+ case BSD:
+ stdin = (fds[0] == -1) ?
+ ProcessBuilder.NullOutputStream.INSTANCE :
+ new ProcessPipeOutputStream(fds[0]);
+
+ stdout = (fds[1] == -1) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new ProcessPipeInputStream(fds[1]);
+
+ stderr = (fds[2] == -1) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new ProcessPipeInputStream(fds[2]);
+
+ processReaperExecutor.execute(() -> {
+ int exitcode = waitForProcessExit(pid);
+
+ synchronized (this) {
+ this.exitcode = exitcode;
+ this.hasExited = true;
+ this.notifyAll();
+ }
+
+ if (stdout instanceof ProcessPipeInputStream)
+ ((ProcessPipeInputStream) stdout).processExited();
+
+ if (stderr instanceof ProcessPipeInputStream)
+ ((ProcessPipeInputStream) stderr).processExited();
+
+ if (stdin instanceof ProcessPipeOutputStream)
+ ((ProcessPipeOutputStream) stdin).processExited();
+ });
+ break;
+
+ case SOLARIS:
+ stdin = (fds[0] == -1) ?
+ ProcessBuilder.NullOutputStream.INSTANCE :
+ new BufferedOutputStream(
+ new FileOutputStream(newFileDescriptor(fds[0])));
+
+ stdout = (fds[1] == -1) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new BufferedInputStream(
+ stdout_inner_stream =
+ new DeferredCloseInputStream(
+ newFileDescriptor(fds[1])));
+
+ stderr = (fds[2] == -1) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new DeferredCloseInputStream(newFileDescriptor(fds[2]));
+
+ /*
+ * For each subprocess forked a corresponding reaper task
+ * is submitted. That task is the only thread which waits
+ * for the subprocess to terminate and it doesn't hold any
+ * locks while doing so. This design allows waitFor() and
+ * exitStatus() to be safely executed in parallel (and they
+ * need no native code).
+ */
+ processReaperExecutor.execute(() -> {
+ int exitcode = waitForProcessExit(pid);
+
+ synchronized (this) {
+ this.exitcode = exitcode;
+ this.hasExited = true;
+ this.notifyAll();
+ }
+ });
+ break;
+
+ case AIX:
+ stdin = (fds[0] == -1) ?
+ ProcessBuilder.NullOutputStream.INSTANCE :
+ new ProcessPipeOutputStream(fds[0]);
+
+ stdout = (fds[1] == -1) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new DeferredCloseProcessPipeInputStream(fds[1]);
+
+ stderr = (fds[2] == -1) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new DeferredCloseProcessPipeInputStream(fds[2]);
+
+ processReaperExecutor.execute(() -> {
+ int exitcode = waitForProcessExit(pid);
+
+ synchronized (this) {
+ this.exitcode = exitcode;
+ this.hasExited = true;
+ this.notifyAll();
+ }
+
+ if (stdout instanceof DeferredCloseProcessPipeInputStream)
+ ((DeferredCloseProcessPipeInputStream) stdout).processExited();
+
+ if (stderr instanceof DeferredCloseProcessPipeInputStream)
+ ((DeferredCloseProcessPipeInputStream) stderr).processExited();
+
+ if (stdin instanceof ProcessPipeOutputStream)
+ ((ProcessPipeOutputStream) stdin).processExited();
+ });
+ break;
+
+ default: throw new AssertionError("Unsupported platform: " + platform);
+ }
+ }
+
+ public OutputStream getOutputStream() {
+ return stdin;
+ }
+
+ public InputStream getInputStream() {
+ return stdout;
+ }
+
+ public InputStream getErrorStream() {
+ return stderr;
+ }
+
+ public synchronized int waitFor() throws InterruptedException {
+ while (!hasExited) {
+ wait();
+ }
+ return exitcode;
+ }
+
+ @Override
+ public synchronized boolean waitFor(long timeout, TimeUnit unit)
+ throws InterruptedException
+ {
+ if (hasExited) return true;
+ if (timeout <= 0) return false;
+
+ long remainingNanos = unit.toNanos(timeout);
+ long deadline = System.nanoTime() + remainingNanos;
+
+ do {
+ // Round up to next millisecond
+ wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L));
+ if (hasExited) {
+ return true;
+ }
+ remainingNanos = deadline - System.nanoTime();
+ } while (remainingNanos > 0);
+ return hasExited;
+ }
+
+ public synchronized int exitValue() {
+ if (!hasExited) {
+ throw new IllegalThreadStateException("process hasn't exited");
+ }
+ return exitcode;
+ }
+
+ private static native void destroyProcess(int pid, boolean force);
+
+ private void destroy(boolean force) {
+ switch (platform) {
+ case LINUX:
+ case BSD:
+ case AIX:
+ // There is a risk that pid will be recycled, causing us to
+ // kill the wrong process! So we only terminate processes
+ // that appear to still be running. Even with this check,
+ // there is an unavoidable race condition here, but the window
+ // is very small, and OSes try hard to not recycle pids too
+ // soon, so this is quite safe.
+ synchronized (this) {
+ if (!hasExited)
+ destroyProcess(pid, force);
+ }
+ try { stdin.close(); } catch (IOException ignored) {}
+ try { stdout.close(); } catch (IOException ignored) {}
+ try { stderr.close(); } catch (IOException ignored) {}
+ break;
+
+ case SOLARIS:
+ // There is a risk that pid will be recycled, causing us to
+ // kill the wrong process! So we only terminate processes
+ // that appear to still be running. Even with this check,
+ // there is an unavoidable race condition here, but the window
+ // is very small, and OSes try hard to not recycle pids too
+ // soon, so this is quite safe.
+ synchronized (this) {
+ if (!hasExited)
+ destroyProcess(pid, force);
+ try {
+ stdin.close();
+ if (stdout_inner_stream != null)
+ stdout_inner_stream.closeDeferred(stdout);
+ if (stderr instanceof DeferredCloseInputStream)
+ ((DeferredCloseInputStream) stderr)
+ .closeDeferred(stderr);
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ break;
+
+ default: throw new AssertionError("Unsupported platform: " + platform);
+ }
+ }
+
+ public void destroy() {
+ destroy(false);
+ }
+
+ @Override
+ public Process destroyForcibly() {
+ destroy(true);
+ return this;
+ }
+
+ @Override
+ public long getPid() {
+ return pid;
+ }
+
+ @Override
+ public synchronized boolean isAlive() {
+ return !hasExited;
+ }
+
+ private static native void init();
+
+ static {
+ init();
+ }
+
+ /**
+ * A buffered input stream for a subprocess pipe file descriptor
+ * that allows the underlying file descriptor to be reclaimed when
+ * the process exits, via the processExited hook.
+ *
+ * This is tricky because we do not want the user-level InputStream to be
+ * closed until the user invokes close(), and we need to continue to be
+ * able to read any buffered data lingering in the OS pipe buffer.
+ */
+ private static class ProcessPipeInputStream extends BufferedInputStream {
+ private final Object closeLock = new Object();
+
+ ProcessPipeInputStream(int fd) {
+ super(new FileInputStream(newFileDescriptor(fd)));
+ }
+ private static byte[] drainInputStream(InputStream in)
+ throws IOException {
+ int n = 0;
+ int j;
+ byte[] a = null;
+ while ((j = in.available()) > 0) {
+ a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
+ n += in.read(a, n, j);
+ }
+ return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
+ }
+
+ /** Called by the process reaper thread when the process exits. */
+ synchronized void processExited() {
+ synchronized (closeLock) {
+ try {
+ InputStream in = this.in;
+ // this stream is closed if and only if: in == null
+ if (in != null) {
+ byte[] stragglers = drainInputStream(in);
+ in.close();
+ this.in = (stragglers == null) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new ByteArrayInputStream(stragglers);
+ }
+ } catch (IOException ignored) {}
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ // BufferedInputStream#close() is not synchronized unlike most other
+ // methods. Synchronizing helps avoid race with processExited().
+ synchronized (closeLock) {
+ super.close();
+ }
+ }
+ }
+
+ /**
+ * A buffered output stream for a subprocess pipe file descriptor
+ * that allows the underlying file descriptor to be reclaimed when
+ * the process exits, via the processExited hook.
+ */
+ private static class ProcessPipeOutputStream extends BufferedOutputStream {
+ ProcessPipeOutputStream(int fd) {
+ super(new FileOutputStream(newFileDescriptor(fd)));
+ }
+
+ /** Called by the process reaper thread when the process exits. */
+ synchronized void processExited() {
+ OutputStream out = this.out;
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException ignored) {
+ // We know of no reason to get an IOException, but if
+ // we do, there's nothing else to do but carry on.
+ }
+ this.out = ProcessBuilder.NullOutputStream.INSTANCE;
+ }
+ }
+ }
+
+ // A FileInputStream that supports the deferment of the actual close
+ // operation until the last pending I/O operation on the stream has
+ // finished. This is required on Solaris because we must close the stdin
+ // and stdout streams in the destroy method in order to reclaim the
+ // underlying file descriptors. Doing so, however, causes any thread
+ // currently blocked in a read on one of those streams to receive an
+ // IOException("Bad file number"), which is incompatible with historical
+ // behavior. By deferring the close we allow any pending reads to see -1
+ // (EOF) as they did before.
+ //
+ private static class DeferredCloseInputStream extends FileInputStream
+ {
+ DeferredCloseInputStream(FileDescriptor fd) {
+ super(fd);
+ }
+
+ private Object lock = new Object(); // For the following fields
+ private boolean closePending = false;
+ private int useCount = 0;
+ private InputStream streamToClose;
+
+ private void raise() {
+ synchronized (lock) {
+ useCount++;
+ }
+ }
+
+ private void lower() throws IOException {
+ synchronized (lock) {
+ useCount--;
+ if (useCount == 0 && closePending) {
+ streamToClose.close();
+ }
+ }
+ }
+
+ // stc is the actual stream to be closed; it might be this object, or
+ // it might be an upstream object for which this object is downstream.
+ //
+ private void closeDeferred(InputStream stc) throws IOException {
+ synchronized (lock) {
+ if (useCount == 0) {
+ stc.close();
+ } else {
+ closePending = true;
+ streamToClose = stc;
+ }
+ }
+ }
+
+ public void close() throws IOException {
+ synchronized (lock) {
+ useCount = 0;
+ closePending = false;
+ }
+ super.close();
+ }
+
+ public int read() throws IOException {
+ raise();
+ try {
+ return super.read();
+ } finally {
+ lower();
+ }
+ }
+
+ public int read(byte[] b) throws IOException {
+ raise();
+ try {
+ return super.read(b);
+ } finally {
+ lower();
+ }
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ raise();
+ try {
+ return super.read(b, off, len);
+ } finally {
+ lower();
+ }
+ }
+
+ public long skip(long n) throws IOException {
+ raise();
+ try {
+ return super.skip(n);
+ } finally {
+ lower();
+ }
+ }
+
+ public int available() throws IOException {
+ raise();
+ try {
+ return super.available();
+ } finally {
+ lower();
+ }
+ }
+ }
+
+ /**
+ * A buffered input stream for a subprocess pipe file descriptor
+ * that allows the underlying file descriptor to be reclaimed when
+ * the process exits, via the processExited hook.
+ *
+ * This is tricky because we do not want the user-level InputStream to be
+ * closed until the user invokes close(), and we need to continue to be
+ * able to read any buffered data lingering in the OS pipe buffer.
+ *
+ * On AIX this is especially tricky, because the 'close()' system call
+ * will block if another thread is at the same time blocked in a file
+ * operation (e.g. 'read()') on the same file descriptor. We therefore
+ * combine 'ProcessPipeInputStream' approach used on Linux and Bsd
+ * with the DeferredCloseInputStream approach used on Solaris. This means
+ * that every potentially blocking operation on the file descriptor
+ * increments a counter before it is executed and decrements it once it
+ * finishes. The 'close()' operation will only be executed if there are
+ * no pending operations. Otherwise it is deferred after the last pending
+ * operation has finished.
+ *
+ */
+ private static class DeferredCloseProcessPipeInputStream
+ extends BufferedInputStream {
+
+ private final Object closeLock = new Object();
+ private int useCount = 0;
+ private boolean closePending = false;
+
+ DeferredCloseProcessPipeInputStream(int fd) {
+ super(new FileInputStream(newFileDescriptor(fd)));
+ }
+
+ private InputStream drainInputStream(InputStream in)
+ throws IOException {
+ int n = 0;
+ int j;
+ byte[] a = null;
+ synchronized (closeLock) {
+ if (buf == null) // asynchronous close()?
+ return null; // discard
+ j = in.available();
+ }
+ while (j > 0) {
+ a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
+ synchronized (closeLock) {
+ if (buf == null) // asynchronous close()?
+ return null; // discard
+ n += in.read(a, n, j);
+ j = in.available();
+ }
+ }
+ return (a == null) ?
+ ProcessBuilder.NullInputStream.INSTANCE :
+ new ByteArrayInputStream(n == a.length ? a : Arrays.copyOf(a, n));
+ }
+
+ /** Called by the process reaper thread when the process exits. */
+ synchronized void processExited() {
+ try {
+ InputStream in = this.in;
+ if (in != null) {
+ InputStream stragglers = drainInputStream(in);
+ in.close();
+ this.in = stragglers;
+ }
+ } catch (IOException ignored) { }
+ }
+
+ private void raise() {
+ synchronized (closeLock) {
+ useCount++;
+ }
+ }
+
+ private void lower() throws IOException {
+ synchronized (closeLock) {
+ useCount--;
+ if (useCount == 0 && closePending) {
+ closePending = false;
+ super.close();
+ }
+ }
+ }
+
+ @Override
+ public int read() throws IOException {
+ raise();
+ try {
+ return super.read();
+ } finally {
+ lower();
+ }
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ raise();
+ try {
+ return super.read(b);
+ } finally {
+ lower();
+ }
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ raise();
+ try {
+ return super.read(b, off, len);
+ } finally {
+ lower();
+ }
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ raise();
+ try {
+ return super.skip(n);
+ } finally {
+ lower();
+ }
+ }
+
+ @Override
+ public int available() throws IOException {
+ raise();
+ try {
+ return super.available();
+ } finally {
+ lower();
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ // BufferedInputStream#close() is not synchronized unlike most other
+ // methods. Synchronizing helps avoid racing with drainInputStream().
+ synchronized (closeLock) {
+ if (useCount == 0) {
+ super.close();
+ }
+ else {
+ closePending = true;
+ }
+ }
+ }
+ }
}
--- a/jdk/src/java.base/unix/classes/java/lang/UNIXProcess.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,836 +0,0 @@
-/*
- * Copyright (c) 1995, 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. 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;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.Locale;
-import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.security.AccessController;
-import static java.security.AccessController.doPrivileged;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-
-/**
- * java.lang.Process subclass in the UNIX environment.
- *
- * @author Mario Wolczko and Ross Knippel.
- * @author Konstantin Kladko (ported to Linux and Bsd)
- * @author Martin Buchholz
- * @author Volker Simonis (ported to AIX)
- */
-final class UNIXProcess extends Process {
- private static final sun.misc.JavaIOFileDescriptorAccess fdAccess
- = sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess();
-
- private final int pid;
- private int exitcode;
- private boolean hasExited;
-
- private /* final */ OutputStream stdin;
- private /* final */ InputStream stdout;
- private /* final */ InputStream stderr;
-
- // only used on Solaris
- private /* final */ DeferredCloseInputStream stdout_inner_stream;
-
- private static enum LaunchMechanism {
- // order IS important!
- FORK,
- POSIX_SPAWN,
- VFORK
- }
-
- private static enum Platform {
-
- LINUX(LaunchMechanism.VFORK, LaunchMechanism.FORK),
-
- BSD(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
-
- SOLARIS(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK),
-
- AIX(LaunchMechanism.POSIX_SPAWN, LaunchMechanism.FORK);
-
- final LaunchMechanism defaultLaunchMechanism;
- final Set<LaunchMechanism> validLaunchMechanisms;
-
- Platform(LaunchMechanism ... launchMechanisms) {
- this.defaultLaunchMechanism = launchMechanisms[0];
- this.validLaunchMechanisms =
- EnumSet.copyOf(Arrays.asList(launchMechanisms));
- }
-
- @SuppressWarnings("fallthrough")
- private String helperPath(String javahome, String osArch) {
- switch (this) {
- case SOLARIS:
- if (osArch.equals("x86")) { osArch = "i386"; }
- else if (osArch.equals("x86_64")) { osArch = "amd64"; }
- // fall through...
- case LINUX:
- case AIX:
- return javahome + "/lib/" + osArch + "/jspawnhelper";
-
- case BSD:
- return javahome + "/lib/jspawnhelper";
-
- default:
- throw new AssertionError("Unsupported platform: " + this);
- }
- }
-
- String helperPath() {
- return AccessController.doPrivileged(
- (PrivilegedAction<String>) () ->
- helperPath(System.getProperty("java.home"),
- System.getProperty("os.arch"))
- );
- }
-
- LaunchMechanism launchMechanism() {
- return AccessController.doPrivileged(
- (PrivilegedAction<LaunchMechanism>) () -> {
- String s = System.getProperty(
- "jdk.lang.Process.launchMechanism");
- LaunchMechanism lm;
- if (s == null) {
- lm = defaultLaunchMechanism;
- s = lm.name().toLowerCase(Locale.ENGLISH);
- } else {
- try {
- lm = LaunchMechanism.valueOf(
- s.toUpperCase(Locale.ENGLISH));
- } catch (IllegalArgumentException e) {
- lm = null;
- }
- }
- if (lm == null || !validLaunchMechanisms.contains(lm)) {
- throw new Error(
- s + " is not a supported " +
- "process launch mechanism on this platform."
- );
- }
- return lm;
- }
- );
- }
-
- static Platform get() {
- String osName = AccessController.doPrivileged(
- (PrivilegedAction<String>) () -> System.getProperty("os.name")
- );
-
- if (osName.equals("Linux")) { return LINUX; }
- if (osName.contains("OS X")) { return BSD; }
- if (osName.equals("SunOS")) { return SOLARIS; }
- if (osName.equals("AIX")) { return AIX; }
-
- throw new Error(osName + " is not a supported OS platform.");
- }
- }
-
- private static final Platform platform = Platform.get();
- private static final LaunchMechanism launchMechanism = platform.launchMechanism();
- private static final byte[] helperpath = toCString(platform.helperPath());
-
- private static byte[] toCString(String s) {
- if (s == null)
- return null;
- byte[] bytes = s.getBytes();
- byte[] result = new byte[bytes.length + 1];
- System.arraycopy(bytes, 0,
- result, 0,
- bytes.length);
- result[result.length-1] = (byte)0;
- return result;
- }
-
- /* this is for the reaping thread */
- private native int waitForProcessExit(int pid);
-
- /**
- * Creates a process. Depending on the {@code mode} flag, this is done by
- * one of the following mechanisms:
- * <pre>
- * 1 - fork(2) and exec(2)
- * 2 - posix_spawn(3P)
- * 3 - vfork(2) and exec(2)
- *
- * (4 - clone(2) and exec(2) - obsolete and currently disabled in native code)
- * </pre>
- * @param fds an array of three file descriptors.
- * Indexes 0, 1, and 2 correspond to standard input,
- * standard output and standard error, respectively. On
- * input, a value of -1 means to create a pipe to connect
- * child and parent processes. On output, a value which
- * is not -1 is the parent pipe fd corresponding to the
- * pipe which has been created. An element of this array
- * is -1 on input if and only if it is <em>not</em> -1 on
- * output.
- * @return the pid of the subprocess
- */
- private native int forkAndExec(int mode, byte[] helperpath,
- byte[] prog,
- byte[] argBlock, int argc,
- byte[] envBlock, int envc,
- byte[] dir,
- int[] fds,
- boolean redirectErrorStream)
- throws IOException;
-
- /**
- * The thread pool of "process reaper" daemon threads.
- */
- private static final Executor processReaperExecutor =
- doPrivileged((PrivilegedAction<Executor>) () -> {
-
- ThreadGroup tg = Thread.currentThread().getThreadGroup();
- while (tg.getParent() != null) tg = tg.getParent();
- ThreadGroup systemThreadGroup = tg;
-
- ThreadFactory threadFactory = grimReaper -> {
- // Our thread stack requirement is quite modest.
- Thread t = new Thread(systemThreadGroup, grimReaper,
- "process reaper", 32768);
- t.setDaemon(true);
- // A small attempt (probably futile) to avoid priority inversion
- t.setPriority(Thread.MAX_PRIORITY);
- return t;
- };
-
- return Executors.newCachedThreadPool(threadFactory);
- });
-
- UNIXProcess(final byte[] prog,
- final byte[] argBlock, final int argc,
- final byte[] envBlock, final int envc,
- final byte[] dir,
- final int[] fds,
- final boolean redirectErrorStream)
- throws IOException {
-
- pid = forkAndExec(launchMechanism.ordinal() + 1,
- helperpath,
- prog,
- argBlock, argc,
- envBlock, envc,
- dir,
- fds,
- redirectErrorStream);
-
- try {
- doPrivileged((PrivilegedExceptionAction<Void>) () -> {
- initStreams(fds);
- return null;
- });
- } catch (PrivilegedActionException ex) {
- throw (IOException) ex.getException();
- }
- }
-
- static FileDescriptor newFileDescriptor(int fd) {
- FileDescriptor fileDescriptor = new FileDescriptor();
- fdAccess.set(fileDescriptor, fd);
- return fileDescriptor;
- }
-
- void initStreams(int[] fds) throws IOException {
- switch (platform) {
- case LINUX:
- case BSD:
- stdin = (fds[0] == -1) ?
- ProcessBuilder.NullOutputStream.INSTANCE :
- new ProcessPipeOutputStream(fds[0]);
-
- stdout = (fds[1] == -1) ?
- ProcessBuilder.NullInputStream.INSTANCE :
- new ProcessPipeInputStream(fds[1]);
-
- stderr = (fds[2] == -1) ?
- ProcessBuilder.NullInputStream.INSTANCE :
- new ProcessPipeInputStream(fds[2]);
-
- processReaperExecutor.execute(() -> {
- int exitcode = waitForProcessExit(pid);
-
- synchronized (this) {
- this.exitcode = exitcode;
- this.hasExited = true;
- this.notifyAll();
- }
-
- if (stdout instanceof ProcessPipeInputStream)
- ((ProcessPipeInputStream) stdout).processExited();
-
- if (stderr instanceof ProcessPipeInputStream)
- ((ProcessPipeInputStream) stderr).processExited();
-
- if (stdin instanceof ProcessPipeOutputStream)
- ((ProcessPipeOutputStream) stdin).processExited();
- });
- break;
-
- case SOLARIS:
- stdin = (fds[0] == -1) ?
- ProcessBuilder.NullOutputStream.INSTANCE :
- new BufferedOutputStream(
- new FileOutputStream(newFileDescriptor(fds[0])));
-
- stdout = (fds[1] == -1) ?
- ProcessBuilder.NullInputStream.INSTANCE :
- new BufferedInputStream(
- stdout_inner_stream =
- new DeferredCloseInputStream(
- newFileDescriptor(fds[1])));
-
- stderr = (fds[2] == -1) ?
- ProcessBuilder.NullInputStream.INSTANCE :
- new DeferredCloseInputStream(newFileDescriptor(fds[2]));
-
- /*
- * For each subprocess forked a corresponding reaper task
- * is submitted. That task is the only thread which waits
- * for the subprocess to terminate and it doesn't hold any
- * locks while doing so. This design allows waitFor() and
- * exitStatus() to be safely executed in parallel (and they
- * need no native code).
- */
- processReaperExecutor.execute(() -> {
- int exitcode = waitForProcessExit(pid);
-
- synchronized (this) {
- this.exitcode = exitcode;
- this.hasExited = true;
- this.notifyAll();
- }
- });
- break;
-
- case AIX:
- stdin = (fds[0] == -1) ?
- ProcessBuilder.NullOutputStream.INSTANCE :
- new ProcessPipeOutputStream(fds[0]);
-
- stdout = (fds[1] == -1) ?
- ProcessBuilder.NullInputStream.INSTANCE :
- new DeferredCloseProcessPipeInputStream(fds[1]);
-
- stderr = (fds[2] == -1) ?
- ProcessBuilder.NullInputStream.INSTANCE :
- new DeferredCloseProcessPipeInputStream(fds[2]);
-
- processReaperExecutor.execute(() -> {
- int exitcode = waitForProcessExit(pid);
-
- synchronized (this) {
- this.exitcode = exitcode;
- this.hasExited = true;
- this.notifyAll();
- }
-
- if (stdout instanceof DeferredCloseProcessPipeInputStream)
- ((DeferredCloseProcessPipeInputStream) stdout).processExited();
-
- if (stderr instanceof DeferredCloseProcessPipeInputStream)
- ((DeferredCloseProcessPipeInputStream) stderr).processExited();
-
- if (stdin instanceof ProcessPipeOutputStream)
- ((ProcessPipeOutputStream) stdin).processExited();
- });
- break;
-
- default: throw new AssertionError("Unsupported platform: " + platform);
- }
- }
-
- public OutputStream getOutputStream() {
- return stdin;
- }
-
- public InputStream getInputStream() {
- return stdout;
- }
-
- public InputStream getErrorStream() {
- return stderr;
- }
-
- public synchronized int waitFor() throws InterruptedException {
- while (!hasExited) {
- wait();
- }
- return exitcode;
- }
-
- @Override
- public synchronized boolean waitFor(long timeout, TimeUnit unit)
- throws InterruptedException
- {
- if (hasExited) return true;
- if (timeout <= 0) return false;
-
- long remainingNanos = unit.toNanos(timeout);
- long deadline = System.nanoTime() + remainingNanos;
-
- do {
- // Round up to next millisecond
- wait(TimeUnit.NANOSECONDS.toMillis(remainingNanos + 999_999L));
- if (hasExited) {
- return true;
- }
- remainingNanos = deadline - System.nanoTime();
- } while (remainingNanos > 0);
- return hasExited;
- }
-
- public synchronized int exitValue() {
- if (!hasExited) {
- throw new IllegalThreadStateException("process hasn't exited");
- }
- return exitcode;
- }
-
- private static native void destroyProcess(int pid, boolean force);
-
- private void destroy(boolean force) {
- switch (platform) {
- case LINUX:
- case BSD:
- case AIX:
- // There is a risk that pid will be recycled, causing us to
- // kill the wrong process! So we only terminate processes
- // that appear to still be running. Even with this check,
- // there is an unavoidable race condition here, but the window
- // is very small, and OSes try hard to not recycle pids too
- // soon, so this is quite safe.
- synchronized (this) {
- if (!hasExited)
- destroyProcess(pid, force);
- }
- try { stdin.close(); } catch (IOException ignored) {}
- try { stdout.close(); } catch (IOException ignored) {}
- try { stderr.close(); } catch (IOException ignored) {}
- break;
-
- case SOLARIS:
- // There is a risk that pid will be recycled, causing us to
- // kill the wrong process! So we only terminate processes
- // that appear to still be running. Even with this check,
- // there is an unavoidable race condition here, but the window
- // is very small, and OSes try hard to not recycle pids too
- // soon, so this is quite safe.
- synchronized (this) {
- if (!hasExited)
- destroyProcess(pid, force);
- try {
- stdin.close();
- if (stdout_inner_stream != null)
- stdout_inner_stream.closeDeferred(stdout);
- if (stderr instanceof DeferredCloseInputStream)
- ((DeferredCloseInputStream) stderr)
- .closeDeferred(stderr);
- } catch (IOException e) {
- // ignore
- }
- }
- break;
-
- default: throw new AssertionError("Unsupported platform: " + platform);
- }
- }
-
- public void destroy() {
- destroy(false);
- }
-
- @Override
- public Process destroyForcibly() {
- destroy(true);
- return this;
- }
-
- @Override
- public long getPid() {
- return pid;
- }
-
- @Override
- public synchronized boolean isAlive() {
- return !hasExited;
- }
-
- private static native void init();
-
- static {
- init();
- }
-
- /**
- * A buffered input stream for a subprocess pipe file descriptor
- * that allows the underlying file descriptor to be reclaimed when
- * the process exits, via the processExited hook.
- *
- * This is tricky because we do not want the user-level InputStream to be
- * closed until the user invokes close(), and we need to continue to be
- * able to read any buffered data lingering in the OS pipe buffer.
- */
- private static class ProcessPipeInputStream extends BufferedInputStream {
- private final Object closeLock = new Object();
-
- ProcessPipeInputStream(int fd) {
- super(new FileInputStream(newFileDescriptor(fd)));
- }
- private static byte[] drainInputStream(InputStream in)
- throws IOException {
- int n = 0;
- int j;
- byte[] a = null;
- while ((j = in.available()) > 0) {
- a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
- n += in.read(a, n, j);
- }
- return (a == null || n == a.length) ? a : Arrays.copyOf(a, n);
- }
-
- /** Called by the process reaper thread when the process exits. */
- synchronized void processExited() {
- synchronized (closeLock) {
- try {
- InputStream in = this.in;
- // this stream is closed if and only if: in == null
- if (in != null) {
- byte[] stragglers = drainInputStream(in);
- in.close();
- this.in = (stragglers == null) ?
- ProcessBuilder.NullInputStream.INSTANCE :
- new ByteArrayInputStream(stragglers);
- }
- } catch (IOException ignored) {}
- }
- }
-
- @Override
- public void close() throws IOException {
- // BufferedInputStream#close() is not synchronized unlike most other
- // methods. Synchronizing helps avoid race with processExited().
- synchronized (closeLock) {
- super.close();
- }
- }
- }
-
- /**
- * A buffered output stream for a subprocess pipe file descriptor
- * that allows the underlying file descriptor to be reclaimed when
- * the process exits, via the processExited hook.
- */
- private static class ProcessPipeOutputStream extends BufferedOutputStream {
- ProcessPipeOutputStream(int fd) {
- super(new FileOutputStream(newFileDescriptor(fd)));
- }
-
- /** Called by the process reaper thread when the process exits. */
- synchronized void processExited() {
- OutputStream out = this.out;
- if (out != null) {
- try {
- out.close();
- } catch (IOException ignored) {
- // We know of no reason to get an IOException, but if
- // we do, there's nothing else to do but carry on.
- }
- this.out = ProcessBuilder.NullOutputStream.INSTANCE;
- }
- }
- }
-
- // A FileInputStream that supports the deferment of the actual close
- // operation until the last pending I/O operation on the stream has
- // finished. This is required on Solaris because we must close the stdin
- // and stdout streams in the destroy method in order to reclaim the
- // underlying file descriptors. Doing so, however, causes any thread
- // currently blocked in a read on one of those streams to receive an
- // IOException("Bad file number"), which is incompatible with historical
- // behavior. By deferring the close we allow any pending reads to see -1
- // (EOF) as they did before.
- //
- private static class DeferredCloseInputStream extends FileInputStream
- {
- DeferredCloseInputStream(FileDescriptor fd) {
- super(fd);
- }
-
- private Object lock = new Object(); // For the following fields
- private boolean closePending = false;
- private int useCount = 0;
- private InputStream streamToClose;
-
- private void raise() {
- synchronized (lock) {
- useCount++;
- }
- }
-
- private void lower() throws IOException {
- synchronized (lock) {
- useCount--;
- if (useCount == 0 && closePending) {
- streamToClose.close();
- }
- }
- }
-
- // stc is the actual stream to be closed; it might be this object, or
- // it might be an upstream object for which this object is downstream.
- //
- private void closeDeferred(InputStream stc) throws IOException {
- synchronized (lock) {
- if (useCount == 0) {
- stc.close();
- } else {
- closePending = true;
- streamToClose = stc;
- }
- }
- }
-
- public void close() throws IOException {
- synchronized (lock) {
- useCount = 0;
- closePending = false;
- }
- super.close();
- }
-
- public int read() throws IOException {
- raise();
- try {
- return super.read();
- } finally {
- lower();
- }
- }
-
- public int read(byte[] b) throws IOException {
- raise();
- try {
- return super.read(b);
- } finally {
- lower();
- }
- }
-
- public int read(byte[] b, int off, int len) throws IOException {
- raise();
- try {
- return super.read(b, off, len);
- } finally {
- lower();
- }
- }
-
- public long skip(long n) throws IOException {
- raise();
- try {
- return super.skip(n);
- } finally {
- lower();
- }
- }
-
- public int available() throws IOException {
- raise();
- try {
- return super.available();
- } finally {
- lower();
- }
- }
- }
-
- /**
- * A buffered input stream for a subprocess pipe file descriptor
- * that allows the underlying file descriptor to be reclaimed when
- * the process exits, via the processExited hook.
- *
- * This is tricky because we do not want the user-level InputStream to be
- * closed until the user invokes close(), and we need to continue to be
- * able to read any buffered data lingering in the OS pipe buffer.
- *
- * On AIX this is especially tricky, because the 'close()' system call
- * will block if another thread is at the same time blocked in a file
- * operation (e.g. 'read()') on the same file descriptor. We therefore
- * combine 'ProcessPipeInputStream' approach used on Linux and Bsd
- * with the DeferredCloseInputStream approach used on Solaris. This means
- * that every potentially blocking operation on the file descriptor
- * increments a counter before it is executed and decrements it once it
- * finishes. The 'close()' operation will only be executed if there are
- * no pending operations. Otherwise it is deferred after the last pending
- * operation has finished.
- *
- */
- private static class DeferredCloseProcessPipeInputStream
- extends BufferedInputStream {
-
- private final Object closeLock = new Object();
- private int useCount = 0;
- private boolean closePending = false;
-
- DeferredCloseProcessPipeInputStream(int fd) {
- super(new FileInputStream(newFileDescriptor(fd)));
- }
-
- private InputStream drainInputStream(InputStream in)
- throws IOException {
- int n = 0;
- int j;
- byte[] a = null;
- synchronized (closeLock) {
- if (buf == null) // asynchronous close()?
- return null; // discard
- j = in.available();
- }
- while (j > 0) {
- a = (a == null) ? new byte[j] : Arrays.copyOf(a, n + j);
- synchronized (closeLock) {
- if (buf == null) // asynchronous close()?
- return null; // discard
- n += in.read(a, n, j);
- j = in.available();
- }
- }
- return (a == null) ?
- ProcessBuilder.NullInputStream.INSTANCE :
- new ByteArrayInputStream(n == a.length ? a : Arrays.copyOf(a, n));
- }
-
- /** Called by the process reaper thread when the process exits. */
- synchronized void processExited() {
- try {
- InputStream in = this.in;
- if (in != null) {
- InputStream stragglers = drainInputStream(in);
- in.close();
- this.in = stragglers;
- }
- } catch (IOException ignored) { }
- }
-
- private void raise() {
- synchronized (closeLock) {
- useCount++;
- }
- }
-
- private void lower() throws IOException {
- synchronized (closeLock) {
- useCount--;
- if (useCount == 0 && closePending) {
- closePending = false;
- super.close();
- }
- }
- }
-
- @Override
- public int read() throws IOException {
- raise();
- try {
- return super.read();
- } finally {
- lower();
- }
- }
-
- @Override
- public int read(byte[] b) throws IOException {
- raise();
- try {
- return super.read(b);
- } finally {
- lower();
- }
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- raise();
- try {
- return super.read(b, off, len);
- } finally {
- lower();
- }
- }
-
- @Override
- public long skip(long n) throws IOException {
- raise();
- try {
- return super.skip(n);
- } finally {
- lower();
- }
- }
-
- @Override
- public int available() throws IOException {
- raise();
- try {
- return super.available();
- } finally {
- lower();
- }
- }
-
- @Override
- public void close() throws IOException {
- // BufferedInputStream#close() is not synchronized unlike most other
- // methods. Synchronizing helps avoid racing with drainInputStream().
- synchronized (closeLock) {
- if (useCount == 0) {
- super.close();
- }
- else {
- closePending = true;
- }
- }
- }
- }
-}
--- a/jdk/src/java.base/unix/classes/sun/security/provider/NativePRNG.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/unix/classes/sun/security/provider/NativePRNG.java Thu Jan 29 03:54:45 2015 +0000
@@ -371,8 +371,8 @@
// constructor, called only once from initIO()
private RandomIO(File seedFile, File nextFile) throws IOException {
this.seedFile = seedFile;
- seedIn = new FileInputStream(seedFile);
- nextIn = new FileInputStream(nextFile);
+ seedIn = FileInputStreamPool.getInputStream(seedFile);
+ nextIn = FileInputStreamPool.getInputStream(nextFile);
nextBuffer = new byte[BUFFER_SIZE];
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,724 @@
+/*
+ * 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
+ * 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.
+ */
+
+#undef _LARGEFILE64_SOURCE
+#define _LARGEFILE64_SOURCE 1
+
+#include "jni.h"
+#include "jvm.h"
+#include "jvm_md.h"
+#include "jni_util.h"
+#include "io_util.h"
+
+/*
+ * Platform-specific support for java.lang.Process
+ */
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <string.h>
+
+#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
+#include <spawn.h>
+#endif
+
+#include "childproc.h"
+
+/*
+ * There are 4 possible strategies we might use to "fork":
+ *
+ * - fork(2). Very portable and reliable but subject to
+ * failure due to overcommit (see the documentation on
+ * /proc/sys/vm/overcommit_memory in Linux proc(5)).
+ * This is the ancient problem of spurious failure whenever a large
+ * process starts a small subprocess.
+ *
+ * - vfork(). Using this is scary because all relevant man pages
+ * contain dire warnings, e.g. Linux vfork(2). But at least it's
+ * documented in the glibc docs and is standardized by XPG4.
+ * http://www.opengroup.org/onlinepubs/000095399/functions/vfork.html
+ * On Linux, one might think that vfork() would be implemented using
+ * the clone system call with flag CLONE_VFORK, but in fact vfork is
+ * a separate system call (which is a good sign, suggesting that
+ * vfork will continue to be supported at least on Linux).
+ * Another good sign is that glibc implements posix_spawn using
+ * vfork whenever possible. Note that we cannot use posix_spawn
+ * ourselves because there's no reliable way to close all inherited
+ * file descriptors.
+ *
+ * - clone() with flags CLONE_VM but not CLONE_THREAD. clone() is
+ * Linux-specific, but this ought to work - at least the glibc
+ * sources contain code to handle different combinations of CLONE_VM
+ * and CLONE_THREAD. However, when this was implemented, it
+ * appeared to fail on 32-bit i386 (but not 64-bit x86_64) Linux with
+ * the simple program
+ * Runtime.getRuntime().exec("/bin/true").waitFor();
+ * with:
+ * # Internal Error (os_linux_x86.cpp:683), pid=19940, tid=2934639536
+ * # Error: pthread_getattr_np failed with errno = 3 (ESRCH)
+ * We believe this is a glibc bug, reported here:
+ * http://sources.redhat.com/bugzilla/show_bug.cgi?id=10311
+ * but the glibc maintainers closed it as WONTFIX.
+ *
+ * - posix_spawn(). While posix_spawn() is a fairly elaborate and
+ * complicated system call, it can't quite do everything that the old
+ * fork()/exec() combination can do, so the only feasible way to do
+ * this, is to use posix_spawn to launch a new helper executable
+ * "jprochelper", which in turn execs the target (after cleaning
+ * up file-descriptors etc.) The end result is the same as before,
+ * a child process linked to the parent in the same way, but it
+ * avoids the problem of duplicating the parent (VM) process
+ * address space temporarily, before launching the target command.
+ *
+ * Based on the above analysis, we are currently using vfork() on
+ * Linux and spawn() on other Unix systems, but the code to use clone()
+ * and fork() remains.
+ */
+
+
+static void
+setSIGCHLDHandler(JNIEnv *env)
+{
+ /* There is a subtle difference between having the signal handler
+ * for SIGCHLD be SIG_DFL and SIG_IGN. We cannot obtain process
+ * termination information for child processes if the signal
+ * handler is SIG_IGN. It must be SIG_DFL.
+ *
+ * We used to set the SIGCHLD handler only on Linux, but it's
+ * safest to set it unconditionally.
+ *
+ * Consider what happens if java's parent process sets the SIGCHLD
+ * handler to SIG_IGN. Normally signal handlers are inherited by
+ * children, but SIGCHLD is a controversial case. Solaris appears
+ * to always reset it to SIG_DFL, but this behavior may be
+ * non-standard-compliant, and we shouldn't rely on it.
+ *
+ * References:
+ * http://www.opengroup.org/onlinepubs/7908799/xsh/exec.html
+ * http://www.pasc.org/interps/unofficial/db/p1003.1/pasc-1003.1-132.html
+ */
+ struct sigaction sa;
+ sa.sa_handler = SIG_DFL;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
+ if (sigaction(SIGCHLD, &sa, NULL) < 0)
+ JNU_ThrowInternalError(env, "Can't set SIGCHLD handler");
+}
+
+static void*
+xmalloc(JNIEnv *env, size_t size)
+{
+ void *p = malloc(size);
+ if (p == NULL)
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return p;
+}
+
+#define NEW(type, n) ((type *) xmalloc(env, (n) * sizeof(type)))
+
+/**
+ * If PATH is not defined, the OS provides some default value.
+ * Unfortunately, there's no portable way to get this value.
+ * Fortunately, it's only needed if the child has PATH while we do not.
+ */
+static const char*
+defaultPath(void)
+{
+#ifdef __solaris__
+ /* These really are the Solaris defaults! */
+ return (geteuid() == 0 || getuid() == 0) ?
+ "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" :
+ "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:";
+#else
+ return ":/bin:/usr/bin"; /* glibc */
+#endif
+}
+
+static const char*
+effectivePath(void)
+{
+ const char *s = getenv("PATH");
+ return (s != NULL) ? s : defaultPath();
+}
+
+static int
+countOccurrences(const char *s, char c)
+{
+ int count;
+ for (count = 0; *s != '\0'; s++)
+ count += (*s == c);
+ return count;
+}
+
+static const char * const *
+effectivePathv(JNIEnv *env)
+{
+ char *p;
+ int i;
+ const char *path = effectivePath();
+ int count = countOccurrences(path, ':') + 1;
+ size_t pathvsize = sizeof(const char *) * (count+1);
+ size_t pathsize = strlen(path) + 1;
+ const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize);
+
+ if (pathv == NULL)
+ return NULL;
+ p = (char *) pathv + pathvsize;
+ memcpy(p, path, pathsize);
+ /* split PATH by replacing ':' with NULs; empty components => "." */
+ for (i = 0; i < count; i++) {
+ char *q = p + strcspn(p, ":");
+ pathv[i] = (p == q) ? "." : p;
+ *q = '\0';
+ p = q + 1;
+ }
+ pathv[count] = NULL;
+ return pathv;
+}
+
+JNIEXPORT void JNICALL
+Java_java_lang_ProcessImpl_init(JNIEnv *env, jclass clazz)
+{
+ parentPathv = effectivePathv(env);
+ CHECK_NULL(parentPathv);
+ setSIGCHLDHandler(env);
+}
+
+
+#ifndef WIFEXITED
+#define WIFEXITED(status) (((status)&0xFF) == 0)
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(status) (((status)>>8)&0xFF)
+#endif
+
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0)
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(status) ((status)&0x7F)
+#endif
+
+/* Block until a child process exits and return its exit code.
+ Note, can only be called once for any given pid. */
+JNIEXPORT jint JNICALL
+Java_java_lang_ProcessImpl_waitForProcessExit(JNIEnv* env,
+ jobject junk,
+ jint pid)
+{
+ /* We used to use waitid() on Solaris, waitpid() on Linux, but
+ * waitpid() is more standard, so use it on all POSIX platforms. */
+ int status;
+ /* Wait for the child process to exit. This returns immediately if
+ the child has already exited. */
+ while (waitpid(pid, &status, 0) < 0) {
+ switch (errno) {
+ case ECHILD: return 0;
+ case EINTR: break;
+ default: return -1;
+ }
+ }
+
+ if (WIFEXITED(status)) {
+ /*
+ * The child exited normally; get its exit code.
+ */
+ return WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status)) {
+ /* The child exited because of a signal.
+ * The best value to return is 0x80 + signal number,
+ * because that is what all Unix shells do, and because
+ * it allows callers to distinguish between process exit and
+ * process death by signal.
+ * Unfortunately, the historical behavior on Solaris is to return
+ * the signal number, and we preserve this for compatibility. */
+#ifdef __solaris__
+ return WTERMSIG(status);
+#else
+ return 0x80 + WTERMSIG(status);
+#endif
+ } else {
+ /*
+ * Unknown exit code; pass it through.
+ */
+ return status;
+ }
+}
+
+static const char *
+getBytes(JNIEnv *env, jbyteArray arr)
+{
+ return arr == NULL ? NULL :
+ (const char*) (*env)->GetByteArrayElements(env, arr, NULL);
+}
+
+static void
+releaseBytes(JNIEnv *env, jbyteArray arr, const char* parr)
+{
+ if (parr != NULL)
+ (*env)->ReleaseByteArrayElements(env, arr, (jbyte*) parr, JNI_ABORT);
+}
+
+static void
+throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
+{
+ static const char * const format = "error=%d, %s";
+ const char *detail = defaultDetail;
+ char *errmsg;
+ jstring s;
+
+ if (errnum != 0) {
+ const char *s = strerror(errnum);
+ if (strcmp(s, "Unknown error") != 0)
+ detail = s;
+ }
+ /* ASCII Decimal representation uses 2.4 times as many bits as binary. */
+ errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum));
+ if (errmsg == NULL)
+ return;
+
+ sprintf(errmsg, format, errnum, detail);
+ s = JNU_NewStringPlatform(env, errmsg);
+ if (s != NULL) {
+ jobject x = JNU_NewObjectByName(env, "java/io/IOException",
+ "(Ljava/lang/String;)V", s);
+ if (x != NULL)
+ (*env)->Throw(env, x);
+ }
+ free(errmsg);
+}
+
+#ifdef DEBUG_PROCESS
+/* Debugging process code is difficult; where to write debug output? */
+static void
+debugPrint(char *format, ...)
+{
+ FILE *tty = fopen("/dev/tty", "w");
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(tty, format, ap);
+ va_end(ap);
+ fclose(tty);
+}
+#endif /* DEBUG_PROCESS */
+
+static void
+copyPipe(int from[2], int to[2])
+{
+ to[0] = from[0];
+ to[1] = from[1];
+}
+
+/* arg is an array of pointers to 0 terminated strings. array is terminated
+ * by a null element.
+ *
+ * *nelems and *nbytes receive the number of elements of array (incl 0)
+ * and total number of bytes (incl. 0)
+ * Note. An empty array will have one null element
+ * But if arg is null, then *nelems set to 0, and *nbytes to 0
+ */
+static void arraysize(const char * const *arg, int *nelems, int *nbytes)
+{
+ int i, bytes, count;
+ const char * const *a = arg;
+ char *p;
+ int *q;
+ if (arg == 0) {
+ *nelems = 0;
+ *nbytes = 0;
+ return;
+ }
+ /* count the array elements and number of bytes */
+ for (count=0, bytes=0; *a != 0; count++, a++) {
+ bytes += strlen(*a)+1;
+ }
+ *nbytes = bytes;
+ *nelems = count+1;
+}
+
+/* copy the strings from arg[] into buf, starting at given offset
+ * return new offset to next free byte
+ */
+static int copystrings(char *buf, int offset, const char * const *arg) {
+ char *p;
+ const char * const *a;
+ int count=0;
+
+ if (arg == 0) {
+ return offset;
+ }
+ for (p=buf+offset, a=arg; *a != 0; a++) {
+ int len = strlen(*a) +1;
+ memcpy(p, *a, len);
+ p += len;
+ count += len;
+ }
+ return offset+count;
+}
+
+/**
+ * We are unusually paranoid; use of clone/vfork is
+ * especially likely to tickle gcc/glibc bugs.
+ */
+#ifdef __attribute_noinline__ /* See: sys/cdefs.h */
+__attribute_noinline__
+#endif
+
+#define START_CHILD_USE_CLONE 0 /* clone() currently disabled; see above. */
+
+#ifdef START_CHILD_USE_CLONE
+static pid_t
+cloneChild(ChildStuff *c) {
+#ifdef __linux__
+#define START_CHILD_CLONE_STACK_SIZE (64 * 1024)
+ /*
+ * See clone(2).
+ * Instead of worrying about which direction the stack grows, just
+ * allocate twice as much and start the stack in the middle.
+ */
+ if ((c->clone_stack = malloc(2 * START_CHILD_CLONE_STACK_SIZE)) == NULL)
+ /* errno will be set to ENOMEM */
+ return -1;
+ return clone(childProcess,
+ c->clone_stack + START_CHILD_CLONE_STACK_SIZE,
+ CLONE_VFORK | CLONE_VM | SIGCHLD, c);
+#else
+/* not available on Solaris / Mac */
+ assert(0);
+ return -1;
+#endif
+}
+#endif
+
+static pid_t
+vforkChild(ChildStuff *c) {
+ volatile pid_t resultPid;
+
+ /*
+ * We separate the call to vfork into a separate function to make
+ * very sure to keep stack of child from corrupting stack of parent,
+ * as suggested by the scary gcc warning:
+ * warning: variable 'foo' might be clobbered by 'longjmp' or 'vfork'
+ */
+ resultPid = vfork();
+
+ if (resultPid == 0) {
+ childProcess(c);
+ }
+ assert(resultPid != 0); /* childProcess never returns */
+ return resultPid;
+}
+
+static pid_t
+forkChild(ChildStuff *c) {
+ pid_t resultPid;
+
+ /*
+ * From Solaris fork(2): In Solaris 10, a call to fork() is
+ * identical to a call to fork1(); only the calling thread is
+ * replicated in the child process. This is the POSIX-specified
+ * behavior for fork().
+ */
+ resultPid = fork();
+
+ if (resultPid == 0) {
+ childProcess(c);
+ }
+ assert(resultPid != 0); /* childProcess never returns */
+ return resultPid;
+}
+
+#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
+static pid_t
+spawnChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) {
+ pid_t resultPid;
+ jboolean isCopy;
+ int i, offset, rval, bufsize, magic;
+ char *buf, buf1[16];
+ char *hlpargs[2];
+ SpawnInfo sp;
+
+ /* need to tell helper which fd is for receiving the childstuff
+ * and which fd to send response back on
+ */
+ snprintf(buf1, sizeof(buf1), "%d:%d", c->childenv[0], c->fail[1]);
+ /* put the fd string as argument to the helper cmd */
+ hlpargs[0] = buf1;
+ hlpargs[1] = 0;
+
+ /* Following items are sent down the pipe to the helper
+ * after it is spawned.
+ * All strings are null terminated. All arrays of strings
+ * have an empty string for termination.
+ * - the ChildStuff struct
+ * - the SpawnInfo struct
+ * - the argv strings array
+ * - the envv strings array
+ * - the home directory string
+ * - the parentPath string
+ * - the parentPathv array
+ */
+ /* First calculate the sizes */
+ arraysize(c->argv, &sp.nargv, &sp.argvBytes);
+ bufsize = sp.argvBytes;
+ arraysize(c->envv, &sp.nenvv, &sp.envvBytes);
+ bufsize += sp.envvBytes;
+ sp.dirlen = c->pdir == 0 ? 0 : strlen(c->pdir)+1;
+ bufsize += sp.dirlen;
+ arraysize(parentPathv, &sp.nparentPathv, &sp.parentPathvBytes);
+ bufsize += sp.parentPathvBytes;
+ /* We need to clear FD_CLOEXEC if set in the fds[].
+ * Files are created FD_CLOEXEC in Java.
+ * Otherwise, they will be closed when the target gets exec'd */
+ for (i=0; i<3; i++) {
+ if (c->fds[i] != -1) {
+ int flags = fcntl(c->fds[i], F_GETFD);
+ if (flags & FD_CLOEXEC) {
+ fcntl(c->fds[i], F_SETFD, flags & (~1));
+ }
+ }
+ }
+
+ rval = posix_spawn(&resultPid, helperpath, 0, 0, (char * const *) hlpargs, environ);
+
+ if (rval != 0) {
+ return -1;
+ }
+
+ /* now the lengths are known, copy the data */
+ buf = NEW(char, bufsize);
+ if (buf == 0) {
+ return -1;
+ }
+ offset = copystrings(buf, 0, &c->argv[0]);
+ offset = copystrings(buf, offset, &c->envv[0]);
+ memcpy(buf+offset, c->pdir, sp.dirlen);
+ offset += sp.dirlen;
+ offset = copystrings(buf, offset, parentPathv);
+ assert(offset == bufsize);
+
+ magic = magicNumber();
+
+ /* write the two structs and the data buffer */
+ write(c->childenv[1], (char *)&magic, sizeof(magic)); // magic number first
+ write(c->childenv[1], (char *)c, sizeof(*c));
+ write(c->childenv[1], (char *)&sp, sizeof(sp));
+ write(c->childenv[1], buf, bufsize);
+ free(buf);
+
+ /* In this mode an external main() in invoked which calls back into
+ * childProcess() in this file, rather than directly
+ * via the statement below */
+ return resultPid;
+}
+#endif
+
+/*
+ * Start a child process running function childProcess.
+ * This function only returns in the parent.
+ */
+static pid_t
+startChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) {
+ switch (c->mode) {
+ case MODE_VFORK:
+ return vforkChild(c);
+ case MODE_FORK:
+ return forkChild(c);
+#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
+ case MODE_POSIX_SPAWN:
+ return spawnChild(env, process, c, helperpath);
+#endif
+ default:
+ return -1;
+ }
+}
+
+JNIEXPORT jint JNICALL
+Java_java_lang_ProcessImpl_forkAndExec(JNIEnv *env,
+ jobject process,
+ jint mode,
+ jbyteArray helperpath,
+ jbyteArray prog,
+ jbyteArray argBlock, jint argc,
+ jbyteArray envBlock, jint envc,
+ jbyteArray dir,
+ jintArray std_fds,
+ jboolean redirectErrorStream)
+{
+ int errnum;
+ int resultPid = -1;
+ int in[2], out[2], err[2], fail[2], childenv[2];
+ jint *fds = NULL;
+ const char *phelperpath = NULL;
+ const char *pprog = NULL;
+ const char *pargBlock = NULL;
+ const char *penvBlock = NULL;
+ ChildStuff *c;
+
+ in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1;
+ childenv[0] = childenv[1] = -1;
+
+ if ((c = NEW(ChildStuff, 1)) == NULL) return -1;
+ c->argv = NULL;
+ c->envv = NULL;
+ c->pdir = NULL;
+ c->clone_stack = NULL;
+
+ /* Convert prog + argBlock into a char ** argv.
+ * Add one word room for expansion of argv for use by
+ * execve_as_traditional_shell_script.
+ * This word is also used when using spawn mode
+ */
+ assert(prog != NULL && argBlock != NULL);
+ if ((phelperpath = getBytes(env, helperpath)) == NULL) goto Catch;
+ if ((pprog = getBytes(env, prog)) == NULL) goto Catch;
+ if ((pargBlock = getBytes(env, argBlock)) == NULL) goto Catch;
+ if ((c->argv = NEW(const char *, argc + 3)) == NULL) goto Catch;
+ c->argv[0] = pprog;
+ c->argc = argc + 2;
+ initVectorFromBlock(c->argv+1, pargBlock, argc);
+
+ if (envBlock != NULL) {
+ /* Convert envBlock into a char ** envv */
+ if ((penvBlock = getBytes(env, envBlock)) == NULL) goto Catch;
+ if ((c->envv = NEW(const char *, envc + 1)) == NULL) goto Catch;
+ initVectorFromBlock(c->envv, penvBlock, envc);
+ }
+
+ if (dir != NULL) {
+ if ((c->pdir = getBytes(env, dir)) == NULL) goto Catch;
+ }
+
+ assert(std_fds != NULL);
+ fds = (*env)->GetIntArrayElements(env, std_fds, NULL);
+ if (fds == NULL) goto Catch;
+
+ if ((fds[0] == -1 && pipe(in) < 0) ||
+ (fds[1] == -1 && pipe(out) < 0) ||
+ (fds[2] == -1 && pipe(err) < 0) ||
+ (pipe(childenv) < 0) ||
+ (pipe(fail) < 0)) {
+ throwIOException(env, errno, "Bad file descriptor");
+ goto Catch;
+ }
+ c->fds[0] = fds[0];
+ c->fds[1] = fds[1];
+ c->fds[2] = fds[2];
+
+ copyPipe(in, c->in);
+ copyPipe(out, c->out);
+ copyPipe(err, c->err);
+ copyPipe(fail, c->fail);
+ copyPipe(childenv, c->childenv);
+
+ c->redirectErrorStream = redirectErrorStream;
+ c->mode = mode;
+
+ resultPid = startChild(env, process, c, phelperpath);
+ assert(resultPid != 0);
+
+ if (resultPid < 0) {
+ switch (c->mode) {
+ case MODE_VFORK:
+ throwIOException(env, errno, "vfork failed");
+ break;
+ case MODE_FORK:
+ throwIOException(env, errno, "fork failed");
+ break;
+ case MODE_POSIX_SPAWN:
+ throwIOException(env, errno, "spawn failed");
+ break;
+ }
+ goto Catch;
+ }
+ close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec (childproc.c) */
+
+ switch (readFully(fail[0], &errnum, sizeof(errnum))) {
+ case 0: break; /* Exec succeeded */
+ case sizeof(errnum):
+ waitpid(resultPid, NULL, 0);
+ throwIOException(env, errnum, "Exec failed");
+ goto Catch;
+ default:
+ throwIOException(env, errno, "Read failed");
+ goto Catch;
+ }
+
+ fds[0] = (in [1] != -1) ? in [1] : -1;
+ fds[1] = (out[0] != -1) ? out[0] : -1;
+ fds[2] = (err[0] != -1) ? err[0] : -1;
+
+ Finally:
+ free(c->clone_stack);
+
+ /* Always clean up the child's side of the pipes */
+ closeSafely(in [0]);
+ closeSafely(out[1]);
+ closeSafely(err[1]);
+
+ /* Always clean up fail and childEnv descriptors */
+ closeSafely(fail[0]);
+ closeSafely(fail[1]);
+ closeSafely(childenv[0]);
+ closeSafely(childenv[1]);
+
+ releaseBytes(env, helperpath, phelperpath);
+ releaseBytes(env, prog, pprog);
+ releaseBytes(env, argBlock, pargBlock);
+ releaseBytes(env, envBlock, penvBlock);
+ releaseBytes(env, dir, c->pdir);
+
+ free(c->argv);
+ free(c->envv);
+ free(c);
+
+ if (fds != NULL)
+ (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0);
+
+ return resultPid;
+
+ Catch:
+ /* Clean up the parent's side of the pipes in case of failure only */
+ closeSafely(in [1]); in[1] = -1;
+ closeSafely(out[0]); out[0] = -1;
+ closeSafely(err[0]); err[0] = -1;
+ goto Finally;
+}
+
+JNIEXPORT void JNICALL
+Java_java_lang_ProcessImpl_destroyProcess(JNIEnv *env,
+ jobject junk,
+ jint pid,
+ jboolean force)
+{
+ int sig = (force == JNI_TRUE) ? SIGKILL : SIGTERM;
+ kill(pid, sig);
+}
--- a/jdk/src/java.base/unix/native/libjava/UNIXProcess_md.c Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,724 +0,0 @@
-/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#undef _LARGEFILE64_SOURCE
-#define _LARGEFILE64_SOURCE 1
-
-#include "jni.h"
-#include "jvm.h"
-#include "jvm_md.h"
-#include "jni_util.h"
-#include "io_util.h"
-
-/*
- * Platform-specific support for java.lang.Process
- */
-#include <assert.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <ctype.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <string.h>
-
-#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
-#include <spawn.h>
-#endif
-
-#include "childproc.h"
-
-/*
- * There are 4 possible strategies we might use to "fork":
- *
- * - fork(2). Very portable and reliable but subject to
- * failure due to overcommit (see the documentation on
- * /proc/sys/vm/overcommit_memory in Linux proc(5)).
- * This is the ancient problem of spurious failure whenever a large
- * process starts a small subprocess.
- *
- * - vfork(). Using this is scary because all relevant man pages
- * contain dire warnings, e.g. Linux vfork(2). But at least it's
- * documented in the glibc docs and is standardized by XPG4.
- * http://www.opengroup.org/onlinepubs/000095399/functions/vfork.html
- * On Linux, one might think that vfork() would be implemented using
- * the clone system call with flag CLONE_VFORK, but in fact vfork is
- * a separate system call (which is a good sign, suggesting that
- * vfork will continue to be supported at least on Linux).
- * Another good sign is that glibc implements posix_spawn using
- * vfork whenever possible. Note that we cannot use posix_spawn
- * ourselves because there's no reliable way to close all inherited
- * file descriptors.
- *
- * - clone() with flags CLONE_VM but not CLONE_THREAD. clone() is
- * Linux-specific, but this ought to work - at least the glibc
- * sources contain code to handle different combinations of CLONE_VM
- * and CLONE_THREAD. However, when this was implemented, it
- * appeared to fail on 32-bit i386 (but not 64-bit x86_64) Linux with
- * the simple program
- * Runtime.getRuntime().exec("/bin/true").waitFor();
- * with:
- * # Internal Error (os_linux_x86.cpp:683), pid=19940, tid=2934639536
- * # Error: pthread_getattr_np failed with errno = 3 (ESRCH)
- * We believe this is a glibc bug, reported here:
- * http://sources.redhat.com/bugzilla/show_bug.cgi?id=10311
- * but the glibc maintainers closed it as WONTFIX.
- *
- * - posix_spawn(). While posix_spawn() is a fairly elaborate and
- * complicated system call, it can't quite do everything that the old
- * fork()/exec() combination can do, so the only feasible way to do
- * this, is to use posix_spawn to launch a new helper executable
- * "jprochelper", which in turn execs the target (after cleaning
- * up file-descriptors etc.) The end result is the same as before,
- * a child process linked to the parent in the same way, but it
- * avoids the problem of duplicating the parent (VM) process
- * address space temporarily, before launching the target command.
- *
- * Based on the above analysis, we are currently using vfork() on
- * Linux and spawn() on other Unix systems, but the code to use clone()
- * and fork() remains.
- */
-
-
-static void
-setSIGCHLDHandler(JNIEnv *env)
-{
- /* There is a subtle difference between having the signal handler
- * for SIGCHLD be SIG_DFL and SIG_IGN. We cannot obtain process
- * termination information for child processes if the signal
- * handler is SIG_IGN. It must be SIG_DFL.
- *
- * We used to set the SIGCHLD handler only on Linux, but it's
- * safest to set it unconditionally.
- *
- * Consider what happens if java's parent process sets the SIGCHLD
- * handler to SIG_IGN. Normally signal handlers are inherited by
- * children, but SIGCHLD is a controversial case. Solaris appears
- * to always reset it to SIG_DFL, but this behavior may be
- * non-standard-compliant, and we shouldn't rely on it.
- *
- * References:
- * http://www.opengroup.org/onlinepubs/7908799/xsh/exec.html
- * http://www.pasc.org/interps/unofficial/db/p1003.1/pasc-1003.1-132.html
- */
- struct sigaction sa;
- sa.sa_handler = SIG_DFL;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
- if (sigaction(SIGCHLD, &sa, NULL) < 0)
- JNU_ThrowInternalError(env, "Can't set SIGCHLD handler");
-}
-
-static void*
-xmalloc(JNIEnv *env, size_t size)
-{
- void *p = malloc(size);
- if (p == NULL)
- JNU_ThrowOutOfMemoryError(env, NULL);
- return p;
-}
-
-#define NEW(type, n) ((type *) xmalloc(env, (n) * sizeof(type)))
-
-/**
- * If PATH is not defined, the OS provides some default value.
- * Unfortunately, there's no portable way to get this value.
- * Fortunately, it's only needed if the child has PATH while we do not.
- */
-static const char*
-defaultPath(void)
-{
-#ifdef __solaris__
- /* These really are the Solaris defaults! */
- return (geteuid() == 0 || getuid() == 0) ?
- "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" :
- "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:";
-#else
- return ":/bin:/usr/bin"; /* glibc */
-#endif
-}
-
-static const char*
-effectivePath(void)
-{
- const char *s = getenv("PATH");
- return (s != NULL) ? s : defaultPath();
-}
-
-static int
-countOccurrences(const char *s, char c)
-{
- int count;
- for (count = 0; *s != '\0'; s++)
- count += (*s == c);
- return count;
-}
-
-static const char * const *
-effectivePathv(JNIEnv *env)
-{
- char *p;
- int i;
- const char *path = effectivePath();
- int count = countOccurrences(path, ':') + 1;
- size_t pathvsize = sizeof(const char *) * (count+1);
- size_t pathsize = strlen(path) + 1;
- const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize);
-
- if (pathv == NULL)
- return NULL;
- p = (char *) pathv + pathvsize;
- memcpy(p, path, pathsize);
- /* split PATH by replacing ':' with NULs; empty components => "." */
- for (i = 0; i < count; i++) {
- char *q = p + strcspn(p, ":");
- pathv[i] = (p == q) ? "." : p;
- *q = '\0';
- p = q + 1;
- }
- pathv[count] = NULL;
- return pathv;
-}
-
-JNIEXPORT void JNICALL
-Java_java_lang_UNIXProcess_init(JNIEnv *env, jclass clazz)
-{
- parentPathv = effectivePathv(env);
- CHECK_NULL(parentPathv);
- setSIGCHLDHandler(env);
-}
-
-
-#ifndef WIFEXITED
-#define WIFEXITED(status) (((status)&0xFF) == 0)
-#endif
-
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(status) (((status)>>8)&0xFF)
-#endif
-
-#ifndef WIFSIGNALED
-#define WIFSIGNALED(status) (((status)&0xFF) > 0 && ((status)&0xFF00) == 0)
-#endif
-
-#ifndef WTERMSIG
-#define WTERMSIG(status) ((status)&0x7F)
-#endif
-
-/* Block until a child process exits and return its exit code.
- Note, can only be called once for any given pid. */
-JNIEXPORT jint JNICALL
-Java_java_lang_UNIXProcess_waitForProcessExit(JNIEnv* env,
- jobject junk,
- jint pid)
-{
- /* We used to use waitid() on Solaris, waitpid() on Linux, but
- * waitpid() is more standard, so use it on all POSIX platforms. */
- int status;
- /* Wait for the child process to exit. This returns immediately if
- the child has already exited. */
- while (waitpid(pid, &status, 0) < 0) {
- switch (errno) {
- case ECHILD: return 0;
- case EINTR: break;
- default: return -1;
- }
- }
-
- if (WIFEXITED(status)) {
- /*
- * The child exited normally; get its exit code.
- */
- return WEXITSTATUS(status);
- } else if (WIFSIGNALED(status)) {
- /* The child exited because of a signal.
- * The best value to return is 0x80 + signal number,
- * because that is what all Unix shells do, and because
- * it allows callers to distinguish between process exit and
- * process death by signal.
- * Unfortunately, the historical behavior on Solaris is to return
- * the signal number, and we preserve this for compatibility. */
-#ifdef __solaris__
- return WTERMSIG(status);
-#else
- return 0x80 + WTERMSIG(status);
-#endif
- } else {
- /*
- * Unknown exit code; pass it through.
- */
- return status;
- }
-}
-
-static const char *
-getBytes(JNIEnv *env, jbyteArray arr)
-{
- return arr == NULL ? NULL :
- (const char*) (*env)->GetByteArrayElements(env, arr, NULL);
-}
-
-static void
-releaseBytes(JNIEnv *env, jbyteArray arr, const char* parr)
-{
- if (parr != NULL)
- (*env)->ReleaseByteArrayElements(env, arr, (jbyte*) parr, JNI_ABORT);
-}
-
-static void
-throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
-{
- static const char * const format = "error=%d, %s";
- const char *detail = defaultDetail;
- char *errmsg;
- jstring s;
-
- if (errnum != 0) {
- const char *s = strerror(errnum);
- if (strcmp(s, "Unknown error") != 0)
- detail = s;
- }
- /* ASCII Decimal representation uses 2.4 times as many bits as binary. */
- errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum));
- if (errmsg == NULL)
- return;
-
- sprintf(errmsg, format, errnum, detail);
- s = JNU_NewStringPlatform(env, errmsg);
- if (s != NULL) {
- jobject x = JNU_NewObjectByName(env, "java/io/IOException",
- "(Ljava/lang/String;)V", s);
- if (x != NULL)
- (*env)->Throw(env, x);
- }
- free(errmsg);
-}
-
-#ifdef DEBUG_PROCESS
-/* Debugging process code is difficult; where to write debug output? */
-static void
-debugPrint(char *format, ...)
-{
- FILE *tty = fopen("/dev/tty", "w");
- va_list ap;
- va_start(ap, format);
- vfprintf(tty, format, ap);
- va_end(ap);
- fclose(tty);
-}
-#endif /* DEBUG_PROCESS */
-
-static void
-copyPipe(int from[2], int to[2])
-{
- to[0] = from[0];
- to[1] = from[1];
-}
-
-/* arg is an array of pointers to 0 terminated strings. array is terminated
- * by a null element.
- *
- * *nelems and *nbytes receive the number of elements of array (incl 0)
- * and total number of bytes (incl. 0)
- * Note. An empty array will have one null element
- * But if arg is null, then *nelems set to 0, and *nbytes to 0
- */
-static void arraysize(const char * const *arg, int *nelems, int *nbytes)
-{
- int i, bytes, count;
- const char * const *a = arg;
- char *p;
- int *q;
- if (arg == 0) {
- *nelems = 0;
- *nbytes = 0;
- return;
- }
- /* count the array elements and number of bytes */
- for (count=0, bytes=0; *a != 0; count++, a++) {
- bytes += strlen(*a)+1;
- }
- *nbytes = bytes;
- *nelems = count+1;
-}
-
-/* copy the strings from arg[] into buf, starting at given offset
- * return new offset to next free byte
- */
-static int copystrings(char *buf, int offset, const char * const *arg) {
- char *p;
- const char * const *a;
- int count=0;
-
- if (arg == 0) {
- return offset;
- }
- for (p=buf+offset, a=arg; *a != 0; a++) {
- int len = strlen(*a) +1;
- memcpy(p, *a, len);
- p += len;
- count += len;
- }
- return offset+count;
-}
-
-/**
- * We are unusually paranoid; use of clone/vfork is
- * especially likely to tickle gcc/glibc bugs.
- */
-#ifdef __attribute_noinline__ /* See: sys/cdefs.h */
-__attribute_noinline__
-#endif
-
-#define START_CHILD_USE_CLONE 0 /* clone() currently disabled; see above. */
-
-#ifdef START_CHILD_USE_CLONE
-static pid_t
-cloneChild(ChildStuff *c) {
-#ifdef __linux__
-#define START_CHILD_CLONE_STACK_SIZE (64 * 1024)
- /*
- * See clone(2).
- * Instead of worrying about which direction the stack grows, just
- * allocate twice as much and start the stack in the middle.
- */
- if ((c->clone_stack = malloc(2 * START_CHILD_CLONE_STACK_SIZE)) == NULL)
- /* errno will be set to ENOMEM */
- return -1;
- return clone(childProcess,
- c->clone_stack + START_CHILD_CLONE_STACK_SIZE,
- CLONE_VFORK | CLONE_VM | SIGCHLD, c);
-#else
-/* not available on Solaris / Mac */
- assert(0);
- return -1;
-#endif
-}
-#endif
-
-static pid_t
-vforkChild(ChildStuff *c) {
- volatile pid_t resultPid;
-
- /*
- * We separate the call to vfork into a separate function to make
- * very sure to keep stack of child from corrupting stack of parent,
- * as suggested by the scary gcc warning:
- * warning: variable 'foo' might be clobbered by 'longjmp' or 'vfork'
- */
- resultPid = vfork();
-
- if (resultPid == 0) {
- childProcess(c);
- }
- assert(resultPid != 0); /* childProcess never returns */
- return resultPid;
-}
-
-static pid_t
-forkChild(ChildStuff *c) {
- pid_t resultPid;
-
- /*
- * From Solaris fork(2): In Solaris 10, a call to fork() is
- * identical to a call to fork1(); only the calling thread is
- * replicated in the child process. This is the POSIX-specified
- * behavior for fork().
- */
- resultPid = fork();
-
- if (resultPid == 0) {
- childProcess(c);
- }
- assert(resultPid != 0); /* childProcess never returns */
- return resultPid;
-}
-
-#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
-static pid_t
-spawnChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) {
- pid_t resultPid;
- jboolean isCopy;
- int i, offset, rval, bufsize, magic;
- char *buf, buf1[16];
- char *hlpargs[2];
- SpawnInfo sp;
-
- /* need to tell helper which fd is for receiving the childstuff
- * and which fd to send response back on
- */
- snprintf(buf1, sizeof(buf1), "%d:%d", c->childenv[0], c->fail[1]);
- /* put the fd string as argument to the helper cmd */
- hlpargs[0] = buf1;
- hlpargs[1] = 0;
-
- /* Following items are sent down the pipe to the helper
- * after it is spawned.
- * All strings are null terminated. All arrays of strings
- * have an empty string for termination.
- * - the ChildStuff struct
- * - the SpawnInfo struct
- * - the argv strings array
- * - the envv strings array
- * - the home directory string
- * - the parentPath string
- * - the parentPathv array
- */
- /* First calculate the sizes */
- arraysize(c->argv, &sp.nargv, &sp.argvBytes);
- bufsize = sp.argvBytes;
- arraysize(c->envv, &sp.nenvv, &sp.envvBytes);
- bufsize += sp.envvBytes;
- sp.dirlen = c->pdir == 0 ? 0 : strlen(c->pdir)+1;
- bufsize += sp.dirlen;
- arraysize(parentPathv, &sp.nparentPathv, &sp.parentPathvBytes);
- bufsize += sp.parentPathvBytes;
- /* We need to clear FD_CLOEXEC if set in the fds[].
- * Files are created FD_CLOEXEC in Java.
- * Otherwise, they will be closed when the target gets exec'd */
- for (i=0; i<3; i++) {
- if (c->fds[i] != -1) {
- int flags = fcntl(c->fds[i], F_GETFD);
- if (flags & FD_CLOEXEC) {
- fcntl(c->fds[i], F_SETFD, flags & (~1));
- }
- }
- }
-
- rval = posix_spawn(&resultPid, helperpath, 0, 0, (char * const *) hlpargs, environ);
-
- if (rval != 0) {
- return -1;
- }
-
- /* now the lengths are known, copy the data */
- buf = NEW(char, bufsize);
- if (buf == 0) {
- return -1;
- }
- offset = copystrings(buf, 0, &c->argv[0]);
- offset = copystrings(buf, offset, &c->envv[0]);
- memcpy(buf+offset, c->pdir, sp.dirlen);
- offset += sp.dirlen;
- offset = copystrings(buf, offset, parentPathv);
- assert(offset == bufsize);
-
- magic = magicNumber();
-
- /* write the two structs and the data buffer */
- write(c->childenv[1], (char *)&magic, sizeof(magic)); // magic number first
- write(c->childenv[1], (char *)c, sizeof(*c));
- write(c->childenv[1], (char *)&sp, sizeof(sp));
- write(c->childenv[1], buf, bufsize);
- free(buf);
-
- /* In this mode an external main() in invoked which calls back into
- * childProcess() in this file, rather than directly
- * via the statement below */
- return resultPid;
-}
-#endif
-
-/*
- * Start a child process running function childProcess.
- * This function only returns in the parent.
- */
-static pid_t
-startChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) {
- switch (c->mode) {
- case MODE_VFORK:
- return vforkChild(c);
- case MODE_FORK:
- return forkChild(c);
-#if defined(__solaris__) || defined(_ALLBSD_SOURCE) || defined(_AIX)
- case MODE_POSIX_SPAWN:
- return spawnChild(env, process, c, helperpath);
-#endif
- default:
- return -1;
- }
-}
-
-JNIEXPORT jint JNICALL
-Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env,
- jobject process,
- jint mode,
- jbyteArray helperpath,
- jbyteArray prog,
- jbyteArray argBlock, jint argc,
- jbyteArray envBlock, jint envc,
- jbyteArray dir,
- jintArray std_fds,
- jboolean redirectErrorStream)
-{
- int errnum;
- int resultPid = -1;
- int in[2], out[2], err[2], fail[2], childenv[2];
- jint *fds = NULL;
- const char *phelperpath = NULL;
- const char *pprog = NULL;
- const char *pargBlock = NULL;
- const char *penvBlock = NULL;
- ChildStuff *c;
-
- in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1;
- childenv[0] = childenv[1] = -1;
-
- if ((c = NEW(ChildStuff, 1)) == NULL) return -1;
- c->argv = NULL;
- c->envv = NULL;
- c->pdir = NULL;
- c->clone_stack = NULL;
-
- /* Convert prog + argBlock into a char ** argv.
- * Add one word room for expansion of argv for use by
- * execve_as_traditional_shell_script.
- * This word is also used when using spawn mode
- */
- assert(prog != NULL && argBlock != NULL);
- if ((phelperpath = getBytes(env, helperpath)) == NULL) goto Catch;
- if ((pprog = getBytes(env, prog)) == NULL) goto Catch;
- if ((pargBlock = getBytes(env, argBlock)) == NULL) goto Catch;
- if ((c->argv = NEW(const char *, argc + 3)) == NULL) goto Catch;
- c->argv[0] = pprog;
- c->argc = argc + 2;
- initVectorFromBlock(c->argv+1, pargBlock, argc);
-
- if (envBlock != NULL) {
- /* Convert envBlock into a char ** envv */
- if ((penvBlock = getBytes(env, envBlock)) == NULL) goto Catch;
- if ((c->envv = NEW(const char *, envc + 1)) == NULL) goto Catch;
- initVectorFromBlock(c->envv, penvBlock, envc);
- }
-
- if (dir != NULL) {
- if ((c->pdir = getBytes(env, dir)) == NULL) goto Catch;
- }
-
- assert(std_fds != NULL);
- fds = (*env)->GetIntArrayElements(env, std_fds, NULL);
- if (fds == NULL) goto Catch;
-
- if ((fds[0] == -1 && pipe(in) < 0) ||
- (fds[1] == -1 && pipe(out) < 0) ||
- (fds[2] == -1 && pipe(err) < 0) ||
- (pipe(childenv) < 0) ||
- (pipe(fail) < 0)) {
- throwIOException(env, errno, "Bad file descriptor");
- goto Catch;
- }
- c->fds[0] = fds[0];
- c->fds[1] = fds[1];
- c->fds[2] = fds[2];
-
- copyPipe(in, c->in);
- copyPipe(out, c->out);
- copyPipe(err, c->err);
- copyPipe(fail, c->fail);
- copyPipe(childenv, c->childenv);
-
- c->redirectErrorStream = redirectErrorStream;
- c->mode = mode;
-
- resultPid = startChild(env, process, c, phelperpath);
- assert(resultPid != 0);
-
- if (resultPid < 0) {
- switch (c->mode) {
- case MODE_VFORK:
- throwIOException(env, errno, "vfork failed");
- break;
- case MODE_FORK:
- throwIOException(env, errno, "fork failed");
- break;
- case MODE_POSIX_SPAWN:
- throwIOException(env, errno, "spawn failed");
- break;
- }
- goto Catch;
- }
- close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec (childproc.c) */
-
- switch (readFully(fail[0], &errnum, sizeof(errnum))) {
- case 0: break; /* Exec succeeded */
- case sizeof(errnum):
- waitpid(resultPid, NULL, 0);
- throwIOException(env, errnum, "Exec failed");
- goto Catch;
- default:
- throwIOException(env, errno, "Read failed");
- goto Catch;
- }
-
- fds[0] = (in [1] != -1) ? in [1] : -1;
- fds[1] = (out[0] != -1) ? out[0] : -1;
- fds[2] = (err[0] != -1) ? err[0] : -1;
-
- Finally:
- free(c->clone_stack);
-
- /* Always clean up the child's side of the pipes */
- closeSafely(in [0]);
- closeSafely(out[1]);
- closeSafely(err[1]);
-
- /* Always clean up fail and childEnv descriptors */
- closeSafely(fail[0]);
- closeSafely(fail[1]);
- closeSafely(childenv[0]);
- closeSafely(childenv[1]);
-
- releaseBytes(env, helperpath, phelperpath);
- releaseBytes(env, prog, pprog);
- releaseBytes(env, argBlock, pargBlock);
- releaseBytes(env, envBlock, penvBlock);
- releaseBytes(env, dir, c->pdir);
-
- free(c->argv);
- free(c->envv);
- free(c);
-
- if (fds != NULL)
- (*env)->ReleaseIntArrayElements(env, std_fds, fds, 0);
-
- return resultPid;
-
- Catch:
- /* Clean up the parent's side of the pipes in case of failure only */
- closeSafely(in [1]); in[1] = -1;
- closeSafely(out[0]); out[0] = -1;
- closeSafely(err[0]); err[0] = -1;
- goto Finally;
-}
-
-JNIEXPORT void JNICALL
-Java_java_lang_UNIXProcess_destroyProcess(JNIEnv *env,
- jobject junk,
- jint pid,
- jboolean force)
-{
- int sig = (force == JNI_TRUE) ? SIGKILL : SIGTERM;
- kill(pid, sig);
-}
--- a/jdk/src/java.base/unix/native/libjava/childproc.h Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/unix/native/libjava/childproc.h Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,7 @@
} while((_result == -1) && (errno == EINTR)); \
} while(0)
-/* These numbers must be the same as the Enum in UNIXProcess.java
+/* These numbers must be the same as the Enum in ProcessImpl.java
* Must be a better way of doing this.
*/
#define MODE_FORK 1
--- a/jdk/src/java.base/unix/native/libjava/java_props_macosx.c Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,349 +0,0 @@
-/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <dlfcn.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <Security/AuthSession.h>
-#include <CoreFoundation/CoreFoundation.h>
-#include <SystemConfiguration/SystemConfiguration.h>
-#include <Foundation/Foundation.h>
-
-#include "java_props_macosx.h"
-
-
-// need dlopen/dlsym trick to avoid pulling in JavaRuntimeSupport before libjava.dylib is loaded
-static void *getJRSFramework() {
- static void *jrsFwk = NULL;
- if (jrsFwk == NULL) {
- jrsFwk = dlopen("/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport", RTLD_LAZY | RTLD_LOCAL);
- }
- return jrsFwk;
-}
-
-char *getPosixLocale(int cat) {
- char *lc = setlocale(cat, NULL);
- if ((lc == NULL) || (strcmp(lc, "C") == 0)) {
- lc = getenv("LANG");
- }
- if (lc == NULL) return NULL;
- return strdup(lc);
-}
-
-#define LOCALEIDLENGTH 128
-char *getMacOSXLocale(int cat) {
- switch (cat) {
- case LC_MESSAGES:
- {
- void *jrsFwk = getJRSFramework();
- if (jrsFwk == NULL) return NULL;
-
- char *(*JRSCopyPrimaryLanguage)() = dlsym(jrsFwk, "JRSCopyPrimaryLanguage");
- char *primaryLanguage = JRSCopyPrimaryLanguage ? JRSCopyPrimaryLanguage() : NULL;
- if (primaryLanguage == NULL) return NULL;
-
- char *(*JRSCopyCanonicalLanguageForPrimaryLanguage)(char *) = dlsym(jrsFwk, "JRSCopyCanonicalLanguageForPrimaryLanguage");
- char *canonicalLanguage = JRSCopyCanonicalLanguageForPrimaryLanguage ? JRSCopyCanonicalLanguageForPrimaryLanguage(primaryLanguage) : NULL;
- free (primaryLanguage);
-
- return canonicalLanguage;
- }
- break;
- default:
- {
- char localeString[LOCALEIDLENGTH];
- if (CFStringGetCString(CFLocaleGetIdentifier(CFLocaleCopyCurrent()),
- localeString, LOCALEIDLENGTH, CFStringGetSystemEncoding())) {
- return strdup(localeString);
- }
- }
- break;
- }
-
- return NULL;
-}
-
-char *setupMacOSXLocale(int cat) {
- char * ret = getMacOSXLocale(cat);
-
- if (cat == LC_MESSAGES && ret != NULL) {
- void *jrsFwk = getJRSFramework();
- if (jrsFwk != NULL) {
- void (*JRSSetDefaultLocalization)(char *) = dlsym(jrsFwk, "JRSSetDefaultLocalization");
- if (JRSSetDefaultLocalization) JRSSetDefaultLocalization(ret);
- }
- }
-
- if (ret == NULL) {
- return getPosixLocale(cat);
- } else {
- return ret;
- }
-}
-
-int isInAquaSession() {
- // environment variable to bypass the aqua session check
- char *ev = getenv("AWT_FORCE_HEADFUL");
- if (ev && (strncasecmp(ev, "true", 4) == 0)) {
- // if "true" then tell the caller we're in an Aqua session without actually checking
- return 1;
- }
- // Is the WindowServer available?
- SecuritySessionId session_id;
- SessionAttributeBits session_info;
- OSStatus status = SessionGetInfo(callerSecuritySession, &session_id, &session_info);
- if (status == noErr) {
- if (session_info & sessionHasGraphicAccess) {
- return 1;
- }
- }
- return 0;
-}
-
-void setOSNameAndVersion(java_props_t *sprops) {
- /* Don't rely on JRSCopyOSName because there's no guarantee the value will
- * remain the same, or even if the JRS functions will continue to be part of
- * Mac OS X. So hardcode os_name, and fill in os_version if we can.
- */
- sprops->os_name = strdup("Mac OS X");
-
- void *jrsFwk = getJRSFramework();
- if (jrsFwk != NULL) {
- char *(*copyOSVersion)() = dlsym(jrsFwk, "JRSCopyOSVersion");
- if (copyOSVersion != NULL) {
- sprops->os_version = copyOSVersion();
- return;
- }
- }
- sprops->os_version = strdup("Unknown");
-}
-
-
-static Boolean getProxyInfoForProtocol(CFDictionaryRef inDict, CFStringRef inEnabledKey, CFStringRef inHostKey, CFStringRef inPortKey, CFStringRef *outProxyHost, int *ioProxyPort) {
- /* See if the proxy is enabled. */
- CFNumberRef cf_enabled = CFDictionaryGetValue(inDict, inEnabledKey);
- if (cf_enabled == NULL) {
- return false;
- }
-
- int isEnabled = false;
- if (!CFNumberGetValue(cf_enabled, kCFNumberIntType, &isEnabled)) {
- return isEnabled;
- }
-
- if (!isEnabled) return false;
- *outProxyHost = CFDictionaryGetValue(inDict, inHostKey);
-
- // If cf_host is null, that means the checkbox is set,
- // but no host was entered. We'll treat that as NOT ENABLED.
- // If cf_port is null or cf_port isn't a number, that means
- // no port number was entered. Treat this as ENABLED with the
- // protocol's default port.
- if (*outProxyHost == NULL) {
- return false;
- }
-
- if (CFStringGetLength(*outProxyHost) == 0) {
- return false;
- }
-
- int newPort = 0;
- CFNumberRef cf_port = NULL;
- if ((cf_port = CFDictionaryGetValue(inDict, inPortKey)) != NULL &&
- CFNumberGetValue(cf_port, kCFNumberIntType, &newPort) &&
- newPort > 0) {
- *ioProxyPort = newPort;
- } else {
- // bad port or no port - leave *ioProxyPort unchanged
- }
-
- return true;
-}
-
-static char *createUTF8CString(const CFStringRef theString) {
- if (theString == NULL) return NULL;
-
- const CFIndex stringLength = CFStringGetLength(theString);
- const CFIndex bufSize = CFStringGetMaximumSizeForEncoding(stringLength, kCFStringEncodingUTF8) + 1;
- char *returnVal = (char *)malloc(bufSize);
-
- if (CFStringGetCString(theString, returnVal, bufSize, kCFStringEncodingUTF8)) {
- return returnVal;
- }
-
- free(returnVal);
- return NULL;
-}
-
-// Return TRUE if str is a syntactically valid IP address.
-// Using inet_pton() instead of inet_aton() for IPv6 support.
-// len is only a hint; cstr must still be nul-terminated
-static int looksLikeIPAddress(char *cstr, size_t len) {
- if (len == 0 || (len == 1 && cstr[0] == '.')) return FALSE;
-
- char dst[16]; // big enough for INET6
- return (1 == inet_pton(AF_INET, cstr, dst) ||
- 1 == inet_pton(AF_INET6, cstr, dst));
-}
-
-
-
-// Convert Mac OS X proxy exception entry to Java syntax.
-// See Radar #3441134 for details.
-// Returns NULL if this exception should be ignored by Java.
-// May generate a string with multiple exceptions separated by '|'.
-static char * createConvertedException(CFStringRef cf_original) {
- // This is done with char* instead of CFString because inet_pton()
- // needs a C string.
- char *c_exception = createUTF8CString(cf_original);
- if (!c_exception) return NULL;
-
- int c_len = strlen(c_exception);
-
- // 1. sanitize exception prefix
- if (c_len >= 1 && 0 == strncmp(c_exception, ".", 1)) {
- memmove(c_exception, c_exception+1, c_len);
- c_len -= 1;
- } else if (c_len >= 2 && 0 == strncmp(c_exception, "*.", 2)) {
- memmove(c_exception, c_exception+2, c_len-1);
- c_len -= 2;
- }
-
- // 2. pre-reject other exception wildcards
- if (strchr(c_exception, '*')) {
- free(c_exception);
- return NULL;
- }
-
- // 3. no IP wildcarding
- if (looksLikeIPAddress(c_exception, c_len)) {
- return c_exception;
- }
-
- // 4. allow domain suffixes
- // c_exception is now "str\0" - change to "str|*.str\0"
- c_exception = reallocf(c_exception, c_len+3+c_len+1);
- if (!c_exception) return NULL;
-
- strncpy(c_exception+c_len, "|*.", 3);
- strncpy(c_exception+c_len+3, c_exception, c_len);
- c_exception[c_len+3+c_len] = '\0';
- return c_exception;
-}
-
-/*
- * Method for fetching the user.home path and storing it in the property list.
- * For signed .apps running in the Mac App Sandbox, user.home is set to the
- * app's sandbox container.
- */
-void setUserHome(java_props_t *sprops) {
- if (sprops == NULL) { return; }
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- sprops->user_home = createUTF8CString((CFStringRef)NSHomeDirectory());
- [pool drain];
-}
-
-/*
- * Method for fetching proxy info and storing it in the property list.
- */
-void setProxyProperties(java_props_t *sProps) {
- if (sProps == NULL) return;
-
- char buf[16]; /* Used for %d of an int - 16 is plenty */
- CFStringRef
- cf_httpHost = NULL,
- cf_httpsHost = NULL,
- cf_ftpHost = NULL,
- cf_socksHost = NULL,
- cf_gopherHost = NULL;
- int
- httpPort = 80, // Default proxy port values
- httpsPort = 443,
- ftpPort = 21,
- socksPort = 1080,
- gopherPort = 70;
-
- CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL);
- if (dict == NULL) return;
-
- /* Read the proxy exceptions list */
- CFArrayRef cf_list = CFDictionaryGetValue(dict, kSCPropNetProxiesExceptionsList);
-
- CFMutableStringRef cf_exceptionList = NULL;
- if (cf_list != NULL) {
- CFIndex len = CFArrayGetCount(cf_list), idx;
-
- cf_exceptionList = CFStringCreateMutable(NULL, 0);
- for (idx = (CFIndex)0; idx < len; idx++) {
- CFStringRef cf_ehost;
- if ((cf_ehost = CFArrayGetValueAtIndex(cf_list, idx))) {
- /* Convert this exception from Mac OS X syntax to Java syntax.
- See Radar #3441134 for details. This may generate a string
- with multiple Java exceptions separated by '|'. */
- char *c_exception = createConvertedException(cf_ehost);
- if (c_exception) {
- /* Append the host to the list of exclusions. */
- if (CFStringGetLength(cf_exceptionList) > 0) {
- CFStringAppendCString(cf_exceptionList, "|", kCFStringEncodingMacRoman);
- }
- CFStringAppendCString(cf_exceptionList, c_exception, kCFStringEncodingMacRoman);
- free(c_exception);
- }
- }
- }
- }
-
- if (cf_exceptionList != NULL) {
- if (CFStringGetLength(cf_exceptionList) > 0) {
- sProps->exceptionList = createUTF8CString(cf_exceptionList);
- }
- CFRelease(cf_exceptionList);
- }
-
-#define CHECK_PROXY(protocol, PROTOCOL) \
- sProps->protocol##ProxyEnabled = \
- getProxyInfoForProtocol(dict, kSCPropNetProxies##PROTOCOL##Enable, \
- kSCPropNetProxies##PROTOCOL##Proxy, \
- kSCPropNetProxies##PROTOCOL##Port, \
- &cf_##protocol##Host, &protocol##Port); \
- if (sProps->protocol##ProxyEnabled) { \
- sProps->protocol##Host = createUTF8CString(cf_##protocol##Host); \
- snprintf(buf, sizeof(buf), "%d", protocol##Port); \
- sProps->protocol##Port = malloc(strlen(buf) + 1); \
- strcpy(sProps->protocol##Port, buf); \
- }
-
- CHECK_PROXY(http, HTTP);
- CHECK_PROXY(https, HTTPS);
- CHECK_PROXY(ftp, FTP);
- CHECK_PROXY(socks, SOCKS);
- CHECK_PROXY(gopher, Gopher);
-
-#undef CHECK_PROXY
-
- CFRelease(dict);
-}
--- a/jdk/src/java.base/unix/native/libjava/java_props_macosx.h Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "java_props.h"
-
-char *setupMacOSXLocale(int cat);
-void setOSNameAndVersion(java_props_t *sprops);
-void setUserHome(java_props_t *sprops);
-void setProxyProperties(java_props_t *sProps);
-int isInAquaSession();
--- a/jdk/src/java.base/unix/native/libnet/NetworkInterface.c Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/unix/native/libnet/NetworkInterface.c Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -274,7 +274,6 @@
if (index <= 0) {
return NULL;
}
-
ifs = enumInterfaces(env);
if (ifs == NULL) {
return NULL;
@@ -551,9 +550,14 @@
jboolean isCopy;
int ret = -1;
int sock;
- const char* name_utf;
+ const char* name_utf = NULL;
- name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+ if (name != NULL) {
+ name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+ } else {
+ JNU_ThrowNullPointerException(env, "network interface name is NULL");
+ return ret;
+ }
if (name_utf == NULL) {
if (!(*env)->ExceptionCheck(env))
JNU_ThrowOutOfMemoryError(env, NULL);
@@ -581,7 +585,13 @@
const char* name_utf;
int flags = 0;
- name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+ if (name != NULL) {
+ name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
+ } else {
+ JNU_ThrowNullPointerException(env, "network interface name is NULL");
+ return -1;
+ }
+
if (name_utf == NULL) {
if (!(*env)->ExceptionCheck(env))
JNU_ThrowOutOfMemoryError(env, NULL);
@@ -1063,6 +1073,7 @@
*/
#ifdef AF_INET6
+// unused arg ifname and struct if2
static int openSocketWithFallback(JNIEnv *env, const char *ifname){
int sock;
struct ifreq if2;
@@ -1453,9 +1464,14 @@
static int getMTU(JNIEnv *env, int sock, const char *ifname) {
struct ifreq if2;
+ memset((char *) &if2, 0, sizeof(if2));
- memset((char *) &if2, 0, sizeof(if2));
- strcpy(if2.ifr_name, ifname);
+ if (ifname != NULL) {
+ strcpy(if2.ifr_name, ifname);
+ } else {
+ JNU_ThrowNullPointerException(env, "network interface name is NULL");
+ return -1;
+ }
if (ioctl(sock, SIOCGIFMTU, (char *)&if2) < 0) {
NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "IOCTL SIOCGIFMTU failed");
--- a/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -62,7 +62,6 @@
#include "jvm.h"
#include "jni_util.h"
#include "net_util.h"
-
#include "java_net_SocketOptions.h"
#include "java_net_PlainDatagramSocketImpl.h"
#include "java_net_NetworkInterface.h"
@@ -83,6 +82,7 @@
extern void setDefaultScopeID(JNIEnv *env, struct sockaddr *him);
extern int getDefaultScopeID(JNIEnv *env);
+
/*
* Returns a java.lang.Integer based on 'i'
*/
@@ -1447,10 +1447,12 @@
static jmethodID ni_ctrID;
static jfieldID ni_indexID;
static jfieldID ni_addrsID;
+ static jfieldID ni_nameID;
jobjectArray addrArray;
jobject addr;
jobject ni;
+ jobject ni_name;
struct in_addr in;
struct in_addr *inP = ∈
@@ -1500,6 +1502,8 @@
ni_addrsID = (*env)->GetFieldID(env, c, "addrs",
"[Ljava/net/InetAddress;");
CHECK_NULL_RETURN(ni_addrsID, NULL);
+ ni_nameID = (*env)->GetFieldID(env, c,"name", "Ljava/lang/String;");
+ CHECK_NULL_RETURN(ni_nameID, NULL);
ni_class = (*env)->NewGlobalRef(env, c);
CHECK_NULL_RETURN(ni_class, NULL);
}
@@ -1521,6 +1525,10 @@
CHECK_NULL_RETURN(addrArray, NULL);
(*env)->SetObjectArrayElement(env, addrArray, 0, addr);
(*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
+ ni_name = (*env)->NewStringUTF(env, "");
+ if (ni_name != NULL) {
+ (*env)->SetObjectField(env, ni, ni_nameID, ni_name);
+ }
return ni;
}
@@ -1537,14 +1545,16 @@
static jfieldID ni_indexID;
static jfieldID ni_addrsID;
static jclass ia_class;
+ static jfieldID ni_nameID;
static jmethodID ia_anyLocalAddressID;
- int index;
+ int index = 0;
socklen_t len = sizeof(index);
jobjectArray addrArray;
jobject addr;
jobject ni;
+ jobject ni_name;
if (getsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
(char*)&index, &len) < 0) {
@@ -1573,6 +1583,8 @@
"anyLocalAddress",
"()Ljava/net/InetAddress;");
CHECK_NULL_RETURN(ia_anyLocalAddressID, NULL);
+ ni_nameID = (*env)->GetFieldID(env, c,"name", "Ljava/lang/String;");
+ CHECK_NULL_RETURN(ni_nameID, NULL);
ni_class = (*env)->NewGlobalRef(env, c);
CHECK_NULL_RETURN(ni_class, NULL);
}
@@ -1633,6 +1645,10 @@
CHECK_NULL_RETURN(addrArray, NULL);
(*env)->SetObjectArrayElement(env, addrArray, 0, addr);
(*env)->SetObjectField(env, ni, ni_addrsID, addrArray);
+ ni_name = (*env)->NewStringUTF(env, "");
+ if (ni_name != NULL) {
+ (*env)->SetObjectField(env, ni, ni_nameID, ni_name);
+ }
return ni;
}
#endif
--- a/jdk/src/java.base/unix/native/libnet/bsd_close.c Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,421 +0,0 @@
-/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/param.h>
-#include <signal.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/poll.h>
-
-/*
- * Stack allocated by thread when doing blocking operation
- */
-typedef struct threadEntry {
- pthread_t thr; /* this thread */
- struct threadEntry *next; /* next thread */
- int intr; /* interrupted */
-} threadEntry_t;
-
-/*
- * Heap allocated during initialized - one entry per fd
- */
-typedef struct {
- pthread_mutex_t lock; /* fd lock */
- threadEntry_t *threads; /* threads blocked on fd */
-} fdEntry_t;
-
-/*
- * Signal to unblock thread
- */
-static int sigWakeup = SIGIO;
-
-/*
- * The fd table and the number of file descriptors
- */
-static fdEntry_t *fdTable;
-static int fdCount;
-
-/*
- * This limit applies if getlimit() returns unlimited.
- * Unfortunately, this means if someone wants a higher limit
- * then they have to set an explicit limit, higher than this,
- * which is probably counter-intuitive.
- */
-#define MAX_FD_COUNT 4096
-
-/*
- * Null signal handler
- */
-static void sig_wakeup(int sig) {
-}
-
-/*
- * Initialization routine (executed when library is loaded)
- * Allocate fd tables and sets up signal handler.
- */
-static void __attribute((constructor)) init() {
- struct rlimit nbr_files;
- sigset_t sigset;
- struct sigaction sa;
- int i;
-
- /*
- * Allocate table based on the maximum number of
- * file descriptors.
- */
- getrlimit(RLIMIT_NOFILE, &nbr_files);
- if (nbr_files.rlim_max == RLIM_INFINITY) {
- fdCount = MAX_FD_COUNT;
- } else {
- fdCount = nbr_files.rlim_max;
- }
- fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
- if (fdTable == NULL) {
- fprintf(stderr, "library initialization failed - "
- "unable to allocate file descriptor table - out of memory");
- abort();
- }
- for (i=0; i<fdCount; i++) {
- pthread_mutex_init(&fdTable[i].lock, NULL);
- }
-
- /*
- * Setup the signal handler
- */
- sa.sa_handler = sig_wakeup;
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sigaction(sigWakeup, &sa, NULL);
-
- sigemptyset(&sigset);
- sigaddset(&sigset, sigWakeup);
- sigprocmask(SIG_UNBLOCK, &sigset, NULL);
-}
-
-/*
- * Return the fd table for this fd or NULL is fd out
- * of range.
- */
-static inline fdEntry_t *getFdEntry(int fd)
-{
- if (fd < 0 || fd >= fdCount) {
- return NULL;
- }
- return &fdTable[fd];
-}
-
-/*
- * Start a blocking operation :-
- * Insert thread onto thread list for the fd.
- */
-static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self)
-{
- self->thr = pthread_self();
- self->intr = 0;
-
- pthread_mutex_lock(&(fdEntry->lock));
- {
- self->next = fdEntry->threads;
- fdEntry->threads = self;
- }
- pthread_mutex_unlock(&(fdEntry->lock));
-}
-
-/*
- * End a blocking operation :-
- * Remove thread from thread list for the fd
- * If fd has been interrupted then set errno to EBADF
- */
-static inline void endOp
- (fdEntry_t *fdEntry, threadEntry_t *self)
-{
- int orig_errno = errno;
- pthread_mutex_lock(&(fdEntry->lock));
- {
- threadEntry_t *curr, *prev=NULL;
- curr = fdEntry->threads;
- while (curr != NULL) {
- if (curr == self) {
- if (curr->intr) {
- orig_errno = EBADF;
- }
- if (prev == NULL) {
- fdEntry->threads = curr->next;
- } else {
- prev->next = curr->next;
- }
- break;
- }
- prev = curr;
- curr = curr->next;
- }
- }
- pthread_mutex_unlock(&(fdEntry->lock));
- errno = orig_errno;
-}
-
-/*
- * Close or dup2 a file descriptor ensuring that all threads blocked on
- * the file descriptor are notified via a wakeup signal.
- *
- * fd1 < 0 => close(fd2)
- * fd1 >= 0 => dup2(fd1, fd2)
- *
- * Returns -1 with errno set if operation fails.
- */
-static int closefd(int fd1, int fd2) {
- int rv, orig_errno;
- fdEntry_t *fdEntry = getFdEntry(fd2);
- if (fdEntry == NULL) {
- errno = EBADF;
- return -1;
- }
-
- /*
- * Lock the fd to hold-off additional I/O on this fd.
- */
- pthread_mutex_lock(&(fdEntry->lock));
-
- {
- /*
- * Send a wakeup signal to all threads blocked on this
- * file descriptor.
- */
- threadEntry_t *curr = fdEntry->threads;
- while (curr != NULL) {
- curr->intr = 1;
- pthread_kill( curr->thr, sigWakeup );
- curr = curr->next;
- }
-
- /*
- * And close/dup the file descriptor
- * (restart if interrupted by signal)
- */
- do {
- if (fd1 < 0) {
- rv = close(fd2);
- } else {
- rv = dup2(fd1, fd2);
- }
- } while (rv == -1 && errno == EINTR);
-
- }
-
- /*
- * Unlock without destroying errno
- */
- orig_errno = errno;
- pthread_mutex_unlock(&(fdEntry->lock));
- errno = orig_errno;
-
- return rv;
-}
-
-/*
- * Wrapper for dup2 - same semantics as dup2 system call except
- * that any threads blocked in an I/O system call on fd2 will be
- * preempted and return -1/EBADF;
- */
-int NET_Dup2(int fd, int fd2) {
- if (fd < 0) {
- errno = EBADF;
- return -1;
- }
- return closefd(fd, fd2);
-}
-
-/*
- * Wrapper for close - same semantics as close system call
- * except that any threads blocked in an I/O on fd will be
- * preempted and the I/O system call will return -1/EBADF.
- */
-int NET_SocketClose(int fd) {
- return closefd(-1, fd);
-}
-
-/************** Basic I/O operations here ***************/
-
-/*
- * Macro to perform a blocking IO operation. Restarts
- * automatically if interrupted by signal (other than
- * our wakeup signal)
- */
-#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
- int ret; \
- threadEntry_t self; \
- fdEntry_t *fdEntry = getFdEntry(FD); \
- if (fdEntry == NULL) { \
- errno = EBADF; \
- return -1; \
- } \
- do { \
- startOp(fdEntry, &self); \
- ret = FUNC; \
- endOp(fdEntry, &self); \
- } while (ret == -1 && errno == EINTR); \
- return ret; \
-}
-
-int NET_Read(int s, void* buf, size_t len) {
- BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
-}
-
-int NET_ReadV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
-}
-
-int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
- struct sockaddr *from, socklen_t *fromlen) {
- BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, fromlen) );
-}
-
-int NET_Send(int s, void *msg, int len, unsigned int flags) {
- BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
-}
-
-int NET_WriteV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) );
-}
-
-int NET_SendTo(int s, const void *msg, int len, unsigned int
- flags, const struct sockaddr *to, int tolen) {
- BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) );
-}
-
-int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) {
- BLOCKING_IO_RETURN_INT( s, accept(s, addr, addrlen) );
-}
-
-int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
- BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
-}
-
-int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
- BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
-}
-
-/*
- * Wrapper for select(s, timeout). We are using select() on Mac OS due to Bug 7131399.
- * Auto restarts with adjusted timeout if interrupted by
- * signal other than our wakeup signal.
- */
-int NET_Timeout(int s, long timeout) {
- long prevtime = 0, newtime;
- struct timeval t, *tp = &t;
- fd_set fds;
- fd_set* fdsp = NULL;
- int allocated = 0;
- threadEntry_t self;
- fdEntry_t *fdEntry = getFdEntry(s);
-
- /*
- * Check that fd hasn't been closed.
- */
- if (fdEntry == NULL) {
- errno = EBADF;
- return -1;
- }
-
- /*
- * Pick up current time as may need to adjust timeout
- */
- if (timeout > 0) {
- /* Timed */
- struct timeval now;
- gettimeofday(&now, NULL);
- prevtime = now.tv_sec * 1000 + now.tv_usec / 1000;
- t.tv_sec = timeout / 1000;
- t.tv_usec = (timeout % 1000) * 1000;
- } else if (timeout < 0) {
- /* Blocking */
- tp = 0;
- } else {
- /* Poll */
- t.tv_sec = 0;
- t.tv_usec = 0;
- }
-
- if (s < FD_SETSIZE) {
- fdsp = &fds;
- FD_ZERO(fdsp);
- } else {
- int length = (howmany(s+1, NFDBITS)) * sizeof(int);
- fdsp = (fd_set *) calloc(1, length);
- if (fdsp == NULL) {
- return -1; // errno will be set to ENOMEM
- }
- allocated = 1;
- }
- FD_SET(s, fdsp);
-
- for(;;) {
- int rv;
-
- /*
- * call select on the fd. If interrupted by our wakeup signal
- * errno will be set to EBADF.
- */
-
- startOp(fdEntry, &self);
- rv = select(s+1, fdsp, 0, 0, tp);
- endOp(fdEntry, &self);
-
- /*
- * If interrupted then adjust timeout. If timeout
- * has expired return 0 (indicating timeout expired).
- */
- if (rv < 0 && errno == EINTR) {
- if (timeout > 0) {
- struct timeval now;
- gettimeofday(&now, NULL);
- newtime = now.tv_sec * 1000 + now.tv_usec / 1000;
- timeout -= newtime - prevtime;
- if (timeout <= 0) {
- if (allocated != 0)
- free(fdsp);
- return 0;
- }
- prevtime = newtime;
- t.tv_sec = timeout / 1000;
- t.tv_usec = (timeout % 1000) * 1000;
- }
- } else {
- if (allocated != 0)
- free(fdsp);
- return rv;
- }
-
- }
-}
--- a/jdk/src/java.base/unix/native/libnet/linux_close.c Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,371 +0,0 @@
-/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/poll.h>
-
-/*
- * Stack allocated by thread when doing blocking operation
- */
-typedef struct threadEntry {
- pthread_t thr; /* this thread */
- struct threadEntry *next; /* next thread */
- int intr; /* interrupted */
-} threadEntry_t;
-
-/*
- * Heap allocated during initialized - one entry per fd
- */
-typedef struct {
- pthread_mutex_t lock; /* fd lock */
- threadEntry_t *threads; /* threads blocked on fd */
-} fdEntry_t;
-
-/*
- * Signal to unblock thread
- */
-static int sigWakeup = (__SIGRTMAX - 2);
-
-/*
- * The fd table and the number of file descriptors
- */
-static fdEntry_t *fdTable;
-static int fdCount;
-
-/*
- * Null signal handler
- */
-static void sig_wakeup(int sig) {
-}
-
-/*
- * Initialization routine (executed when library is loaded)
- * Allocate fd tables and sets up signal handler.
- */
-static void __attribute((constructor)) init() {
- struct rlimit nbr_files;
- sigset_t sigset;
- struct sigaction sa;
-
- /*
- * Allocate table based on the maximum number of
- * file descriptors.
- */
- getrlimit(RLIMIT_NOFILE, &nbr_files);
- fdCount = nbr_files.rlim_max;
- fdTable = (fdEntry_t *)calloc(fdCount, sizeof(fdEntry_t));
- if (fdTable == NULL) {
- fprintf(stderr, "library initialization failed - "
- "unable to allocate file descriptor table - out of memory");
- abort();
- }
-
- /*
- * Setup the signal handler
- */
- sa.sa_handler = sig_wakeup;
- sa.sa_flags = 0;
- sigemptyset(&sa.sa_mask);
- sigaction(sigWakeup, &sa, NULL);
-
- sigemptyset(&sigset);
- sigaddset(&sigset, sigWakeup);
- sigprocmask(SIG_UNBLOCK, &sigset, NULL);
-}
-
-/*
- * Return the fd table for this fd or NULL is fd out
- * of range.
- */
-static inline fdEntry_t *getFdEntry(int fd)
-{
- if (fd < 0 || fd >= fdCount) {
- return NULL;
- }
- return &fdTable[fd];
-}
-
-/*
- * Start a blocking operation :-
- * Insert thread onto thread list for the fd.
- */
-static inline void startOp(fdEntry_t *fdEntry, threadEntry_t *self)
-{
- self->thr = pthread_self();
- self->intr = 0;
-
- pthread_mutex_lock(&(fdEntry->lock));
- {
- self->next = fdEntry->threads;
- fdEntry->threads = self;
- }
- pthread_mutex_unlock(&(fdEntry->lock));
-}
-
-/*
- * End a blocking operation :-
- * Remove thread from thread list for the fd
- * If fd has been interrupted then set errno to EBADF
- */
-static inline void endOp
- (fdEntry_t *fdEntry, threadEntry_t *self)
-{
- int orig_errno = errno;
- pthread_mutex_lock(&(fdEntry->lock));
- {
- threadEntry_t *curr, *prev=NULL;
- curr = fdEntry->threads;
- while (curr != NULL) {
- if (curr == self) {
- if (curr->intr) {
- orig_errno = EBADF;
- }
- if (prev == NULL) {
- fdEntry->threads = curr->next;
- } else {
- prev->next = curr->next;
- }
- break;
- }
- prev = curr;
- curr = curr->next;
- }
- }
- pthread_mutex_unlock(&(fdEntry->lock));
- errno = orig_errno;
-}
-
-/*
- * Close or dup2 a file descriptor ensuring that all threads blocked on
- * the file descriptor are notified via a wakeup signal.
- *
- * fd1 < 0 => close(fd2)
- * fd1 >= 0 => dup2(fd1, fd2)
- *
- * Returns -1 with errno set if operation fails.
- */
-static int closefd(int fd1, int fd2) {
- int rv, orig_errno;
- fdEntry_t *fdEntry = getFdEntry(fd2);
- if (fdEntry == NULL) {
- errno = EBADF;
- return -1;
- }
-
- /*
- * Lock the fd to hold-off additional I/O on this fd.
- */
- pthread_mutex_lock(&(fdEntry->lock));
-
- {
- /*
- * And close/dup the file descriptor
- * (restart if interrupted by signal)
- */
- do {
- if (fd1 < 0) {
- rv = close(fd2);
- } else {
- rv = dup2(fd1, fd2);
- }
- } while (rv == -1 && errno == EINTR);
-
- /*
- * Send a wakeup signal to all threads blocked on this
- * file descriptor.
- */
- threadEntry_t *curr = fdEntry->threads;
- while (curr != NULL) {
- curr->intr = 1;
- pthread_kill( curr->thr, sigWakeup );
- curr = curr->next;
- }
- }
-
- /*
- * Unlock without destroying errno
- */
- orig_errno = errno;
- pthread_mutex_unlock(&(fdEntry->lock));
- errno = orig_errno;
-
- return rv;
-}
-
-/*
- * Wrapper for dup2 - same semantics as dup2 system call except
- * that any threads blocked in an I/O system call on fd2 will be
- * preempted and return -1/EBADF;
- */
-int NET_Dup2(int fd, int fd2) {
- if (fd < 0) {
- errno = EBADF;
- return -1;
- }
- return closefd(fd, fd2);
-}
-
-/*
- * Wrapper for close - same semantics as close system call
- * except that any threads blocked in an I/O on fd will be
- * preempted and the I/O system call will return -1/EBADF.
- */
-int NET_SocketClose(int fd) {
- return closefd(-1, fd);
-}
-
-/************** Basic I/O operations here ***************/
-
-/*
- * Macro to perform a blocking IO operation. Restarts
- * automatically if interrupted by signal (other than
- * our wakeup signal)
- */
-#define BLOCKING_IO_RETURN_INT(FD, FUNC) { \
- int ret; \
- threadEntry_t self; \
- fdEntry_t *fdEntry = getFdEntry(FD); \
- if (fdEntry == NULL) { \
- errno = EBADF; \
- return -1; \
- } \
- do { \
- startOp(fdEntry, &self); \
- ret = FUNC; \
- endOp(fdEntry, &self); \
- } while (ret == -1 && errno == EINTR); \
- return ret; \
-}
-
-int NET_Read(int s, void* buf, size_t len) {
- BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
-}
-
-int NET_ReadV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
-}
-
-int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
- struct sockaddr *from, socklen_t *fromlen) {
- BLOCKING_IO_RETURN_INT( s, recvfrom(s, buf, len, flags, from, fromlen) );
-}
-
-int NET_Send(int s, void *msg, int len, unsigned int flags) {
- BLOCKING_IO_RETURN_INT( s, send(s, msg, len, flags) );
-}
-
-int NET_WriteV(int s, const struct iovec * vector, int count) {
- BLOCKING_IO_RETURN_INT( s, writev(s, vector, count) );
-}
-
-int NET_SendTo(int s, const void *msg, int len, unsigned int
- flags, const struct sockaddr *to, int tolen) {
- BLOCKING_IO_RETURN_INT( s, sendto(s, msg, len, flags, to, tolen) );
-}
-
-int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) {
- BLOCKING_IO_RETURN_INT( s, accept(s, addr, addrlen) );
-}
-
-int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
- BLOCKING_IO_RETURN_INT( s, connect(s, addr, addrlen) );
-}
-
-int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
- BLOCKING_IO_RETURN_INT( ufds[0].fd, poll(ufds, nfds, timeout) );
-}
-
-/*
- * Wrapper for poll(s, timeout).
- * Auto restarts with adjusted timeout if interrupted by
- * signal other than our wakeup signal.
- */
-int NET_Timeout(int s, long timeout) {
- long prevtime = 0, newtime;
- struct timeval t;
- fdEntry_t *fdEntry = getFdEntry(s);
-
- /*
- * Check that fd hasn't been closed.
- */
- if (fdEntry == NULL) {
- errno = EBADF;
- return -1;
- }
-
- /*
- * Pick up current time as may need to adjust timeout
- */
- if (timeout > 0) {
- gettimeofday(&t, NULL);
- prevtime = t.tv_sec * 1000 + t.tv_usec / 1000;
- }
-
- for(;;) {
- struct pollfd pfd;
- int rv;
- threadEntry_t self;
-
- /*
- * Poll the fd. If interrupted by our wakeup signal
- * errno will be set to EBADF.
- */
- pfd.fd = s;
- pfd.events = POLLIN | POLLERR;
-
- startOp(fdEntry, &self);
- rv = poll(&pfd, 1, timeout);
- endOp(fdEntry, &self);
-
- /*
- * If interrupted then adjust timeout. If timeout
- * has expired return 0 (indicating timeout expired).
- */
- if (rv < 0 && errno == EINTR) {
- if (timeout > 0) {
- gettimeofday(&t, NULL);
- newtime = t.tv_sec * 1000 + t.tv_usec / 1000;
- timeout -= newtime - prevtime;
- if (timeout <= 0) {
- return 0;
- }
- prevtime = newtime;
- }
- } else {
- return rv;
- }
-
- }
-}
--- a/jdk/src/java.base/unix/native/libnet/solaris_close.c Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +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. 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.
- */
-
-#include <errno.h>
-#include <sys/socket.h>
-#include <stropts.h>
-#include <unistd.h>
-
-/* Support for restartable system calls on Solaris. */
-
-#define RESTARTABLE_RETURN_INT(_cmd) do { \
- int _result; \
- if (1) { \
- do { \
- _result = _cmd; \
- } while((_result == -1) && (errno == EINTR)); \
- return _result; \
- } \
-} while(0)
-
-int NET_Read(int s, void* buf, size_t len) {
- RESTARTABLE_RETURN_INT(recv(s, buf, len, 0));
-}
-
-int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
- struct sockaddr *from, socklen_t *fromlen) {
- RESTARTABLE_RETURN_INT(recvfrom(s, buf, len, flags, from, fromlen));
-}
-
-int NET_ReadV(int s, const struct iovec * vector, int count) {
- RESTARTABLE_RETURN_INT(readv(s, vector, count));
-}
-
-int NET_WriteV(int s, const struct iovec * vector, int count) {
- RESTARTABLE_RETURN_INT(writev(s, vector, count));
-}
-
-int NET_Send(int s, void *msg, int len, unsigned int flags) {
- RESTARTABLE_RETURN_INT(send(s, msg, len, flags));
-}
-
-int NET_SendTo(int s, const void *msg, int len, unsigned int flags,
- const struct sockaddr *to, int tolen) {
- RESTARTABLE_RETURN_INT(sendto(s, msg, len, flags, to, tolen));
-}
-
-int NET_Connect(int s, struct sockaddr *addr, int addrlen) {
- RESTARTABLE_RETURN_INT(connect(s, addr, addrlen));
-}
-
-int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) {
- RESTARTABLE_RETURN_INT(accept(s, addr, addrlen));
-}
-
-int NET_SocketClose(int fd) {
- return close(fd);
-}
-
-int NET_Dup2(int fd, int fd2) {
- return dup2(fd, fd2);
-}
-
-int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
- RESTARTABLE_RETURN_INT(poll(ufds, nfds, timeout));
-}
-
-int NET_Timeout(int s, long timeout) {
- int result;
- struct timeval t;
- long prevtime, newtime;
- struct pollfd pfd;
- pfd.fd = s;
- pfd.events = POLLIN;
-
- if (timeout > 0) {
- gettimeofday(&t, NULL);
- prevtime = (t.tv_sec * 1000) + t.tv_usec / 1000;
- }
-
- for(;;) {
- result = poll(&pfd, 1, timeout);
- if (result < 0 && errno == EINTR) {
- if (timeout > 0) {
- gettimeofday(&t, NULL);
- newtime = (t.tv_sec * 1000) + t.tv_usec /1000;
- timeout -= newtime - prevtime;
- if (timeout <= 0)
- return 0;
- prevtime = newtime;
- }
- } else {
- return result;
- }
- }
-}
--- a/jdk/src/java.base/windows/classes/java/lang/ClassLoaderHelper.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/windows/classes/java/lang/ClassLoaderHelper.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,11 @@
private ClassLoaderHelper() {}
/**
+ * Indicates, whether PATH env variable is allowed to contain quoted entries.
+ */
+ static final boolean allowsQuotedPathElements = true;
+
+ /**
* Returns an alternate path name for the given file
* such that if the original pathname did not exist, then the
* file may be located at the alternate location.
--- a/jdk/src/java.base/windows/native/libjava/ProcessImpl_md.c Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/windows/native/libjava/ProcessImpl_md.c Thu Jan 29 03:54:45 2015 +0000
@@ -283,14 +283,10 @@
FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE};
- {
- /* Extraction of current process standard IOE handles */
- DWORD idsIOE[3] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE};
- int i;
- for (i = 0; i < 3; ++i)
- /* Should not be closed by CloseHandle! */
- stdIOE[i] = GetStdHandle(idsIOE[i]);
- }
+ /* These three should not be closed by CloseHandle! */
+ stdIOE[0] = GetStdHandle(STD_INPUT_HANDLE);
+ stdIOE[1] = GetStdHandle(STD_OUTPUT_HANDLE);
+ stdIOE[2] = GetStdHandle(STD_ERROR_HANDLE);
prepareIOEHandleState(stdIOE, inherit);
{
@@ -319,11 +315,16 @@
if (success) {
PROCESS_INFORMATION pi;
- DWORD processFlag = CREATE_UNICODE_ENVIRONMENT;
+ DWORD processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;
- /* Suppress popping-up of a console window for non-console applications */
- if (GetConsoleWindow() == NULL)
- processFlag |= CREATE_NO_WINDOW;
+ /* If the standard I/O is inherited, CREATE_NO_WINDOW must not be used. */
+ if (GetConsoleWindow() != NULL &&
+ (si.hStdInput == stdIOE[0] ||
+ si.hStdOutput == stdIOE[1] ||
+ si.hStdError == (redirectErrorStream ? stdIOE[1] : stdIOE[2])))
+ {
+ processFlag &= ~CREATE_NO_WINDOW;
+ }
si.dwFlags = STARTF_USESTDHANDLES;
if (!CreateProcessW(
--- a/jdk/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c Thu Jan 29 03:54:45 2015 +0000
@@ -48,6 +48,8 @@
isa_ctorID = (*env)->GetMethodID(env, cls, "<init>",
"(Ljava/net/InetAddress;I)V");
+ initInetAddressIDs(env);
+
// implement read timeout with select.
isRcvTimeoutSupported = 0;
}
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsButtonUI.java Thu Jan 29 03:54:45 2015 +0000
@@ -248,7 +248,8 @@
Part part = getXPButtonType(b);
- if (b.isContentAreaFilled() && xp != null) {
+ if (b.isContentAreaFilled() && b.getBorder() != null
+ && b.isBorderPainted() && xp != null) {
Skin skin = xp.getSkin(b, part);
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java Thu Jan 29 03:54:45 2015 +0000
@@ -1081,16 +1081,9 @@
directories.clear();
- File[] baseFolders;
- if (useShellFolder) {
- baseFolders = AccessController.doPrivileged(new PrivilegedAction<File[]>() {
- public File[] run() {
- return (File[]) ShellFolder.get("fileChooserComboBoxFolders");
- }
- });
- } else {
- baseFolders = fsv.getRoots();
- }
+ File[] baseFolders = (useShellFolder)
+ ? (File[]) ShellFolder.get("fileChooserComboBoxFolders")
+ : fsv.getRoots();
directories.addAll(Arrays.asList(baseFolders));
// Get the canonical (full) path. This has the side
--- a/jdk/src/java.desktop/share/classes/java/beans/package.html Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/classes/java/beans/package.html Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
<!--
- Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ 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
@@ -147,8 +147,8 @@
For overview, architecture, and tutorial documentation, please see:
<ul>
- <li><a href="http://java.sun.com/docs/books/tutorial/javabeans/">JavaBeans</a>, a trail in <em>The Java Tutorial</em>.
- <li><a href="http://java.sun.com/products/jfc/tsc/articles/persistence2/">Long-Term Persistence</a>, an article in <em>The Swing Connection</em>.
+ <li><a href="http://docs.oracle.com/javase/tutorial/javabeans/">JavaBeans</a>, a trail in <em>The Java Tutorial</em>.
+ <li><a href="http://www.oracle.com/technetwork/java/persistence2-141443.html">Long-Term Persistence</a>, an article in <em>The Swing Connection</em>.
</ul>
</body>
--- a/jdk/src/java.desktop/share/classes/javax/swing/ToolTipManager.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/classes/javax/swing/ToolTipManager.java Thu Jan 29 03:54:45 2015 +0000
@@ -28,6 +28,7 @@
import java.awt.event.*;
import java.awt.*;
+import java.util.Objects;
/**
* Manages all the <code>ToolTips</code> in the system.
@@ -476,8 +477,8 @@
preferredLocation.equals(newPreferredLocation) :
(newPreferredLocation == null);
- if (!sameComponent || !toolTipText.equals(newToolTipText) ||
- !sameLoc) {
+ if (!sameComponent || !Objects.equals(toolTipText, newToolTipText)
+ || !sameLoc) {
toolTipText = newToolTipText;
preferredLocation = newPreferredLocation;
showTipWindow();
--- a/jdk/src/java.desktop/share/classes/javax/swing/UIDefaults.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/classes/javax/swing/UIDefaults.java Thu Jan 29 03:54:45 2015 +0000
@@ -44,9 +44,7 @@
import java.awt.Color;
import java.awt.Insets;
import java.awt.Dimension;
-import java.lang.reflect.Method;
import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeEvent;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
@@ -76,7 +74,7 @@
@SuppressWarnings("serial") // Same-version serialization only
public class UIDefaults extends Hashtable<Object,Object>
{
- private static final Object PENDING = "Pending";
+ private static final Object PENDING = new Object();
private SwingPropertyChangeSupport changeSupport;
@@ -170,7 +168,7 @@
* Looks up the given key in our Hashtable and resolves LazyValues
* or ActiveValues.
*/
- private Object getFromHashtable(Object key) {
+ private Object getFromHashtable(final Object key) {
/* Quickly handle the common case, without grabbing
* a lock.
*/
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java Thu Jan 29 03:54:45 2015 +0000
@@ -1020,16 +1020,9 @@
directories.clear();
- File[] baseFolders;
- if (useShellFolder) {
- baseFolders = AccessController.doPrivileged(new PrivilegedAction<File[]>() {
- public File[] run() {
- return (File[]) ShellFolder.get("fileChooserComboBoxFolders");
- }
- });
- } else {
- baseFolders = fsv.getRoots();
- }
+ File[] baseFolders = (useShellFolder)
+ ? (File[]) ShellFolder.get("fileChooserComboBoxFolders")
+ : fsv.getRoots();
directories.addAll(Arrays.asList(baseFolders));
// Get the canonical (full) path. This has the side
--- a/jdk/src/java.desktop/share/classes/sun/swing/FilePane.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/classes/sun/swing/FilePane.java Thu Jan 29 03:54:45 2015 +0000
@@ -1993,20 +1993,24 @@
return false;
}
- if (f instanceof ShellFolder) {
- return f.canWrite();
- } else {
- if (usesShellFolder(getFileChooser())) {
- try {
- return ShellFolder.getShellFolder(f).canWrite();
- } catch (FileNotFoundException ex) {
- // File doesn't exist
- return false;
+ try {
+ if (f instanceof ShellFolder) {
+ return f.canWrite();
+ } else {
+ if (usesShellFolder(getFileChooser())) {
+ try {
+ return ShellFolder.getShellFolder(f).canWrite();
+ } catch (FileNotFoundException ex) {
+ // File doesn't exist
+ return false;
+ }
+ } else {
+ // Ordinary file
+ return f.canWrite();
}
- } else {
- // Ordinary file
- return f.canWrite();
}
+ } catch (SecurityException e) {
+ return false;
}
}
--- a/jdk/src/java.desktop/share/classes/sun/swing/WindowsPlacesBar.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/classes/sun/swing/WindowsPlacesBar.java Thu Jan 29 03:54:45 2015 +0000
@@ -82,11 +82,7 @@
setBackground(bgColor);
FileSystemView fsv = fc.getFileSystemView();
- files = AccessController.doPrivileged(new PrivilegedAction<File[]>() {
- public File[] run() {
- return (File[]) ShellFolder.get("fileChooserShortcutPanelFolders");
- }
- });
+ files = (File[]) ShellFolder.get("fileChooserShortcutPanelFolders");
buttons = new JToggleButton[files.length];
buttonGroup = new ButtonGroup();
--- a/jdk/src/java.desktop/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/classes/sun/swing/plaf/synth/DefaultSynthStyle.java Thu Jan 29 03:54:45 2015 +0000
@@ -28,7 +28,6 @@
import java.awt.*;
import java.util.*;
import javax.swing.*;
-import javax.swing.border.Border;
import javax.swing.plaf.*;
/**
@@ -44,7 +43,8 @@
* @author Scott Violet
*/
public class DefaultSynthStyle extends SynthStyle implements Cloneable {
- private static final String PENDING = "Pending";
+
+ private static final Object PENDING = new Object();
/**
* Should the component be opaque?
--- a/jdk/src/java.desktop/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java Thu Jan 29 03:54:45 2015 +0000
@@ -771,16 +771,9 @@
fireIntervalRemoved(this, 0, oldSize);
}
- File[] baseFolders;
- if (useShellFolder) {
- baseFolders = AccessController.doPrivileged(new PrivilegedAction<File[]>() {
- public File[] run() {
- return (File[]) ShellFolder.get("fileChooserComboBoxFolders");
- }
- });
- } else {
- baseFolders = fsv.getRoots();
- }
+ File[] baseFolders = (useShellFolder)
+ ? (File[]) ShellFolder.get("fileChooserComboBoxFolders")
+ : fsv.getRoots();
directories.addAll(Arrays.asList(baseFolders));
// Get the canonical (full) path. This has the side
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualSubstSubtables.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualSubstSubtables.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -583,6 +583,8 @@
LEReferenceTo<ChainSubClassRuleTable>
chainSubClassRuleTable(chainSubClassSetTable, success, chainSubClassRuleTableOffset);
le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount);
+ LEReferenceToArrayOf<le_uint16> backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount);
+ if( LE_FAILURE(success) ) { return 0; }
le_uint16 inputGlyphCount = SWAPW(chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount]) - 1;
LEReferenceToArrayOf<le_uint16> inputClassArray(base, success, &chainSubClassRuleTable->backtrackClassArray[backtrackGlyphCount + 1],inputGlyphCount+2); // +2 for the lookaheadGlyphCount count
le_uint16 lookaheadGlyphCount = SWAPW(inputClassArray.getObject(inputGlyphCount, success));
@@ -599,8 +601,6 @@
}
tempIterator.prev();
- LEReferenceToArrayOf<le_uint16> backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount);
- if( LE_FAILURE(success) ) { return 0; }
if (! matchGlyphClasses(backtrackClassArray, backtrackGlyphCount,
&tempIterator, backtrackClassDefinitionTable, success, TRUE)) {
continue;
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/CursiveAttachmentSubtables.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/CursiveAttachmentSubtables.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -45,6 +45,9 @@
le_int32 coverageIndex = getGlyphCoverage(base, glyphID, success);
le_uint16 eeCount = SWAPW(entryExitCount);
+ LEReferenceToArrayOf<EntryExitRecord>
+ entryExitRecordsArrayRef(base, success, entryExitRecords, coverageIndex);
+
if (coverageIndex < 0 || coverageIndex >= eeCount || LE_FAILURE(success)) {
glyphIterator->setCursiveGlyph();
return 0;
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/Features.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/Features.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -40,6 +40,9 @@
LEReferenceTo<FeatureTable> FeatureListTable::getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const
{
+ LEReferenceToArrayOf<FeatureRecord>
+ featureRecordArrayRef(base, success, featureRecordArray, featureIndex);
+
if (featureIndex >= SWAPW(featureCount) || LE_FAILURE(success)) {
return LEReferenceTo<FeatureTable>();
}
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LETableReference.h Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LETableReference.h Thu Jan 29 03:54:45 2015 +0000
@@ -470,7 +470,12 @@
#endif
const T& getObject(le_uint32 i, LEErrorCode &success) const {
- return *getAlias(i,success);
+ const T *ret = getAlias(i, success);
+ if (LE_FAILURE(success) || ret==NULL) {
+ return *(new T(0));
+ } else {
+ return *ret;
+ }
}
/**
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstSubtables.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstSubtables.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -64,6 +64,9 @@
LEReferenceTo<LigatureTable> ligTable(ligSetTable, success, ligTableOffset);
if(LE_FAILURE(success)) { return 0; }
le_uint16 compCount = SWAPW(ligTable->compCount) - 1;
+ LEReferenceToArrayOf<TTGlyphID>
+ componentArrayRef(base, success, ligTable->componentArray, compCount);
+ if (LE_FAILURE(success)) { return 0; }
le_int32 startPosition = glyphIterator->getCurrStreamPosition();
TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph);
le_uint16 comp;
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/MultipleSubstSubtables.cpp Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/MultipleSubstSubtables.cpp Thu Jan 29 03:54:45 2015 +0000
@@ -61,6 +61,8 @@
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
le_uint16 seqCount = SWAPW(sequenceCount);
+ LEReferenceToArrayOf<Offset>
+ sequenceTableOffsetArrayRef(base, success, sequenceTableOffsetArray, seqCount);
if (LE_FAILURE(success)) {
return 0;
--- a/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Thu Jan 29 03:54:45 2015 +0000
@@ -36,6 +36,7 @@
import java.util.*;
import java.util.List;
import java.util.concurrent.*;
+import java.util.stream.Stream;
import static sun.awt.shell.Win32ShellFolder2.*;
import sun.awt.OSInfo;
@@ -251,7 +252,7 @@
if (file == null) {
file = getDesktop();
}
- return file;
+ return checkFile(file);
} else if (key.equals("roots")) {
// Should be "History" and "Desktop" ?
if (roots == null) {
@@ -262,11 +263,11 @@
roots = (File[])super.get(key);
}
}
- return roots;
+ return checkFiles(roots);
} else if (key.equals("fileChooserComboBoxFolders")) {
Win32ShellFolder2 desktop = getDesktop();
- if (desktop != null) {
+ if (desktop != null && checkFile(desktop) != null) {
ArrayList<File> folders = new ArrayList<File>();
Win32ShellFolder2 drives = getDrives();
@@ -277,7 +278,7 @@
folders.add(desktop);
// Add all second level folders
- File[] secondLevelFolders = desktop.listFiles();
+ File[] secondLevelFolders = checkFiles(desktop.listFiles());
Arrays.sort(secondLevelFolders);
for (File secondLevelFolder : secondLevelFolders) {
Win32ShellFolder2 folder = (Win32ShellFolder2) secondLevelFolder;
@@ -285,7 +286,7 @@
folders.add(folder);
// Add third level for "My Computer"
if (folder.equals(drives)) {
- File[] thirdLevelFolders = folder.listFiles();
+ File[] thirdLevelFolders = checkFiles(folder.listFiles());
if (thirdLevelFolders != null && thirdLevelFolders.length > 0) {
List<File> thirdLevelFoldersList = Arrays.asList(thirdLevelFolders);
@@ -295,7 +296,7 @@
}
}
}
- return folders.toArray(new File[folders.size()]);
+ return checkFiles(folders);
} else {
return super.get(key);
}
@@ -332,7 +333,7 @@
}
}
}
- return folders.toArray(new File[folders.size()]);
+ return checkFiles(folders);
} else if (key.startsWith("fileChooserIcon ")) {
String name = key.substring(key.indexOf(" ") + 1);
@@ -378,6 +379,41 @@
return null;
}
+ private File checkFile(File file) {
+ SecurityManager sm = System.getSecurityManager();
+ return (sm == null || file == null) ? file : checkFile(file, sm);
+ }
+
+ private File checkFile(File file, SecurityManager sm) {
+ try {
+ sm.checkRead(file.getPath());
+ return file;
+ } catch (SecurityException se) {
+ return null;
+ }
+ }
+
+ private File[] checkFiles(File[] files) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm == null || files == null || files.length == 0) {
+ return files;
+ }
+ return checkFiles(Arrays.stream(files), sm);
+ }
+
+ private File[] checkFiles(List<File> files) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm == null || files.isEmpty()) {
+ return files.toArray(new File[files.size()]);
+ }
+ return checkFiles(files.stream(), sm);
+ }
+
+ private File[] checkFiles(Stream<File> filesStream, SecurityManager sm) {
+ return filesStream.filter((file) -> checkFile(file, sm) != null)
+ .toArray(File[]::new);
+ }
+
/**
* Does <code>dir</code> represent a "computer" such as a node on the network, or
* "My Computer" on the desktop.
--- a/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/BerDecoder.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.naming/share/classes/com/sun/jndi/ldap/BerDecoder.java Thu Jan 29 03:54:45 2015 +0000
@@ -95,6 +95,9 @@
for( int i = 0; i < lengthbyte; i++) {
retval = (retval << 8) + (buf[offset++] & 0xff);
}
+ if (retval < 0) {
+ throw new DecodeException("Invalid length bytes");
+ }
return retval;
} else {
return lengthbyte;
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/Transport.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/Transport.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -37,7 +37,10 @@
import java.rmi.server.RemoteServer;
import java.rmi.server.ServerNotActiveException;
import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permissions;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import sun.rmi.runtime.Log;
import sun.rmi.server.Dispatcher;
import sun.rmi.server.UnicastServerRef;
@@ -69,6 +72,15 @@
/** ObjID for DGCImpl */
private static final ObjID dgcID = new ObjID(ObjID.DGC_ID);
+ /** AccessControlContext for setting context ClassLoader */
+ private static final AccessControlContext SETCCL_ACC;
+ static {
+ Permissions perms = new Permissions();
+ perms.add(new RuntimePermission("setContextClassLoader"));
+ ProtectionDomain[] pd = { new ProtectionDomain(null, perms) };
+ SETCCL_ACC = new AccessControlContext(pd);
+ }
+
/**
* Returns a <I>Channel</I> that generates connections to the
* endpoint <I>ep</I>. A Channel is an object that creates and
@@ -118,6 +130,16 @@
protected abstract void checkAcceptPermission(AccessControlContext acc);
/**
+ * Sets the context class loader for the current thread.
+ */
+ private static void setContextClassLoader(ClassLoader ccl) {
+ AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
+ Thread.currentThread().setContextClassLoader(ccl);
+ return null;
+ }, SETCCL_ACC);
+ }
+
+ /**
* Service an incoming remote call. When a message arrives on the
* connection indicating the beginning of a remote call, the
* threads are required to call the <I>serviceCall</I> method of
@@ -165,11 +187,10 @@
target.getAccessControlContext();
ClassLoader ccl = target.getContextClassLoader();
- Thread t = Thread.currentThread();
- ClassLoader savedCcl = t.getContextClassLoader();
+ ClassLoader savedCcl = Thread.currentThread().getContextClassLoader();
try {
- t.setContextClassLoader(ccl);
+ setContextClassLoader(ccl);
currentTransport.set(this);
try {
java.security.AccessController.doPrivileged(
@@ -184,7 +205,7 @@
throw (IOException) pae.getException();
}
} finally {
- t.setContextClassLoader(savedCcl);
+ setContextClassLoader(savedCcl);
currentTransport.set(null);
}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -49,7 +49,9 @@
import java.rmi.server.UID;
import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Permissions;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -120,6 +122,14 @@
private static final ThreadLocal<ConnectionHandler>
threadConnectionHandler = new ThreadLocal<>();
+ /** an AccessControlContext with no permissions */
+ private static final AccessControlContext NOPERMS_ACC;
+ static {
+ Permissions perms = new Permissions();
+ ProtectionDomain[] pd = { new ProtectionDomain(null, perms) };
+ NOPERMS_ACC = new AccessControlContext(pd);
+ }
+
/** endpoints for this transport */
private final LinkedList<TCPEndpoint> epList;
/** number of objects exported on this transport */
@@ -664,7 +674,10 @@
t.setName("RMI TCP Connection(" +
connectionCount.incrementAndGet() +
")-" + remoteHost);
- run0();
+ AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
+ run0();
+ return null;
+ }, NOPERMS_ACC);
} finally {
t.setName(name);
}
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSHeader.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSHeader.java Thu Jan 29 03:54:45 2015 +0000
@@ -270,6 +270,9 @@
value <<= 8;
value += 0x0ff & in.read();
}
+ if (value < 0) {
+ throw new IOException("Invalid length bytes");
+ }
}
return value;
}
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSNameImpl.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/GSSNameImpl.java Thu Jan 29 03:54:45 2015 +0000
@@ -257,7 +257,8 @@
((0xFF & bytes[pos++]) << 16) |
((0xFF & bytes[pos++]) << 8) |
(0xFF & bytes[pos++]));
- if (pos > bytes.length - mechPortionLen) {
+
+ if (mechPortionLen < 0 || pos > bytes.length - mechPortionLen) {
throw new GSSExceptionImpl(GSSException.BAD_NAME,
"Exported name mech name is corrupted!");
}
--- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java Thu Jan 29 03:54:45 2015 +0000
@@ -233,6 +233,9 @@
((0xFF & nameVal[pos++]) << 16) |
((0xFF & nameVal[pos++]) << 8) |
(0xFF & nameVal[pos++]));
+ if (mechPortionLen < 0) {
+ throw new GSSException(GSSException.BAD_NAME);
+ }
byte[] mechPortion = new byte[mechPortionLen];
System.arraycopy(nameVal, pos, mechPortion, 0, mechPortionLen);
return mechPortion;
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/Config.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/Config.java Thu Jan 29 03:54:45 2015 +0000
@@ -913,9 +913,9 @@
private static String unquote(String s) {
s = s.trim();
- if (s.isEmpty()) return s;
- if (s.charAt(0) == '"' && s.charAt(s.length()-1) == '"' ||
- s.charAt(0) == '\'' && s.charAt(s.length()-1) == '\'') {
+ if (s.length() >= 2 &&
+ ((s.charAt(0) == '"' && s.charAt(s.length()-1) == '"') ||
+ (s.charAt(0) == '\'' && s.charAt(s.length()-1) == '\''))) {
s = s.substring(1, s.length()-1).trim();
}
return s;
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/SCDynamicStoreConfig.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/SCDynamicStoreConfig.java Thu Jan 29 03:54:45 2015 +0000
@@ -113,15 +113,17 @@
@SuppressWarnings("unchecked")
private static Hashtable<String, Object> convertNativeConfig(
- Hashtable<String, Object> stanzaTable) {
+ Hashtable<String, Object> stanzaTable) throws IOException {
// convert SCDynamicStore realm structure to Java realm structure
Hashtable<String, ?> realms =
(Hashtable<String, ?>) stanzaTable.get("realms");
- if (realms != null) {
- stanzaTable.remove("realms");
- Hashtable<String, Object> realmsTable = convertRealmConfigs(realms);
- stanzaTable.put("realms", realmsTable);
+ if (realms == null || realms.isEmpty()) {
+ throw new IOException(
+ "SCDynamicStore contains an empty Kerberos setting");
}
+ stanzaTable.remove("realms");
+ Hashtable<String, Object> realmsTable = convertRealmConfigs(realms);
+ stanzaTable.put("realms", realmsTable);
WrapAllStringInVector(stanzaTable);
if (DEBUG) System.out.println("stanzaTable : " + stanzaTable);
return stanzaTable;
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java Thu Jan 29 03:54:45 2015 +0000
@@ -118,7 +118,7 @@
} else {
type = read(4);
}
- length = read(4);
+ length = readLength4();
List<String> result = new ArrayList<String>();
/*
* DCE includes the principal's realm in the count; the new format
@@ -127,7 +127,7 @@
if (version == KRB5_FCC_FVNO_1)
length--;
for (int i = 0; i <= length; i++) {
- namelength = read(4);
+ namelength = readLength4();
byte[] bytes = IOUtils.readFully(this, namelength, true);
result.add(new String(bytes));
}
@@ -184,7 +184,7 @@
keyType = read(2);
if (version == KRB5_FCC_FVNO_3)
read(2); /* keytype recorded twice in fvno 3 */
- keyLen = read(4);
+ keyLen = readLength4();
byte[] bytes = IOUtils.readFully(this, keyLen, true);
return new EncryptionKey(bytes, keyType, version);
}
@@ -207,12 +207,12 @@
HostAddress[] readAddr() throws IOException, KrbApErrException {
int numAddrs, addrType, addrLength;
- numAddrs = read(4);
+ numAddrs = readLength4();
if (numAddrs > 0) {
List<HostAddress> addrs = new ArrayList<>();
for (int i = 0; i < numAddrs; i++) {
addrType = read(2);
- addrLength = read(4);
+ addrLength = readLength4();
if (!(addrLength == 4 || addrLength == 16)) {
if (DEBUG) {
System.out.println("Incorrect address format.");
@@ -231,13 +231,13 @@
AuthorizationDataEntry[] readAuth() throws IOException {
int num, adtype, adlength;
- num = read(4);
+ num = readLength4();
if (num > 0) {
List<AuthorizationDataEntry> auData = new ArrayList<>();
byte[] data = null;
for (int i = 0; i < num; i++) {
adtype = read(2);
- adlength = read(4);
+ adlength = readLength4();
data = IOUtils.readFully(this, adlength, true);
auData.add(new AuthorizationDataEntry(adtype, data));
}
@@ -248,7 +248,7 @@
byte[] readData() throws IOException {
int length;
- length = read(4);
+ length = readLength4();
if (length == 0) {
return null;
} else {
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java Thu Jan 29 03:54:45 2015 +0000
@@ -150,43 +150,43 @@
synchronized void init(PrincipalName principal, String name)
throws IOException, KrbException {
primaryPrincipal = principal;
- CCacheOutputStream cos =
- new CCacheOutputStream(new FileOutputStream(name));
- version = KRB5_FCC_FVNO_3;
- cos.writeHeader(primaryPrincipal, version);
- cos.close();
+ try (FileOutputStream fos = new FileOutputStream(name);
+ CCacheOutputStream cos = new CCacheOutputStream(fos)) {
+ version = KRB5_FCC_FVNO_3;
+ cos.writeHeader(primaryPrincipal, version);
+ }
load(name);
}
synchronized void load(String name) throws IOException, KrbException {
PrincipalName p;
- CCacheInputStream cis =
- new CCacheInputStream(new FileInputStream(name));
- version = cis.readVersion();
- if (version == KRB5_FCC_FVNO_4) {
- tag = cis.readTag();
- } else {
- tag = null;
- if (version == KRB5_FCC_FVNO_1 || version == KRB5_FCC_FVNO_2) {
- cis.setNativeByteOrder();
+ try (FileInputStream fis = new FileInputStream(name);
+ CCacheInputStream cis = new CCacheInputStream(fis)) {
+ version = cis.readVersion();
+ if (version == KRB5_FCC_FVNO_4) {
+ tag = cis.readTag();
+ } else {
+ tag = null;
+ if (version == KRB5_FCC_FVNO_1 || version == KRB5_FCC_FVNO_2) {
+ cis.setNativeByteOrder();
+ }
+ }
+ p = cis.readPrincipal(version);
+
+ if (primaryPrincipal != null) {
+ if (!(primaryPrincipal.match(p))) {
+ throw new IOException("Primary principals don't match.");
+ }
+ } else
+ primaryPrincipal = p;
+ credentialsList = new Vector<Credentials>();
+ while (cis.available() > 0) {
+ Credentials cred = cis.readCred(version);
+ if (cred != null) {
+ credentialsList.addElement(cred);
+ }
}
}
- p = cis.readPrincipal(version);
-
- if (primaryPrincipal != null) {
- if (!(primaryPrincipal.match(p))) {
- throw new IOException("Primary principals don't match.");
- }
- } else
- primaryPrincipal = p;
- credentialsList = new Vector<Credentials> ();
- while (cis.available() > 0) {
- Credentials cred = cis.readCred(version);
- if (cred != null) {
- credentialsList.addElement(cred);
- }
- }
- cis.close();
}
@@ -245,16 +245,16 @@
* Saves the credentials cache file to the disk.
*/
public synchronized void save() throws IOException, Asn1Exception {
- CCacheOutputStream cos
- = new CCacheOutputStream(new FileOutputStream(cacheName));
- cos.writeHeader(primaryPrincipal, version);
- Credentials[] tmp = null;
- if ((tmp = getCredsList()) != null) {
- for (int i = 0; i < tmp.length; i++) {
- cos.addCreds(tmp[i]);
+ try (FileOutputStream fos = new FileOutputStream(cacheName);
+ CCacheOutputStream cos = new CCacheOutputStream(fos)) {
+ cos.writeHeader(primaryPrincipal, version);
+ Credentials[] tmp = null;
+ if ((tmp = getCredsList()) != null) {
+ for (int i = 0; i < tmp.length; i++) {
+ cos.addCreds(tmp[i]);
+ }
}
}
- cos.close();
}
boolean match(String[] s1, String[] s2) {
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/util/KrbDataInputStream.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/util/KrbDataInputStream.java Thu Jan 29 03:54:45 2015 +0000
@@ -56,15 +56,33 @@
public KrbDataInputStream(InputStream is){
super(is);
}
+
+ /**
+ * Reads a length value which is represented in 4 bytes from
+ * this input stream. The value must be positive.
+ * @return the length value represented by this byte array.
+ * @throws IOException if there are not enough bytes or it represents
+ * a negative value
+ */
+ final public int readLength4() throws IOException {
+ int len = read(4);
+ if (len < 0) {
+ throw new IOException("Invalid encoding");
+ }
+ return len;
+ }
+
/**
* Reads up to the specific number of bytes from this input stream.
* @param num the number of bytes to be read.
* @return the int value of this byte array.
- * @exception IOException.
+ * @throws IOException if there are not enough bytes
*/
- public int read(int num) throws IOException{
+ public int read(int num) throws IOException {
byte[] bytes = new byte[num];
- read(bytes, 0, num);
+ if (read(bytes, 0, num) != num) {
+ throw new IOException("Premature end of stream reached");
+ }
int result = 0;
for (int i = 0; i < num; i++) {
if (bigEndian) {
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/Code.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/Code.java Thu Jan 29 03:54:45 2015 +0000
@@ -103,7 +103,7 @@
case HTTP_UNAVAILABLE: return " Service Unavailable";
case HTTP_GATEWAY_TIMEOUT: return " Gateway Timeout";
case HTTP_VERSION: return " HTTP Version Not Supported";
- default: return "";
+ default: return " ";
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.security.auth/solaris/native/libjaas/Solaris.c Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+#include "com_sun_security_auth_module_SolarisSystem.h"
+#include <stdio.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pwd.h>
+
+static void throwIllegalArgumentException(JNIEnv *env, const char *msg) {
+ jclass clazz = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
+ if (clazz != NULL)
+ (*env)->ThrowNew(env, clazz, msg);
+}
+
+JNIEXPORT void JNICALL
+Java_com_sun_security_auth_module_SolarisSystem_getSolarisInfo
+ (JNIEnv *env, jobject obj) {
+
+ int i;
+ char pwd_buf[1024];
+ struct passwd pwd;
+ jsize numSuppGroups = getgroups(0, NULL);
+ jfieldID fid;
+ jstring jstr;
+ jlongArray jgroups;
+ jlong *jgroupsAsArray;
+ gid_t *groups;
+ jclass cls;
+
+ groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t));
+
+ if (groups == NULL) {
+ jclass cls = (*env)->FindClass(env,"java/lang/OutOfMemoryError");
+ if (cls != NULL)
+ (*env)->ThrowNew(env, cls, NULL);
+ return;
+ }
+
+ cls = (*env)->GetObjectClass(env, obj);
+
+ memset(pwd_buf, 0, sizeof(pwd_buf));
+ if (getpwuid_r(getuid(), &pwd, pwd_buf, sizeof(pwd_buf)) != NULL &&
+ getgroups(numSuppGroups, groups) != -1) {
+
+ /*
+ * set username
+ */
+ fid = (*env)->GetFieldID(env, cls, "username", "Ljava/lang/String;");
+ if (fid == 0) {
+ (*env)->ExceptionClear(env);
+ throwIllegalArgumentException(env, "invalid field: username");
+ goto cleanupAndReturn;
+ }
+ jstr = (*env)->NewStringUTF(env, pwd.pw_name);
+ if (jstr == NULL) {
+ goto cleanupAndReturn;
+ }
+ (*env)->SetObjectField(env, obj, fid, jstr);
+
+ /*
+ * set uid
+ */
+ fid = (*env)->GetFieldID(env, cls, "uid", "J");
+ if (fid == 0) {
+ (*env)->ExceptionClear(env);
+ throwIllegalArgumentException(env, "invalid field: uid");
+ goto cleanupAndReturn;
+ }
+ (*env)->SetLongField(env, obj, fid, pwd.pw_uid);
+
+ /*
+ * set gid
+ */
+ fid = (*env)->GetFieldID(env, cls, "gid", "J");
+ if (fid == 0) {
+ (*env)->ExceptionClear(env);
+ throwIllegalArgumentException(env, "invalid field: gid");
+ goto cleanupAndReturn;
+ }
+ (*env)->SetLongField(env, obj, fid, pwd.pw_gid);
+
+ /*
+ * set supplementary groups
+ */
+ fid = (*env)->GetFieldID(env, cls, "groups", "[J");
+ if (fid == 0) {
+ (*env)->ExceptionClear(env);
+ throwIllegalArgumentException(env, "invalid field: groups");
+ goto cleanupAndReturn;
+ }
+
+ jgroups = (*env)->NewLongArray(env, numSuppGroups);
+ if (jgroups == NULL) {
+ goto cleanupAndReturn;
+ }
+ jgroupsAsArray = (*env)->GetLongArrayElements(env, jgroups, 0);
+ if (jgroupsAsArray == NULL) {
+ goto cleanupAndReturn;
+ }
+ for (i = 0; i < numSuppGroups; i++)
+ jgroupsAsArray[i] = groups[i];
+ (*env)->ReleaseLongArrayElements(env, jgroups, jgroupsAsArray, 0);
+ (*env)->SetObjectField(env, obj, fid, jgroups);
+ }
+cleanupAndReturn:
+ free(groups);
+
+ return;
+}
--- a/jdk/src/jdk.security.auth/unix/native/libjaas/Solaris.c Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <jni.h>
-#include "com_sun_security_auth_module_SolarisSystem.h"
-#include <stdio.h>
-#include <pwd.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pwd.h>
-
-static void throwIllegalArgumentException(JNIEnv *env, const char *msg) {
- jclass clazz = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
- if (clazz != NULL)
- (*env)->ThrowNew(env, clazz, msg);
-}
-
-JNIEXPORT void JNICALL
-Java_com_sun_security_auth_module_SolarisSystem_getSolarisInfo
- (JNIEnv *env, jobject obj) {
-
- int i;
- char pwd_buf[1024];
- struct passwd pwd;
- jsize numSuppGroups = getgroups(0, NULL);
- jfieldID fid;
- jstring jstr;
- jlongArray jgroups;
- jlong *jgroupsAsArray;
- gid_t *groups;
- jclass cls;
-
- groups = (gid_t *)calloc(numSuppGroups, sizeof(gid_t));
-
- if (groups == NULL) {
- jclass cls = (*env)->FindClass(env,"java/lang/OutOfMemoryError");
- if (cls != NULL)
- (*env)->ThrowNew(env, cls, NULL);
- return;
- }
-
- cls = (*env)->GetObjectClass(env, obj);
-
- memset(pwd_buf, 0, sizeof(pwd_buf));
- if (getpwuid_r(getuid(), &pwd, pwd_buf, sizeof(pwd_buf)) != NULL &&
- getgroups(numSuppGroups, groups) != -1) {
-
- /*
- * set username
- */
- fid = (*env)->GetFieldID(env, cls, "username", "Ljava/lang/String;");
- if (fid == 0) {
- (*env)->ExceptionClear(env);
- throwIllegalArgumentException(env, "invalid field: username");
- goto cleanupAndReturn;
- }
- jstr = (*env)->NewStringUTF(env, pwd.pw_name);
- if (jstr == NULL) {
- goto cleanupAndReturn;
- }
- (*env)->SetObjectField(env, obj, fid, jstr);
-
- /*
- * set uid
- */
- fid = (*env)->GetFieldID(env, cls, "uid", "J");
- if (fid == 0) {
- (*env)->ExceptionClear(env);
- throwIllegalArgumentException(env, "invalid field: uid");
- goto cleanupAndReturn;
- }
- (*env)->SetLongField(env, obj, fid, pwd.pw_uid);
-
- /*
- * set gid
- */
- fid = (*env)->GetFieldID(env, cls, "gid", "J");
- if (fid == 0) {
- (*env)->ExceptionClear(env);
- throwIllegalArgumentException(env, "invalid field: gid");
- goto cleanupAndReturn;
- }
- (*env)->SetLongField(env, obj, fid, pwd.pw_gid);
-
- /*
- * set supplementary groups
- */
- fid = (*env)->GetFieldID(env, cls, "groups", "[J");
- if (fid == 0) {
- (*env)->ExceptionClear(env);
- throwIllegalArgumentException(env, "invalid field: groups");
- goto cleanupAndReturn;
- }
-
- jgroups = (*env)->NewLongArray(env, numSuppGroups);
- if (jgroups == NULL) {
- goto cleanupAndReturn;
- }
- jgroupsAsArray = (*env)->GetLongArrayElements(env, jgroups, 0);
- if (jgroupsAsArray == NULL) {
- goto cleanupAndReturn;
- }
- for (i = 0; i < numSuppGroups; i++)
- jgroupsAsArray[i] = groups[i];
- (*env)->ReleaseLongArrayElements(env, jgroups, jgroupsAsArray, 0);
- (*env)->SetObjectField(env, obj, fid, jgroups);
- }
-cleanupAndReturn:
- free(groups);
-
- return;
-}
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 201, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,6 @@
import java.util.zip.InflaterInputStream;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.ZipException;
-import java.util.zip.ZipError;
import static java.lang.Boolean.*;
import static jdk.nio.zipfs.ZipConstants.*;
import static jdk.nio.zipfs.ZipUtils.*;
@@ -119,7 +118,16 @@
this.zc = ZipCoder.get(nameEncoding);
this.defaultdir = new ZipPath(this, getBytes(defaultDir));
this.ch = Files.newByteChannel(zfpath, READ);
- this.cen = initCEN();
+ try {
+ this.cen = initCEN();
+ } catch (IOException x) {
+ try {
+ this.ch.close();
+ } catch (IOException xx) {
+ x.addSuppressed(xx);
+ }
+ throw x;
+ }
}
@Override
@@ -1058,12 +1066,15 @@
int nlen = CENNAM(cen, pos);
int elen = CENEXT(cen, pos);
int clen = CENCOM(cen, pos);
- if ((CENFLG(cen, pos) & 1) != 0)
+ if ((CENFLG(cen, pos) & 1) != 0) {
zerror("invalid CEN header (encrypted entry)");
- if (method != METHOD_STORED && method != METHOD_DEFLATED)
+ }
+ if (method != METHOD_STORED && method != METHOD_DEFLATED) {
zerror("invalid CEN header (unsupported compression method: " + method + ")");
- if (pos + CENHDR + nlen > limit)
+ }
+ if (pos + CENHDR + nlen > limit) {
zerror("invalid CEN header (bad header size)");
+ }
byte[] name = Arrays.copyOfRange(cen, pos + CENHDR, pos + CENHDR + nlen);
IndexNode inode = new IndexNode(name, pos);
inodes.put(inode, inode);
@@ -1533,6 +1544,7 @@
private CRC32 crc;
private Entry e;
private long written;
+ private boolean isClosed = false;
EntryOutputStream(Entry e, OutputStream os)
throws IOException
@@ -1545,9 +1557,14 @@
}
@Override
- public void write(byte b[], int off, int len) throws IOException {
+ public synchronized void write(byte b[], int off, int len)
+ throws IOException
+ {
if (e.type != Entry.FILECH) // only from sync
ensureOpen();
+ if (isClosed) {
+ throw new IOException("Stream closed");
+ }
if (off < 0 || len < 0 || off > b.length - len) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
@@ -1568,7 +1585,11 @@
}
@Override
- public void close() throws IOException {
+ public synchronized void close() throws IOException {
+ if (isClosed) {
+ return;
+ }
+ isClosed = true;
// TBD ensureOpen();
switch (e.method) {
case METHOD_DEFLATED:
@@ -1599,8 +1620,8 @@
}
}
- static void zerror(String msg) {
- throw new ZipError(msg);
+ static void zerror(String msg) throws ZipException {
+ throw new ZipException(msg);
}
// Maxmum number of de/inflater we cache
--- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java Thu Jan 29 03:54:45 2015 +0000
@@ -36,7 +36,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import java.util.zip.ZipError;
+import java.util.zip.ZipException;
import java.util.concurrent.ExecutorService;
/*
@@ -100,7 +100,7 @@
ZipFileSystem zipfs = null;
try {
zipfs = new ZipFileSystem(this, path, env);
- } catch (ZipError ze) {
+ } catch (ZipException ze) {
String pname = path.toString();
if (pname.endsWith(".zip") || pname.endsWith(".jar"))
throw ze;
@@ -122,7 +122,7 @@
ensureFile(path);
try {
return new ZipFileSystem(this, path, env);
- } catch (ZipError ze) {
+ } catch (ZipException ze) {
String pname = path.toString();
if (pname.endsWith(".zip") || pname.endsWith(".jar"))
throw ze;
--- a/jdk/test/ProblemList.txt Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/ProblemList.txt Thu Jan 29 03:54:45 2015 +0000
@@ -127,9 +127,6 @@
# jdk_instrument
-# 8058536
-java/lang/instrument/NativeMethodPrefixAgent.java generic-all
-
# 8061177
java/lang/instrument/RedefineBigClass.sh generic-all
java/lang/instrument/RetransformBigClass.sh generic-all
@@ -248,6 +245,9 @@
# 8062758
java/security/Security/ClassLoaderDeadlock/Deadlock2.sh generic-all
+# 8026393
+sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java generic-all
+
############################################################################
# jdk_sound
--- a/jdk/test/TEST.groups Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/TEST.groups Thu Jan 29 03:54:45 2015 +0000
@@ -628,7 +628,6 @@
sun/net/www/protocol/http \
java/io/BufferedReader/Lines.java \
java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java \
- java/lang/CharSequence/DefaultTest.java \
java/lang/IntegralPrimitiveToString.java \
java/lang/PrimitiveSumMinMaxTest.java \
java/lang/String/StringJoinTest.java \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/net/httpserver/MissingTrailingSpace.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8068795
+ * @summary HttpServer missing tailing space for some response codes
+ * @author lev.priima@oracle.com
+ */
+
+import java.net.InetSocketAddress;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+public class MissingTrailingSpace {
+
+ private static final int noMsgCode = 207;
+ private static final String someContext = "/context";
+
+ public static void main(String[] args) throws Exception {
+ HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
+ try {
+ server.setExecutor(Executors.newFixedThreadPool(1));
+ server.createContext(someContext, new HttpHandler() {
+ @Override
+ public void handle(HttpExchange msg) {
+ try {
+ try {
+ msg.sendResponseHeaders(noMsgCode, -1);
+ } catch(IOException ioe) {
+ ioe.printStackTrace();
+ }
+ } finally {
+ msg.close();
+ }
+ }
+ });
+ server.start();
+ System.out.println("Server started at port "
+ + server.getAddress().getPort());
+
+ runRawSocketHttpClient("localhost", server.getAddress().getPort());
+ } finally {
+ ((ExecutorService)server.getExecutor()).shutdown();
+ server.stop(0);
+ }
+ System.out.println("Server finished.");
+ }
+
+ static void runRawSocketHttpClient(String hostname, int port)
+ throws Exception
+ {
+ Socket socket = null;
+ PrintWriter writer = null;
+ BufferedReader reader = null;
+ final String CRLF = "\r\n";
+ try {
+ socket = new Socket(hostname, port);
+ writer = new PrintWriter(new OutputStreamWriter(
+ socket.getOutputStream()));
+ System.out.println("Client connected by socket: " + socket);
+
+ writer.print("GET " + someContext + "/ HTTP/1.1" + CRLF);
+ writer.print("User-Agent: Java/"
+ + System.getProperty("java.version")
+ + CRLF);
+ writer.print("Host: " + hostname + CRLF);
+ writer.print("Accept: */*" + CRLF);
+ writer.print("Connection: keep-alive" + CRLF);
+ writer.print(CRLF); // Important, else the server will expect that
+ // there's more into the request.
+ writer.flush();
+ System.out.println("Client wrote rquest to socket: " + socket);
+
+ reader = new BufferedReader(new InputStreamReader(
+ socket.getInputStream()));
+ System.out.println("Client start reading from server:" );
+ String line = reader.readLine();
+ if ( !line.endsWith(" ") ) {
+ throw new RuntimeException("respond to unknown code "
+ + noMsgCode
+ + " doesn't return space at the end of the first header.\n"
+ + "Should be: " + "\"" + line + " \""
+ + ", but returns: " + "\"" + line + "\".");
+ }
+ for (; line != null; line = reader.readLine()) {
+ if (line.isEmpty()) {
+ break;
+ }
+ System.out.println("\"" + line + "\"");
+ }
+ System.out.println("Client finished reading from server" );
+ } finally {
+ if (reader != null)
+ try {
+ reader.close();
+ } catch (IOException logOrIgnore) {
+ logOrIgnore.printStackTrace();
+ }
+ if (writer != null) {
+ writer.close();
+ }
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (IOException logOrIgnore) {
+ logOrIgnore.printStackTrace();
+ }
+ }
+ }
+ System.out.println("Client finished." );
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Modal/MultipleDialogs/MultipleDialogs1Test.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2007, 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 8054358
+ * @summary Check whether a set of dialogs created with a toolkit excluded Frame
+ * parent has a proper modal blocking behavior. Also show a document modal
+ * dialog and check if it blocks the document properly.
+ *
+ * @library ../helpers ../../../../lib/testlibrary/
+ * @build ExtendedRobot
+ * @build Flag
+ * @build TestDialog
+ * @build TestFrame
+ * @run main/timeout=500 MultipleDialogs1Test
+ */
+
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Collections;
+import java.util.Iterator;
+
+public class MultipleDialogs1Test {
+
+ private volatile CustomFrame frame;
+ private List<CustomDialog> dialogList;
+
+ private static int delay = 500;
+ private int dialogCount = -1;
+
+ public void createGUI() {
+
+ final int n = 8;
+ dialogList = new ArrayList<>();
+
+ frame = new CustomFrame();
+ frame.setLocation(50, 50);
+ frame.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE);
+ frame.setVisible(true);
+
+ int x = 250, y = 50;
+
+ CustomDialog dlg;
+
+ for (int i = 0; i < n - 1; ++i) {
+
+ dlg = new CustomDialog(frame);
+ dlg.setLocation(x, y);
+ x += 200;
+
+ if (x > 600) {
+ x = 50;
+ y += 200;
+ }
+
+ Dialog.ModalityType type;
+
+ if (i % 3 == 0) {
+ type = Dialog.ModalityType.MODELESS;
+ } else if (i % 3 == 1) {
+ type = Dialog.ModalityType.APPLICATION_MODAL;
+ } else {
+ type = Dialog.ModalityType.TOOLKIT_MODAL;
+ }
+
+ dlg.setModalityType(type);
+ dialogList.add(dlg);
+ }
+
+ dlg = new CustomDialog(frame);
+ dlg.setLocation(x, y);
+ dlg.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
+ dialogList.add(dlg);
+ }
+
+ public void doTest() throws Exception {
+
+ try {
+ EventQueue.invokeAndWait(this::createGUI);
+
+ ExtendedRobot robot = new ExtendedRobot();
+ robot.waitForIdle(delay);
+
+ List<CustomDialog> dialogs = Collections.synchronizedList(dialogList);
+
+ final int n = dialogs.size();
+
+ synchronized(dialogs) {
+ for (int i = 0; i < n - 1; ++i) {
+
+ frame.clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ dialogs.get(i).checkUnblockedDialog(
+ robot, i + ": This is " + getType(i) + ".");
+
+ frame.checkUnblockedFrame(robot, i + ": Other dialogs are visible.");
+
+ if (i > 0) {
+ for (int j = 0; j < i; j++) {
+ dialogs.get(j).checkUnblockedDialog(robot, j + ": A toolkit modality " +
+ "excluded frame is a parent of this dialog.");
+ }
+ }
+ } // i
+
+ frame.clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ dialogs.get(n - 1).checkUnblockedDialog(
+ robot, (n - 1) + ": This is " + getType(n - 1) + ".");
+
+ frame.checkBlockedFrame(robot,
+ "A document modal dialog with Frame parent is visible.");
+
+ for (int i = 0; i < n - 1; ++i) {
+ dialogs.get(i).checkUnblockedDialog(robot,
+ i + ": A document modal dialog should not block " +
+ "this dialog. The parent is modality excluded.");
+ }
+
+ dialogs.get(n - 1).clickCloseButton(robot);
+ robot.waitForIdle(delay);
+
+ for (int i = 0; i < n - 1; ++i) {
+ dialogs.get(i).checkUnblockedDialog(robot, i + ": A document modal " +
+ "dialog which blocked this dialog was closed.");
+ }
+ frame.checkUnblockedFrame(robot,
+ "A blocking document modal dialog was closed.");
+ robot.waitForIdle(delay);
+ } // synchronized
+
+ } finally {
+ EventQueue.invokeAndWait(this::closeAll);
+ }
+ }
+
+ private String getType(int i) {
+
+ switch (dialogList.get(i).getModalityType()) {
+ case APPLICATION_MODAL:
+ return "an application modal dialog";
+ case DOCUMENT_MODAL:
+ return "a document modal dialog";
+ case TOOLKIT_MODAL:
+ return "a toolkit modal dialog";
+ }
+ return "a modeless dialog";
+ }
+
+ private void closeAll() {
+
+ if (frame != null) { frame.dispose(); }
+ if (dialogList != null) {
+ Iterator<CustomDialog> it = dialogList.iterator();
+ while (it.hasNext()) { it.next().dispose(); }
+ }
+ }
+
+ class CustomFrame extends TestFrame {
+
+ @Override
+ public void doOpenAction() {
+ if ((dialogList != null) && (dialogList.size() > dialogCount)) {
+ dialogCount++;
+ CustomDialog d = dialogList.get(dialogCount);
+ if (d != null) { d.setVisible(true); }
+ }
+ }
+ }
+
+ class CustomDialog extends TestDialog {
+
+ public CustomDialog(Frame f) { super(f); }
+ public CustomDialog(Dialog d) { super(d); }
+
+ @Override
+ public void doCloseAction() { this.dispose(); }
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ (new MultipleDialogs1Test()).doTest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Modal/MultipleDialogs/MultipleDialogs2Test.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2007, 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 8054358
+ * @summary Check whether a set of dialogs created with an application excluded Frame
+ * parent has a proper modal blocking behavior. Also show a document modal
+ * dialog and check if it blocks the document properly.
+ *
+ * @library ../helpers ../../../../lib/testlibrary/
+ * @build ExtendedRobot
+ * @build Flag
+ * @build TestDialog
+ * @build TestFrame
+ * @run main/timeout=500 MultipleDialogs2Test
+ */
+
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Collections;
+import java.util.Iterator;
+
+public class MultipleDialogs2Test {
+
+ private volatile CustomFrame frame;
+ private List<CustomDialog> dialogList;
+ private static final int delay = 500;
+
+ private int dialogCount = -1;
+
+ private void createGUI() {
+
+ final int n = 8;
+ dialogList = new ArrayList<>();
+
+ frame = new CustomFrame();
+ frame.setLocation(50, 50);
+ frame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
+ frame.setVisible(true);
+
+ CustomDialog dlg;
+
+ int x = 250, y = 50;
+ for (int i = 0; i < n - 1; ++i) {
+
+ dlg = new CustomDialog(frame);
+ dlg.setLocation(x, y);
+ x += 200;
+ if (x > 600) {
+ x = 50;
+ y += 200;
+ }
+
+ Dialog.ModalityType type;
+ if (i % 3 == 0) {
+ type = Dialog.ModalityType.MODELESS;
+ } else if (i % 3 == 1) {
+ type = Dialog.ModalityType.APPLICATION_MODAL;
+ } else {
+ type = Dialog.ModalityType.TOOLKIT_MODAL;
+ }
+ dlg.setModalityType(type);
+ dialogList.add(dlg);
+ }
+
+ dlg = new CustomDialog(frame);
+ dlg.setLocation(x, y);
+ dlg.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
+ dialogList.add(dlg);
+ }
+
+ public void doTest() throws Exception {
+
+ try {
+ EventQueue.invokeAndWait(this::createGUI);
+
+ ExtendedRobot robot = new ExtendedRobot();
+ robot.waitForIdle(delay);
+
+ List<CustomDialog> dialogs = Collections.synchronizedList(dialogList);
+ final int n = dialogs.size();
+
+ synchronized(dialogs) {
+ for (int i = 0; i < n - 1; ++i) {
+
+ frame.clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ dialogs.get(i).checkUnblockedDialog(
+ robot, i + ": This is " + getType(i) + ".");
+
+ if (isToolkitModal(i)) {
+
+ for (int j = 0; j < i; ++j) {
+ dialogs.get(j).checkBlockedDialog(robot, j + ": This dialog " +
+ "should be blocked by a toolkit modal dialog.");
+ }
+
+ frame.checkBlockedFrame(robot, i + ": A toolkit modal dialog " +
+ "should block this application modality excluded frame.");
+
+ break;
+
+ } else {
+ for (int j = 0; j < i; ++j) {
+ dialogs.get(j).checkUnblockedDialog(robot,
+ j + ": An application modality excluded frame " +
+ "is the parent of this dialog.");
+ }
+
+ frame.checkUnblockedFrame(robot, i + ": The frame is " +
+ "application modality excluded, but it is blocked.");
+ }
+ }
+
+ int tkIndex = dialogCount; // continue testing
+ final int tk0 = tkIndex;
+
+ for (int i = tk0 + 1; i < n - 1; ++i) {
+
+ dialogs.get(tkIndex).clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ frame.checkBlockedFrame(robot, i + ": A toolkit modal dialog " +
+ "should block this application modality excluded frame.");
+
+ if (isToolkitModal(i)) {
+ dialogs.get(i).checkUnblockedDialog(robot, i + ": This is " +
+ "a toolkit modal dialog with blocked frame parent. " +
+ "Another toolkit modal dialog is visible.");
+
+ for (int j = 0; j < i; ++j) {
+ dialogs.get(j).checkBlockedDialog(robot, j + ": " +
+ "A toolkit modal dialog should block this child " +
+ "dialog of application modality excluded frame.");
+ }
+ tkIndex = i;
+ } else {
+ dialogs.get(i).checkBlockedDialog(
+ robot, i + ": This is " + getType(i) + " with blocked " +
+ "Frame parent. Also, a toolkit modal dialog is visible.");
+
+ for (int j = 0; j < i; ++j) {
+ if (j != tkIndex) {
+ dialogs.get(j).checkBlockedDialog(robot, j +
+ ": A toolkit modal dialog should block this " +
+ "child dialog of an application modality excluded frame.");
+ }
+ }
+ }
+ }
+
+ // show a document modal dialog; the toolkit modal dialog should block it
+ dialogs.get(tkIndex).clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ frame.checkBlockedFrame(robot, "A toolkit modal dialog is visible.");
+
+ for (int i = 0; i < n; ++i) {
+ if (i == tkIndex) {
+ dialogs.get(tkIndex).checkUnblockedDialog(robot,
+ tkIndex + ": This is a toolkit modal dialog. " +
+ "A document modal dialog is visible.");
+ } else {
+ dialogs.get(i).checkBlockedDialog(robot,
+ i + ": A toolkit modal dialog should block this dialog.");
+ }
+ }
+
+ dialogs.get(tk0 + 3).clickCloseButton(robot); // close 2nd toolkit dialog
+ robot.waitForIdle(delay);
+
+ for (int i = 0; i < n; ++i) {
+
+ if (i == tk0 + 3) { continue; }
+ if (i == tk0) {
+ dialogs.get(i).checkUnblockedDialog(robot,
+ i + ": This is a toolkit modal dialog. A blocking " +
+ "toolkit modal dialog was opened and then closed.");
+ } else {
+ dialogs.get(i).checkBlockedDialog(robot,
+ i + ": This dialog should be blocked by a toolkit modal dialog. " +
+ "Another blocking toolkit modal dialog was closed.");
+ }
+ }
+
+ dialogs.get(tk0).clickCloseButton(robot);
+ robot.waitForIdle(delay);
+
+ frame.checkBlockedFrame(
+ robot, "A document modal dialog should block this Frame.");
+
+ for (int i = 0; i < n - 1; ++i) {
+ if (!isToolkitModal(i)) {
+ dialogs.get(i).checkUnblockedDialog(robot, i + ": The parent " +
+ "of the dialog is an app modality excluded Frame.");
+ }
+ }
+
+ dialogs.get(n - 1).clickCloseButton(robot);
+ robot.waitForIdle(delay);
+
+ frame.checkUnblockedFrame(robot, "A document modal dialog " +
+ "blocking this Frame was closed.");
+
+ for (int i = 0; i < n - 1; ++i) {
+ if (!isToolkitModal(i)) {
+ dialogs.get(i).checkUnblockedDialog(robot, i + ": A document modal " +
+ "dialog blocking the parent frame was closed.");
+ }
+ }
+ } // synchronized
+
+ } finally {
+ EventQueue.invokeAndWait(this::closeAll);
+ }
+ }
+
+ private boolean isToolkitModal(int i) { return (i % 3 == 2); }
+
+ private String getType(int i) {
+
+ switch (dialogList.get(i).getModalityType()) {
+ case APPLICATION_MODAL:
+ return "an application modal dialog";
+ case DOCUMENT_MODAL:
+ return "a document modal dialog";
+ case TOOLKIT_MODAL:
+ return "a toolkit modal dialog";
+ }
+ return "a modeless dialog";
+ }
+
+ public void closeAll() {
+
+ if (frame != null) { frame.dispose(); }
+ if (dialogList != null) {
+ Iterator<CustomDialog> it = dialogList.iterator();
+ while (it.hasNext()) { it.next().dispose(); }
+ }
+ }
+
+ class CustomFrame extends TestFrame {
+
+ @Override
+ public void doOpenAction() {
+ if ((dialogList != null) && (dialogList.size() > dialogCount)) {
+ dialogCount++;
+ CustomDialog d = dialogList.get(dialogCount);
+ if (d != null) { d.setVisible(true); }
+ }
+ }
+ }
+
+ class CustomDialog extends TestDialog {
+
+ public CustomDialog(Frame frame) { super(frame); }
+
+ @Override
+ public void doCloseAction() { this.dispose(); }
+
+ @Override
+ public void doOpenAction() {
+ if ((dialogList != null) && (dialogList.size() > dialogCount)) {
+ dialogCount++;
+ if (dialogList.get(dialogCount) != null) {
+ dialogList.get(dialogCount).setVisible(true);
+ }
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ (new MultipleDialogs2Test()).doTest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Modal/MultipleDialogs/MultipleDialogs3Test.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2007, 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 8054358
+ * @summary Check correctness of modal blocking behavior for a chain of Dialogs
+ * having different modality types with a Frame as a document root.
+ *
+ * @library ../helpers ../../../../lib/testlibrary/
+ * @build ExtendedRobot
+ * @build Flag
+ * @build TestDialog
+ * @build TestFrame
+ * @run main/timeout=500 MultipleDialogs3Test
+ */
+
+
+import java.awt.*;
+import static jdk.testlibrary.Asserts.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Collections;
+import java.util.Iterator;
+
+
+public class MultipleDialogs3Test {
+
+ private volatile CustomFrame frame;
+ private List<CustomDialog> dialogList;
+ private static int delay = 500;
+
+ private int dialogCount = -1;
+
+ public void createGUI() {
+
+ final int n = 8;
+ dialogList = new ArrayList<>();
+
+ frame = new CustomFrame();
+ frame.setLocation(50, 50);
+ frame.setVisible(true);
+
+ int x = 250;
+ int y = 50;
+ for (int i = 0; i < n; ++i) {
+
+ CustomDialog dlg;
+ if (i == 0) {
+ dlg = new CustomDialog(frame);
+ } else {
+ dlg = new CustomDialog(dialogList.get(i - 1));
+ }
+ dlg.setLocation(x, y);
+ x += 200;
+ if (x > 600) {
+ x = 50;
+ y += 200;
+ }
+
+ Dialog.ModalityType type;
+
+ if (i % 4 == 0) {
+ type = Dialog.ModalityType.MODELESS;
+ } else if (i % 4 == 1) {
+ type = Dialog.ModalityType.DOCUMENT_MODAL;
+ } else if (i % 4 == 2) {
+ type = Dialog.ModalityType.APPLICATION_MODAL;
+ } else {
+ type = Dialog.ModalityType.TOOLKIT_MODAL;
+ }
+
+ dlg.setModalityType(type);
+ dialogList.add(dlg);
+ }
+ }
+
+ public void doTest() throws Exception {
+
+ try {
+ EventQueue.invokeAndWait(this::createGUI);
+
+ ExtendedRobot robot = new ExtendedRobot();
+ robot.waitForIdle(delay);
+
+ frame.clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ List<CustomDialog> dialogs = Collections.synchronizedList(dialogList);
+ final int n = dialogs.size();
+
+ synchronized(dialogs) {
+ for (int i = 0; i < n; ++i) {
+ dialogs.get(i).activated.waitForFlagTriggered();
+ assertTrue(dialogs.get(i).activated.flag(), i + ": Dialog did not " +
+ "trigger windowActivated event when it became visible.");
+
+ dialogs.get(i).closeGained.waitForFlagTriggered();
+ assertTrue(dialogs.get(i).closeGained.flag(), i + ": Close button " +
+ "did not gain focus when Dialog became visible.");
+
+ assertTrue(dialogs.get(i).closeButton.hasFocus(), i +
+ ": Close button gained focus but then lost it.");
+
+ dialogs.get(i).checkUnblockedDialog(robot,
+ i + ": The dialog shouldn't be blocked.");
+
+ if (i == 0) {
+ assertTrue(dialogs.get(0).getModalityType() ==
+ Dialog.ModalityType.MODELESS, "0: invalid modality type.");
+
+ frame.checkUnblockedFrame(robot, i + ": A modeless dialog was " +
+ "shown, but the parent frame became blocked.");
+
+ } else {
+ if (i % 4 == 0) { // modeless dialog
+ assertTrue(dialogs.get(i).getModalityType() ==
+ Dialog.ModalityType.MODELESS, i +
+ ": incorrect dialog modality type.");
+
+ dialogs.get(i - 1).checkUnblockedDialog(robot, i + ": A modeless " +
+ "dialog was shown, but the parent dialog became blocked.");
+
+ if (i > 0) {
+ for (int j = 0; j < i - 1; ++j) {
+
+ dialogs.get(j).checkBlockedDialog(robot, i + ", " + j +
+ ": Showing a modeless dialog as a child of a " +
+ "modal dialog unblocked some dialog in its hierarchy.");
+ }
+ }
+ } else {
+
+ for (int j = 0; j < i; ++j) {
+
+ dialogs.get(j).checkBlockedDialog(robot, i + ", " + j +
+ ": A modal dialog was shown, but some dialog " +
+ "in its hierarchy became unblocked.");
+ }
+ }
+
+ frame.checkBlockedFrame(robot, i + ": A modal was dialog shown, " +
+ "but the document root frame became unblocked.");
+ }
+
+ if (i != n - 1) {
+ dialogs.get(i).clickOpenButton(robot);
+ robot.waitForIdle(delay);
+ }
+ }
+
+ for (int i = n - 1; i >= 0; --i) {
+
+ resetAll();
+ dialogs.get(i).clickCloseButton(robot);
+ robot.waitForIdle(delay);
+
+ if (i > 0) {
+
+ dialogs.get(i - 1).activated.waitForFlagTriggered();
+ assertTrue(dialogs.get(i - 1).activated.flag(), i + ": Dialog " +
+ "was not activated when a child dialog was closed.");
+
+ if (i == 1) {
+
+ frame.checkUnblockedFrame(robot, "1: Frame having " +
+ "a child modeless dialog was blocked.");
+
+ dialogs.get(0).checkUnblockedDialog(robot,
+ "0: A modeless dialog at the bottom " +
+ "of the hierarchy was blocked.");
+
+ } else if ((i - 1) % 4 == 0) { // dialog[i - 1] is modeless
+
+ for (int j = 0; j < i - 2; ++j) {
+
+ dialogs.get(j).checkBlockedDialog(robot, i + ", " + j +
+ ": A dialog in the hierarchy was not blocked. " +
+ "A dialog blocking a modeless dialog was closed.");
+ }
+
+ dialogs.get(i - 2).checkUnblockedDialog(robot, i + ": A modal " +
+ "dialog having a child modeless dialog was blocked.");
+
+ dialogs.get(i - 1).checkUnblockedDialog(robot, i + ": A modeless " +
+ "dialog at the bottom of the hierarchy was blocked.");
+
+ frame.checkBlockedFrame(robot, i +
+ ": Frame having a child modal dialog was not blocked.");
+
+ } else {
+ for (int j = 0; j <= i - 2; ++j) {
+ dialogs.get(j).checkBlockedDialog(robot, i + ", " + j +
+ ": A dialog in the hierarchy was not blocked. " +
+ "A child dialog was closed.");
+ }
+
+ dialogs.get(i - 1).checkUnblockedDialog(robot, (i - 1) +
+ ": A dialog was not unblocked when the modal dialog was closed.");
+
+ frame.checkBlockedFrame(robot, i + ": Frame having " +
+ "a child modal dialog was not blocked. " +
+ "Another child dialog was closed.");
+ }
+ } else {
+ frame.activated.waitForFlagTriggered();
+ assertTrue(frame.activated.flag(), i + ": Frame was not " +
+ "activated when a child dialog was closed.");
+ }
+ }
+ } // synchronized
+
+ } finally {
+ EventQueue.invokeAndWait(this::closeAll);
+ }
+ }
+
+ private void resetAll() {
+ frame.resetStatus();
+ Iterator<CustomDialog> it = dialogList.iterator();
+ while (it.hasNext()) { it.next().resetStatus(); }
+ }
+
+ public void closeAll() {
+ if (frame != null) { frame.dispose(); }
+ if (dialogList != null) {
+ Iterator<CustomDialog> it = dialogList.iterator();
+ while (it.hasNext()) { it.next().dispose(); }
+ }
+ }
+
+ class CustomFrame extends TestFrame {
+
+ @Override
+ public void doOpenAction() {
+ if ((dialogList != null) && (dialogList.size() > dialogCount)) {
+ dialogCount++;
+ CustomDialog d = dialogList.get(dialogCount);
+ if (d != null) { d.setVisible(true); }
+ }
+ }
+ }
+
+ class CustomDialog extends TestDialog {
+
+ public CustomDialog(Frame frame) { super(frame); }
+ public CustomDialog(Dialog dialog) { super(dialog); }
+
+ @Override
+ public void doCloseAction() { this.dispose(); }
+
+ @Override
+ public void doOpenAction() {
+ if ((dialogList != null) && (dialogList.size() > dialogCount)) {
+ dialogCount++;
+ CustomDialog d = dialogList.get(dialogCount);
+ if (d != null) { d.setVisible(true); }
+ }
+ }
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ (new MultipleDialogs3Test()).doTest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Modal/MultipleDialogs/MultipleDialogs4Test.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2007, 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 8054358 8055003
+ * @summary Check whether application and document modality levels for Dialog
+ * work properly. Also check whether the blocking dialogs are
+ * opening on top of the windows they block.
+ *
+ * @library ../helpers ../../../../lib/testlibrary/
+ * @build ExtendedRobot
+ * @build Flag
+ * @build TestDialog
+ * @build TestFrame
+ * @run main MultipleDialogs4Test
+ */
+
+
+import java.awt.*;
+import static jdk.testlibrary.Asserts.*;
+
+
+public class MultipleDialogs4Test {
+
+ private volatile TopLevelFrame frame;
+ private volatile CustomFrame secondFrame;
+ private volatile TestFrame thirdFrame;
+ private volatile TestDialog dialog, secondDialog, docChildDialog, appChildDialog;
+
+ private static final int delay = 500;
+
+
+ private void createGUI() {
+
+ frame = new TopLevelFrame();
+ frame.setLocation(50, 50);
+ frame.setVisible(true);
+
+ dialog = new TestDialog((Dialog) null);
+ dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
+ dialog.setLocation(150, 50);
+
+ appChildDialog = new TestDialog(dialog);
+ appChildDialog.setLocation(150, 90);
+
+ secondFrame = new CustomFrame();
+ secondFrame.setLocation(50, 250);
+
+ secondDialog = new TestDialog(secondFrame);
+ secondDialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
+ secondDialog.setLocation(150, 250);
+
+ docChildDialog = new TestDialog(secondFrame);
+ docChildDialog.setBackground(Color.black);
+ docChildDialog.setLocation(250, 250);
+
+ thirdFrame = new TestFrame();
+ thirdFrame.setLocation(250, 50);
+ }
+
+ public void doTest() throws Exception {
+
+ try {
+ EventQueue.invokeAndWait(this::createGUI);
+
+ final int nAttempts = 3;
+ ExtendedRobot robot = new ExtendedRobot();
+ robot.waitForIdle(delay);
+
+ frame.clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ secondFrame.clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ secondFrame.checkBlockedFrame(robot,
+ "A document modal dialog should block this Frame.");
+
+ secondDialog.checkUnblockedDialog(robot, "This is a document " +
+ "modal dialog. No window blocks it.");
+
+ frame.checkUnblockedFrame(robot,
+ "There are no dialogs blocking this Frame.");
+
+ frame.clickCloseButton(robot);
+ robot.waitForIdle(delay);
+
+ frame.clickDummyButton(robot, nAttempts, false,
+ "The frame still on top even after showing a modal dialog.");
+ robot.waitForIdle(delay);
+
+ EventQueue.invokeAndWait(() -> { thirdFrame.setVisible(true); });
+ robot.waitForIdle(delay);
+
+ dialog.clickDummyButton(robot);
+ robot.waitForIdle(delay);
+
+ secondDialog.clickDummyButton(
+ robot, nAttempts, false, "The document modal dialog " +
+ "was not blocked by an application modal dialog.");
+ robot.waitForIdle(delay);
+
+ EventQueue.invokeLater(() -> { docChildDialog.setVisible(true); });
+ robot.waitForIdle(delay);
+
+ Color c = robot.getPixelColor(
+ (int) secondDialog.getLocationOnScreen().x + secondDialog.getSize().width - 25,
+ (int) secondDialog.getLocationOnScreen().y + secondDialog.getSize().height - 25);
+ assertFalse(c.equals(Color.black), "A dialog which should be blocked " +
+ "by document modal dialog overlapping it.");
+
+ EventQueue.invokeLater(() -> { appChildDialog.setVisible(true); });
+ robot.waitForIdle(delay);
+
+ appChildDialog.activated.waitForFlagTriggered();
+ assertTrue(appChildDialog.activated.flag(), "The child dialog of the " +
+ "application modal dialog still not visible.");
+ robot.waitForIdle(delay);
+
+ dialog.clickDummyButton(robot, nAttempts, false, "The child dialog of " +
+ "the application modal dialog did not overlap it.");
+ robot.waitForIdle(delay);
+
+ } finally {
+ EventQueue.invokeAndWait(this::closeAll);
+ }
+ }
+
+ public void closeAll() {
+
+ if (frame != null) { frame.dispose(); }
+ if (dialog != null) { dialog.dispose(); }
+ if (appChildDialog != null) { appChildDialog.dispose(); }
+ if (secondFrame != null) { secondFrame.dispose(); }
+ if (secondDialog != null) { secondDialog.dispose(); }
+ if (docChildDialog != null) { docChildDialog.dispose(); }
+ if (thirdFrame != null) { thirdFrame.dispose(); }
+ }
+
+ class TopLevelFrame extends TestFrame {
+
+ @Override
+ public void doOpenAction() { secondFrame.setVisible(true); }
+ @Override
+ public void doCloseAction() { dialog.setVisible(true); }
+ }
+
+ class CustomFrame extends TestFrame {
+
+ @Override
+ public void doOpenAction() { secondDialog.setVisible(true); }
+ }
+
+ public static void main(String[] args) throws Exception {
+ (new MultipleDialogs4Test()).doTest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Modal/MultipleDialogs/MultipleDialogs5Test.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2007, 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 8054358
+ * @summary This is a simple check if a chain of dialogs having different
+ * modality types block each other properly.
+ *
+ * @library ../helpers ../../../../lib/testlibrary/
+ * @build ExtendedRobot
+ * @build Flag
+ * @build TestDialog
+ * @build TestFrame
+ * @build TestWindow
+ * @run main MultipleDialogs5Test
+ */
+
+
+import java.awt.*;
+import static jdk.testlibrary.Asserts.*;
+
+
+public class MultipleDialogs5Test {
+
+ private volatile ParentFrame parent;
+ private volatile ModalDialog appDialog, docDialog, tkDialog;
+ private volatile CustomWindow window;
+
+ private static int delay = 500;
+
+ private void createGUI() {
+
+ parent = new ParentFrame();
+ parent.setLocation(50, 50);
+ parent.setVisible(true);
+
+ appDialog = new ModalDialog(parent);
+ appDialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
+ appDialog.setLocation(250, 50);
+
+ docDialog = new ModalDialog(appDialog);
+ docDialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
+ docDialog.setLocation(450, 50);
+
+ window = new CustomWindow(docDialog);
+ window.setLocation(50, 250);
+
+ tkDialog = new ModalDialog(docDialog);
+ tkDialog.setLocation(250, 250);
+ tkDialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
+
+ appDialog.setWindowToOpen(docDialog);
+ docDialog.setWindowToOpen(window);
+ }
+
+ public void doTest() throws Exception {
+
+ try {
+ EventQueue.invokeAndWait(this::createGUI);
+
+ ExtendedRobot robot = new ExtendedRobot();
+ robot.waitForIdle(delay);
+
+ parent.clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ parent.checkBlockedFrame(robot,
+ "This Frame is blocked by an application modal dialog.");
+
+ appDialog.clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ appDialog.checkBlockedDialog(robot,
+ "This Dialog is blocked by a document modal dialog.");
+
+ docDialog.clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ docDialog.checkUnblockedDialog(robot,
+ "This Dialog is not blocked by any modal dialog.");
+
+ window.clickOpenButton(robot);
+ robot.waitForIdle(delay);
+
+ window.checkBlockedWindow(robot,
+ "This Window is blocked by a toolkit modal dialog.");
+
+ tkDialog.clickCloseButton(robot);
+ robot.waitForIdle(delay);
+ assertFalse(tkDialog.isVisible(),
+ "The toolkit modal dialog was not disposed.");
+
+ window.clickCloseButton(robot);
+ robot.waitForIdle(delay);
+ assertFalse(window.isVisible(),
+ "The window was not disposed.");
+
+ docDialog.clickCloseButton(robot);
+ robot.waitForIdle(delay);
+ assertFalse(docDialog.isVisible(),
+ "The document modal dialog was not disposed.");
+
+ appDialog.clickCloseButton(robot);
+ robot.waitForIdle(delay);
+ assertFalse(appDialog.isVisible(),
+ "The application modal dialog was not disposed.");
+ } finally {
+ EventQueue.invokeAndWait(this::closeAll); // if something wasn't closed
+ }
+ }
+
+ private void closeAll() {
+
+ if (appDialog != null) { appDialog.dispose(); }
+ if (tkDialog != null) { tkDialog.dispose(); }
+ if (docDialog != null) { docDialog.dispose(); }
+ if (parent != null) { parent.dispose(); }
+ if (window != null) { window.dispose(); }
+ }
+
+ private class ParentFrame extends TestFrame {
+
+ @Override
+ public void doOpenAction() {
+ if (appDialog != null) { appDialog.setVisible(true); }
+ }
+ }
+
+ private class CustomWindow extends TestWindow {
+
+ public CustomWindow(Dialog d) { super(d); }
+
+ @Override
+ public void doOpenAction() {
+ if (tkDialog != null) { tkDialog.setVisible(true); }
+ }
+
+ @Override
+ public void doCloseAction() { this.dispose(); }
+ }
+
+ private class ModalDialog extends TestDialog {
+
+ private Window w;
+
+ public ModalDialog(Frame f) { super(f); }
+ public ModalDialog(Dialog d) { super(d); }
+
+ public void setWindowToOpen(Window w) { this.w = w; }
+
+ @Override
+ public void doCloseAction() { this.dispose(); }
+
+ @Override
+ public void doOpenAction() {
+ if (w != null) { w.setVisible(true); }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ (new MultipleDialogs5Test()).doTest();
+ }
+}
--- a/jdk/test/java/awt/regtesthelpers/Util.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/java/awt/regtesthelpers/Util.java Thu Jan 29 03:54:45 2015 +0000
@@ -76,12 +76,17 @@
public final class Util {
private Util() {} // this is a helper class with static methods :)
+ private volatile static Robot robot;
+
/*
* @throws RuntimeException when creation failed
*/
public static Robot createRobot() {
try {
- return new Robot();
+ if (robot == null) {
+ robot = new Robot();
+ }
+ return robot;
} catch (AWTException e) {
throw new RuntimeException("Error: unable to create robot", e);
}
@@ -200,7 +205,10 @@
return false;
}
- public static void waitForIdle(final Robot robot) {
+ public static void waitForIdle(Robot robot) {
+ if (robot == null) {
+ robot = createRobot();
+ }
robot.waitForIdle();
}
--- a/jdk/test/java/lang/CharSequence/DefaultTest.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.PrimitiveIterator;
-import java.util.Spliterator;
-import java.util.stream.Collectors;
-
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.*;
-
-/*
- * @test
- * @summary Unit test for CharSequence default methods
- * @bug 8012665 8025002
- * @run testng DefaultTest
- */
-
-@Test(groups = "lib")
-public class DefaultTest {
-
- @Test(expectedExceptions = NoSuchElementException.class)
- public void testEmptyChars() {
- PrimitiveIterator.OfInt s = "".chars().iterator();
- assertFalse(s.hasNext());
- int ch = s.nextInt();
- }
-
- public void testSimpleChars() {
- List<Integer> list = "abc".chars().boxed().collect(Collectors.toList());
- assertEquals(list, Arrays.asList((int) 'a', (int) 'b', (int) 'c'));
- }
-
- public void testCodePointsCharacteristics() {
- Spliterator.OfInt s = "".codePoints().spliterator();
- assertFalse(s.hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED));
- assertTrue(s.hasCharacteristics(Spliterator.ORDERED));
- }
-
- @Test(expectedExceptions = NoSuchElementException.class)
- public void testEmptyCodePoints() {
- PrimitiveIterator.OfInt s = "".codePoints().iterator();
- assertFalse(s.hasNext());
- int cp = s.nextInt();
- }
-
- public void testSimpleCodePoints() {
- List<Integer> list = "abc".codePoints().boxed().collect(Collectors.toList());
- assertEquals(list, Arrays.asList((int)'a', (int)'b', (int)'c'));
- }
-
- public void testUndefCodePoints() {
- List<Integer> list = "X\ufffeY".codePoints().boxed().collect(Collectors.toList());
- assertEquals(list, Arrays.asList((int)'X', 0xFFFE, (int)'Y'));
- }
-
- public void testSurrogatePairing() {
- // U+1D11E = MUSICAL SYMBOL G CLEF
- // equivalent to surrogate pair U+D834 U+DD1E
- List<Integer> list;
- final int GCLEF = 0x1d11e;
-
- list = "\ud834\udd1e".codePoints().boxed().collect(Collectors.toList());
- assertEquals(list, Arrays.asList(GCLEF));
- list = "A\ud834\udd1e".codePoints().boxed().collect(Collectors.toList());
- assertEquals(list, Arrays.asList((int)'A', GCLEF));
- list = "\ud834\udd1eB".codePoints().boxed().collect(Collectors.toList());
- assertEquals(list, Arrays.asList(GCLEF, (int)'B'));
- list = "X\ud834\udd1eY".codePoints().boxed().collect(Collectors.toList());
- assertEquals(list, Arrays.asList((int)'X', GCLEF, (int)'Y'));
- }
-
- public void testUndefUnpaired() {
- List<Integer> list = "W\udd1eX\ud834Y\ufffeZ".codePoints().boxed().collect(Collectors.toList());
- assertEquals(list, Arrays.asList(
- (int)'W', 0xdd1e, (int)'X', 0xd834, (int)'Y', 0xfffe, (int)'Z'));
- }
-}
--- a/jdk/test/java/lang/Class/GenericStringTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/java/lang/Class/GenericStringTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,29 @@
@ExpectedGenericString("public class GenericStringTest")
public class GenericStringTest {
- public static void main(String... args){
+ public Map<String, Integer>[] mixed = null;
+ public Map<String, Integer>[][] mixed2 = null;
+
+ public static void main(String... args) throws ReflectiveOperationException {
int failures = 0;
+ String[][] nested = {{""}};
+ int[][] intArray = {{1}};
+
failures += checkToGenericString(int.class, "int");
+ failures += checkToGenericString(void.class, "void");
+ failures += checkToGenericString(args.getClass(), "java.lang.String[]");
+ failures += checkToGenericString(nested.getClass(), "java.lang.String[][]");
+ failures += checkToGenericString(intArray.getClass(), "int[][]");
+ failures += checkToGenericString(java.util.Map.class, "public abstract interface java.util.Map<K,V>");
+
+ Field f = GenericStringTest.class.getDeclaredField("mixed");
+ // The expected value includes "<K,V>" rather than
+ // "<...String,...Integer>" since the Class object rather than
+ // Type objects is being queried.
+ failures += checkToGenericString(f.getType(), "java.util.Map<K,V>[]");
+ f = GenericStringTest.class.getDeclaredField("mixed2");
+ failures += checkToGenericString(f.getType(), "java.util.Map<K,V>[][]");
Class<?>[] types = {
GenericStringTest.class,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/LibraryPathProperty.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8067951
+ * @summary Unit test for internal ClassLoader#initializePath().
+ * Quoted entries should get unquoted on Windows.
+ * Empty entries should be replaced with dot.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.Platform
+ * @run main LibraryPathProperty
+ */
+
+import java.lang.reflect.Method;
+import java.io.File;
+import java.util.Arrays;
+import jdk.testlibrary.Platform;
+
+public class LibraryPathProperty {
+
+ static final String propName = "test.property.name";
+ static final String SP = File.pathSeparator;
+ static Method method;
+
+ public static void main(String[] args) throws Throwable {
+ method = ClassLoader.class
+ .getDeclaredMethod("initializePath",
+ String.class);
+ method.setAccessible(true);
+
+ test("", ".");
+ test(SP, ".", ".");
+ test("a" + SP, "a", ".");
+ test(SP + "b", ".", "b");
+ test("a" + SP + SP + "b", "a", ".", "b");
+
+ if (Platform.isWindows()) {
+ // on Windows parts of paths may be quoted
+ test("\"\"", ".");
+ test("\"\"" + SP, ".", ".");
+ test(SP + "\"\"", ".", ".");
+ test("a" + SP + "\"b\"" + SP, "a", "b", ".");
+ test(SP + "\"a\"" + SP + SP + "b", ".", "a", ".", "b");
+ test("\"a\"" + SP + "\"b\"", "a", "b");
+ test("\"/a/\"b" + SP + "c", "/a/b", "c");
+ test("\"/a;b\"" + SP + "c", "/a;b", "c");
+ test("\"/a:b\"" + SP + "c", "/a:b", "c");
+ test("\"/a" + SP + "b\"" + SP + "c", "/a" + SP + "b", "c");
+ test("/\"a\"\";\"\"b\"" + SP + "\"c\"", "/a;b", "c");
+ test("/\"a:\"b" + SP + "c", "/a:b", "c");
+ }
+ }
+
+ static void test(String s, String... expected) throws Throwable {
+ System.setProperty(propName, s);
+ String[] res = (String[])method.invoke(null, propName);
+ if (!Arrays.asList(res).equals(Arrays.asList(expected))) {
+ throw new RuntimeException("Parsing [" + s + "] " +
+ " result " + Arrays.asList(res) +
+ " doesn't match " + Arrays.asList(expected));
+ }
+ }
+}
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java Thu Jan 29 03:54:45 2015 +0000
@@ -2042,7 +2042,7 @@
final Object deferred;
Class<?> c = s.getClass();
if (c.getName().equals(
- "java.lang.UNIXProcess$DeferredCloseInputStream"))
+ "java.lang.ProcessImpl$DeferredCloseInputStream"))
{
deferred = s;
} else {
--- a/jdk/test/java/lang/ref/OOMEInReferenceHandler.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/java/lang/ref/OOMEInReferenceHandler.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,7 +25,7 @@
* @test
* @bug 7038914 8016341
* @summary Verify that the reference handler does not die after an OOME allocating the InterruptedException object
- * @run main/othervm -Xmx24M -XX:-UseTLAB OOMEInReferenceHandler
+ * @run main/othervm -XX:-UseGCOverheadLimit -Xmx24M -XX:-UseTLAB OOMEInReferenceHandler
* @author peter.levart@gmail.com
*/
--- a/jdk/test/java/net/Socket/GetLocalAddress.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/java/net/Socket/GetLocalAddress.java Thu Jan 29 03:54:45 2015 +0000
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4106601 8026245
+ * @bug 4106601 8026245 8071424
* @run main/othervm GetLocalAddress
* @run main/othervm -Djava.net.preferIPv4Stack=true GetLocalAddress
* @run main/othervm -Djava.net.preferIPv6Addresses=true GetLocalAddress
@@ -39,6 +39,8 @@
static int port;
public static void main(String args[]) throws Exception {
+ testBindNull();
+
boolean error = true;
int linger = 65546;
int value = 0;
@@ -66,4 +68,18 @@
}
}
+ static void testBindNull() throws Exception {
+ try (Socket soc = new Socket()) {
+ soc.bind(null);
+ if (!soc.isBound())
+ throw new RuntimeException(
+ "should be bound after bind(null)");
+ if (soc.getLocalPort() <= 0)
+ throw new RuntimeException(
+ "bind(null) failed, local port: " + soc.getLocalPort());
+ if (soc.getLocalAddress() == null)
+ throw new RuntimeException(
+ "bind(null) failed, local address is null");
+ }
+ }
}
--- a/jdk/test/java/net/URI/Test.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/java/net/URI/Test.java Thu Jan 29 03:54:45 2015 +0000
@@ -24,7 +24,7 @@
/* @test
* @summary Unit test for java.net.URI
* @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 7041800
- * 7171415
+ * 7171415 6933879
* @author Mark Reinhold
*/
@@ -1600,6 +1600,7 @@
static void bugs() {
b6339649();
+ b6933879();
b8037396();
}
@@ -1614,6 +1615,18 @@
}
}
+ // 6933879 - check that "." and "_" characters are allowed in IPv6 scope_id.
+ private static void b6933879() {
+ final String HOST = "fe80::c00:16fe:cebe:3214%eth1.12_55";
+ URI uri;
+ try {
+ uri = new URI("http", null, HOST, 10, "/", null, null);
+ } catch (URISyntaxException ex) {
+ throw new AssertionError("Should not happen", ex);
+ }
+ eq("[" + HOST + "]", uri.getHost());
+ }
+
private static void b8037396() {
// primary checks:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Hashtable/DeserializedLength.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,110 @@
+/*
+ * 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 java.io.*;
+import java.lang.reflect.Field;
+import java.util.Hashtable;
+
+/**
+ * @test
+ * @bug 8068427
+ * @summary Hashtable deserialization reconstitutes table with wrong capacity
+ */
+public class DeserializedLength {
+
+ static boolean testDeserializedLength(int elements, float loadFactor) throws Exception {
+
+ // construct Hashtable with minimal initial capacity and given loadFactor
+ Hashtable<Integer, Integer> ht1 = new Hashtable<>(1, loadFactor);
+
+ // add given number of unique elements
+ for (int i = 0; i < elements; i++) {
+ ht1.put(i, i);
+ }
+
+ // serialize and deserialize into a deep clone
+ Hashtable<Integer, Integer> ht2 = serialClone(ht1);
+
+ // compare lengths of internal tables
+ Object[] table1 = (Object[]) hashtableTableField.get(ht1);
+ Object[] table2 = (Object[]) hashtableTableField.get(ht2);
+ assert table1 != null;
+ assert table2 != null;
+
+ int minLength = (int) (ht1.size() / loadFactor) + 1;
+ int maxLength = minLength * 2;
+
+ boolean ok = (table2.length >= minLength && table2.length <= maxLength);
+
+ System.out.printf(
+ "%7d %5.2f %7d %7d %7d...%7d %s\n",
+ ht1.size(), loadFactor,
+ table1.length, table2.length,
+ minLength, maxLength,
+ (ok ? "OK" : "NOT-OK")
+ );
+
+ return ok;
+ }
+
+ static <T> T serialClone(T o) throws IOException, ClassNotFoundException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {
+ oos.writeObject(o);
+ }
+ @SuppressWarnings("unchecked")
+ T clone = (T) new ObjectInputStream(
+ new ByteArrayInputStream(bos.toByteArray())).readObject();
+ return clone;
+ }
+
+ private static final Field hashtableTableField;
+
+ static {
+ try {
+ hashtableTableField = Hashtable.class.getDeclaredField("table");
+ hashtableTableField.setAccessible(true);
+ } catch (NoSuchFieldException e) {
+ throw new Error(e);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ boolean ok = true;
+
+ System.out.printf("Results:\n" +
+ " ser. deser.\n" +
+ " size load lentgh length valid range ok?\n" +
+ "------- ----- ------- ------- ----------------- ------\n"
+ );
+
+ for (int elements : new int[]{10, 50, 500, 5000}) {
+ for (float loadFactor : new float[]{0.15f, 0.5f, 0.75f, 1.0f, 2.5f}) {
+ ok &= testDeserializedLength(elements, loadFactor);
+ }
+ }
+ if (!ok) {
+ throw new AssertionError("Test failed.");
+ }
+ }
+}
--- a/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/java/util/Spliterator/SpliteratorCharacteristics.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8020156 8020009 8022326 8012913 8024405 8024408
+ * @bug 8020156 8020009 8022326 8012913 8024405 8024408 8071477
* @run testng SpliteratorCharacteristics
*/
@@ -59,6 +59,57 @@
@Test
public class SpliteratorCharacteristics {
+ public void testSpliteratorFromCharSequence() {
+ class CharSequenceImpl implements CharSequence {
+ final String s;
+
+ public CharSequenceImpl(String s) {
+ this.s = s;
+ }
+
+ @Override
+ public int length() {
+ return s.length();
+ }
+
+ @Override
+ public char charAt(int index) {
+ return s.charAt(index);
+ }
+
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ return s.subSequence(start, end);
+ }
+
+ @Override
+ public String toString() {
+ return s;
+ }
+ }
+
+ CharSequence cs = "A";
+ Spliterator.OfInt s = cs.chars().spliterator();
+ assertCharacteristics(s, Spliterator.IMMUTABLE | Spliterator.ORDERED |
+ Spliterator.SIZED | Spliterator.SUBSIZED);
+ assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
+ s = cs.codePoints().spliterator();
+ assertCharacteristics(s, Spliterator.IMMUTABLE | Spliterator.ORDERED);
+ assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
+
+ for (CharSequence c : Arrays.asList(new CharSequenceImpl("A"),
+ new StringBuilder("A"),
+ new StringBuffer("A"))) {
+ s = cs.chars().spliterator();
+ assertCharacteristics(s, Spliterator.ORDERED |
+ Spliterator.SIZED | Spliterator.SUBSIZED);
+ assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
+ s = cs.codePoints().spliterator();
+ assertCharacteristics(s, Spliterator.ORDERED);
+ assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
+ }
+ }
+
public void testSpliteratorFromCollection() {
List<Integer> l = Arrays.asList(1, 2, 3, 4);
--- a/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
* @test
* @summary Spliterator traversing and splitting tests
* @run testng SpliteratorTraversingAndSplittingTest
- * @bug 8020016
+ * @bug 8020016 8071477
*/
import org.testng.annotations.DataProvider;
@@ -85,7 +85,38 @@
@Test
public class SpliteratorTraversingAndSplittingTest {
- private static List<Integer> SIZES = Arrays.asList(0, 1, 10, 100, 1000);
+ private static final List<Integer> SIZES = Arrays.asList(0, 1, 10, 100, 1000);
+
+ private static final String LOW = new String(new char[] {Character.MIN_LOW_SURROGATE});
+ private static final String HIGH = new String(new char[] {Character.MIN_HIGH_SURROGATE});
+ private static final String HIGH_LOW = HIGH + LOW;
+ private static final String CHAR_HIGH_LOW = "A" + HIGH_LOW;
+ private static final String HIGH_LOW_CHAR = HIGH_LOW + "A";
+ private static final String CHAR_HIGH_LOW_CHAR = "A" + HIGH_LOW + "A";
+
+ private static final List<String> STRINGS = generateTestStrings();
+
+ private static List<String> generateTestStrings() {
+ List<String> strings = new ArrayList<>();
+ for (int n : Arrays.asList(1, 2, 3, 16, 17)) {
+ strings.add(generate("A", n));
+ strings.add(generate(LOW, n));
+ strings.add(generate(HIGH, n));
+ strings.add(generate(HIGH_LOW, n));
+ strings.add(generate(CHAR_HIGH_LOW, n));
+ strings.add(generate(HIGH_LOW_CHAR, n));
+ strings.add(generate(CHAR_HIGH_LOW_CHAR, n));
+ }
+ return strings;
+ }
+
+ private static String generate(String s, int n) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < n; i++) {
+ sb.append(s);
+ }
+ return sb.toString();
+ }
private static class SpliteratorDataBuilder<T> {
List<Object[]> data;
@@ -564,6 +595,60 @@
}
}
+ private static class SpliteratorOfIntCharDataBuilder {
+ List<Object[]> data;
+
+ String s;
+
+ List<Integer> expChars;
+
+ List<Integer> expCodePoints;
+
+ SpliteratorOfIntCharDataBuilder(List<Object[]> data, String s) {
+ this.data = data;
+ this.s = s;
+ this.expChars = transform(s, false);
+ this.expCodePoints = transform(s, true);
+ }
+
+ static List<Integer> transform(String s, boolean toCodePoints) {
+ List<Integer> l = new ArrayList<>();
+
+ if (!toCodePoints) {
+ for (int i = 0; i < s.length(); i++) {
+ l.add((int) s.charAt(i));
+ }
+ }
+ else {
+ for (int i = 0; i < s.length();) {
+ char c1 = s.charAt(i++);
+ int cp = c1;
+ if (Character.isHighSurrogate(c1) && i < s.length()) {
+ char c2 = s.charAt(i);
+ if (Character.isLowSurrogate(c2)) {
+ i++;
+ cp = Character.toCodePoint(c1, c2);
+ }
+ }
+ l.add(cp);
+ }
+ }
+ return l;
+ }
+
+ void add(String description, Function<String, CharSequence> f) {
+ description = description.replace("%s", s);
+ {
+ Supplier<Spliterator.OfInt> supplier = () -> f.apply(s).chars().spliterator();
+ data.add(new Object[]{description + ".chars().spliterator()", expChars, supplier});
+ }
+ {
+ Supplier<Spliterator.OfInt> supplier = () -> f.apply(s).codePoints().spliterator();
+ data.add(new Object[]{description + ".codePoints().spliterator()", expCodePoints, supplier});
+ }
+ }
+ }
+
static Object[][] spliteratorOfIntDataProvider;
@DataProvider(name = "Spliterator.OfInt")
@@ -615,6 +700,43 @@
() -> new IntSpliteratorFromArray(exp));
}
+ // Class for testing default methods
+ class CharSequenceImpl implements CharSequence {
+ final String s;
+
+ public CharSequenceImpl(String s) {
+ this.s = s;
+ }
+
+ @Override
+ public int length() {
+ return s.length();
+ }
+
+ @Override
+ public char charAt(int index) {
+ return s.charAt(index);
+ }
+
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ return s.subSequence(start, end);
+ }
+
+ @Override
+ public String toString() {
+ return s;
+ }
+ }
+
+ for (String string : STRINGS) {
+ SpliteratorOfIntCharDataBuilder cdb = new SpliteratorOfIntCharDataBuilder(data, string);
+ cdb.add("\"%s\"", s -> s);
+ cdb.add("new CharSequenceImpl(\"%s\")", CharSequenceImpl::new);
+ cdb.add("new StringBuilder(\"%s\")", StringBuilder::new);
+ cdb.add("new StringBuffer(\"%s\")", StringBuffer::new);
+ }
+
return spliteratorOfIntDataProvider = data.toArray(new Object[0][]);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/concurrent/CompletableFuture/ThenComposeExceptionTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+
+
+/**
+ * @test
+ * @bug 8068432
+ * @run testng ThenComposeExceptionTest
+ * @summary Test that CompletableFuture.thenCompose works correctly if the
+ * composing future completes exceptionally
+ */
+@Test
+public class ThenComposeExceptionTest {
+
+ static final BiFunction<CompletableFuture<String>, CompletableFuture<String>, CompletableFuture<String>>
+ THEN_COMPOSE = (f, fe) -> f.thenCompose(s -> fe);
+
+ static final BiFunction<CompletableFuture<String>, CompletableFuture<String>, CompletableFuture<String>>
+ THEN_COMPOSE_ASYNC = (f, fe) -> f.thenComposeAsync(s -> fe);
+
+ static final Consumer<CompletableFuture<String>>
+ COMPLETE_EXCEPTIONALLY = f -> f.completeExceptionally(new RuntimeException());
+
+ static final Consumer<CompletableFuture<String>>
+ NOP = f -> { };
+
+ static Object[][] actionsDataProvider;
+
+ @DataProvider(name = "actions")
+ static Object[][] actionsDataProvider() {
+ if (actionsDataProvider != null) {
+ return actionsDataProvider;
+ }
+
+ List<Object[]> data = new ArrayList<>();
+ data.add(new Object[]{"thenCompose and completeExceptionally", NOP, THEN_COMPOSE, COMPLETE_EXCEPTIONALLY});
+ data.add(new Object[]{"thenComposeAsync and completeExceptionally", NOP, THEN_COMPOSE_ASYNC, COMPLETE_EXCEPTIONALLY});
+ data.add(new Object[]{"completeExceptionally and thenCompose", COMPLETE_EXCEPTIONALLY, THEN_COMPOSE, NOP});
+ data.add(new Object[]{"completeExceptionally and thenComposeAsync", COMPLETE_EXCEPTIONALLY, THEN_COMPOSE_ASYNC, NOP});
+
+ return actionsDataProvider = data.toArray(new Object[0][]);
+ }
+
+ @Test(dataProvider = "actions")
+ public void testThenCompose(
+ String description,
+ Consumer<CompletableFuture<String>> beforeAction,
+ BiFunction<CompletableFuture<String>, CompletableFuture<String>, CompletableFuture<String>> composeFunction,
+ Consumer<CompletableFuture<String>> afterAction) throws Exception {
+ CompletableFuture<String> f = new CompletableFuture<>();
+ CompletableFuture<String> fe = new CompletableFuture<>();
+
+ // Ensure pre-composed stage is completed to trigger
+ // processing the composing future
+ f.complete("");
+
+ beforeAction.accept(fe);
+
+ CompletableFuture<String> f_thenCompose = composeFunction.apply(f, fe);
+ Assert.assertNotSame(f_thenCompose, fe, "Composed CompletableFuture returned directly");
+
+ AtomicReference<Throwable> eOnWhenComplete = new AtomicReference<>();
+ f_thenCompose.whenComplete((r, e) -> eOnWhenComplete.set(e));
+
+ afterAction.accept(fe);
+
+ Throwable eOnJoined = null;
+ try {
+ f_thenCompose.join();
+ }
+ catch (Throwable t) {
+ eOnJoined = t;
+ }
+
+ Assert.assertTrue(eOnWhenComplete.get() instanceof CompletionException,
+ "Incorrect exception reported on whenComplete");
+ Assert.assertTrue(eOnJoined instanceof CompletionException,
+ "Incorrect exception reported when joined");
+ }
+}
--- a/jdk/test/javax/net/ssl/SSLSession/TestEnabledProtocols.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/javax/net/ssl/SSLSession/TestEnabledProtocols.java Thu Jan 29 03:54:45 2015 +0000
@@ -120,6 +120,10 @@
volatile Exception clientException = null;
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
String keyFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + keyStoreFile;
--- a/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorer.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/javax/net/ssl/ServerName/SSLEngineExplorer.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -44,6 +44,7 @@
import java.net.*;
import java.util.*;
import java.nio.channels.*;
+import java.security.Security;
public class SSLEngineExplorer extends SSLEngineService {
@@ -231,6 +232,10 @@
volatile int serverPort = 0;
public static void main(String args[]) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
if (debug)
System.setProperty("javax.net.debug", "all");
--- a/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorer.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/javax/net/ssl/ServerName/SSLSocketExplorer.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -45,6 +45,7 @@
import java.util.*;
import java.net.*;
import javax.net.ssl.*;
+import java.security.Security;
public class SSLSocketExplorer {
@@ -224,6 +225,10 @@
volatile Exception clientException = null;
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
String keyFilename =
System.getProperty("test.src", ".") + "/" + pathToStores +
"/" + keyStoreFile;
--- a/jdk/test/javax/net/ssl/TLS/TLSClientPropertyTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/javax/net/ssl/TLS/TLSClientPropertyTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -29,8 +29,10 @@
/*
* @test
- * @bug 8049432
+ * @bug 8049432 8069038
* @summary New tests for TLS property jdk.tls.client.protocols
+ * @summary javax/net/ssl/TLS/TLSClientPropertyTest.java needs to be
+ * updated for JDK-8061210
* @run main/othervm TLSClientPropertyTest NoProperty
* @run main/othervm TLSClientPropertyTest SSLv3
* @run main/othervm TLSClientPropertyTest TLSv1
@@ -46,7 +48,7 @@
* protocols in the SSLContext.
*/
public class TLSClientPropertyTest {
- private final String[] expecteSupportedProtos = new String[] {
+ private final String[] expectedSupportedProtos = new String[] {
"SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"
};
@@ -67,31 +69,30 @@
}
contextProtocol = null;
expectedDefaultProtos = new String[] {
- "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"
+ "TLSv1", "TLSv1.1", "TLSv1.2"
};
break;
case "SSLv3":
contextProtocol = "SSLv3";
expectedDefaultProtos = new String[] {
- "SSLv3"
};
break;
case "TLSv1":
contextProtocol = "TLSv1";
expectedDefaultProtos = new String[] {
- "SSLv3", "TLSv1"
+ "TLSv1"
};
break;
case "TLSv11":
contextProtocol = "TLSv1.1";
expectedDefaultProtos = new String[] {
- "SSLv3", "TLSv1", "TLSv1.1"
+ "TLSv1", "TLSv1.1"
};
break;
case "TLSv12":
contextProtocol = "TLSv1.2";
expectedDefaultProtos = new String[] {
- "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"
+ "TLSv1", "TLSv1.1", "TLSv1.2"
};
break;
case "WrongProperty":
@@ -182,12 +183,12 @@
expectedProto = "Default";
}
if (!context.getProtocol().equals(expectedProto)) {
- error("Invalid current protocol:" + context.getProtocol()
+ error("Invalid current protocol: " + context.getProtocol()
+ ", Expected:" + expectedProto, null);
}
List<String> actualDefaultProtos = Arrays.asList(context
.getDefaultSSLParameters().getProtocols());
- for (String p: expectedDefaultProtos) {
+ for (String p : expectedDefaultProtos) {
if (!actualDefaultProtos.contains(p)) {
error("Default protocol " + p + "missing", null);
}
@@ -195,7 +196,7 @@
List<String> actualSupportedProtos = Arrays.asList(context
.getSupportedSSLParameters().getProtocols());
- for (String p: expecteSupportedProtos) {
+ for (String p : expectedSupportedProtos) {
if (!actualSupportedProtos.contains(p)) {
error("Expected to support protocol:" + p, null);
}
--- a/jdk/test/javax/net/ssl/TLS/TestJSSE.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/javax/net/ssl/TLS/TestJSSE.java Thu Jan 29 03:54:45 2015 +0000
@@ -78,6 +78,10 @@
private static final String LOCAL_IP = "127.0.0.1";
public static void main(String... args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
String serverProtocol = System.getProperty("SERVER_PROTOCOL");
String clientProtocol = System.getProperty("CLIENT_PROTOCOL");
int port = jdk.testlibrary.Utils.getFreePort();
--- a/jdk/test/javax/net/ssl/sanity/interop/ClientJSSEServerJSSE.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/javax/net/ssl/sanity/interop/ClientJSSEServerJSSE.java Thu Jan 29 03:54:45 2015 +0000
@@ -33,6 +33,10 @@
public class ClientJSSEServerJSSE {
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
// MD5 is used in this test case, don't disable MD5 algorithm.
Security.setProperty(
"jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
--- a/jdk/test/javax/sql/testng/test/rowset/BaseRowSetTests.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/javax/sql/testng/test/rowset/BaseRowSetTests.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -30,13 +30,9 @@
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
import java.sql.Date;
import java.sql.Ref;
-import java.sql.RowId;
-import java.sql.SQLFeatureNotSupportedException;
+import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
@@ -44,407 +40,74 @@
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Calendar;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import javax.sql.RowSet;
import javax.sql.rowset.serial.SerialArray;
import javax.sql.rowset.serial.SerialBlob;
import javax.sql.rowset.serial.SerialClob;
import javax.sql.rowset.serial.SerialRef;
import static org.testng.Assert.*;
-import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
-import util.BaseTest;
import util.StubArray;
import util.StubBaseRowSet;
import util.StubBlob;
import util.StubClob;
-import util.StubNClob;
import util.StubRef;
-import util.StubRowId;
-import util.StubSQLXML;
import util.TestRowSetListener;
-public class BaseRowSetTests extends BaseTest {
+public class BaseRowSetTests extends CommonRowSetTests {
private StubBaseRowSet brs;
- private StubBaseRowSet brs1;
- private final String query = "SELECT * FROM SUPERHEROS";
- private final String url = "jdbc:derby://localhost:1527/myDB";
- private final String dsName = "jdbc/myDB";
- private final String user = "Bruce Wayne";
- private final String password = "The Dark Knight";
- private final Date aDate = Date.valueOf(LocalDate.now());
- private final Time aTime = Time.valueOf(LocalTime.now());
- private final Timestamp ts = Timestamp.valueOf(LocalDateTime.now());
- private final Calendar cal = Calendar.getInstance();
- private final byte[] bytes = new byte[10];
- private RowId aRowid;
- private Ref aRef;
- private Blob aBlob;
- private Clob aClob;
- private Array aArray;
- private InputStream is;
- private Reader rdr;
- private Map<String, Class<?>> map = new HashMap<>();
- public BaseRowSetTests() {
- brs1 = new StubBaseRowSet();
- is = new StringBufferInputStream(query);
- rdr = new StringReader(query);
- aRowid = new StubRowId();
- try {
- aBlob = new SerialBlob(new StubBlob());
- aClob = new SerialClob(new StubClob());
- aRef = new SerialRef(new StubRef("INTEGER", query));
- aArray = new SerialArray(new StubArray("INTEGER", new Object[1]));
- map.put("SUPERHERO", Class.forName("util.SuperHero"));
- } catch (SQLException | ClassNotFoundException ex) {
- Logger.getLogger(BaseRowSetTests.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- @BeforeMethod
@Override
- public void setUpMethod() throws Exception {
- brs = new StubBaseRowSet();
- }
-
- /*
- * Validate that getCommand() returns null by default
- */
- @Test
- public void test() {
- assertTrue(brs.getCommand() == null);
- }
-
- /*
- * Validate that getCommand() returns command specified to setCommand
- */
- @Test
- public void test01() throws Exception {
- brs.setCommand(query);
- assertTrue(brs.getCommand().equals(query));
- }
-
- /*
- * Validate that getCurrency() returns the correct default value
- */
- @Test
- public void test02() throws Exception {
- assertTrue(brs.getConcurrency() == ResultSet.CONCUR_UPDATABLE);
- }
-
- /*
- * Validate that getCurrency() returns the correct value
- * after a call to setConcurrency())
- */
- @Test(dataProvider = "concurTypes")
- public void test03(int concurType) throws Exception {
- brs.setConcurrency(concurType);
- assertTrue(brs.getConcurrency() == concurType);
- }
-
- /*
- * Validate that getCurrency() throws a SQLException for an invalid value
- */
- @Test(expectedExceptions = SQLException.class)
- public void test04() throws Exception {
- brs.setConcurrency(ResultSet.CLOSE_CURSORS_AT_COMMIT);
- }
-
- /*
- * Validate that getDataSourceName() returns null by default
- */
- @Test
- public void test05() throws Exception {
- assertTrue(brs.getDataSourceName() == null);
- }
-
- /*
- * Validate that getDataSourceName() returns the value specified
- * by setDataSourceName() and getUrl() returns null
- */
- @Test
- public void test06() throws Exception {
- brs.setUrl(url);
- brs.setDataSourceName(dsName);
- assertTrue(brs.getDataSourceName().equals(dsName));
- assertTrue(brs.getUrl() == null);
- }
-
- /*
- * Validate that setDataSourceName() throws a SQLException for an empty
- * String specified for the data source name
- */
- @Test(expectedExceptions = SQLException.class)
- public void test07() throws Exception {
- String dsname = "";
- brs.setDataSourceName(dsname);
- }
-
- /*
- * Validate that getEscapeProcessing() returns true by default
- */
- @Test
- public void test08() throws Exception {
- assertTrue(brs.getEscapeProcessing());
- }
-
- /*
- * Validate that getEscapeProcessing() returns value set by
- * setEscapeProcessing()
- */
- @Test(dataProvider = "trueFalse")
- public void test09(boolean val) throws Exception {
- brs.setEscapeProcessing(val);
- assertTrue(brs.getEscapeProcessing() == val);
- }
-
- /*
- * Validate that getFetchDirection() returns the correct default value
- */
- @Test
- public void test10() throws Exception {
- assertTrue(brs.getFetchDirection() == ResultSet.FETCH_FORWARD);
- }
-
- /*
- * Validate that getFetchDirection() returns the value set by
- * setFetchDirection()
- */
- @Test(dataProvider = "fetchDirection")
- public void test11(int direction) throws Exception {
- brs.setFetchDirection(direction);
- assertTrue(brs.getFetchDirection() == direction);
+ protected RowSet newInstance() throws SQLException {
+ return new StubBaseRowSet();
}
/*
- * Validate that setConcurrency() throws a SQLException for an invalid value
- */
- @Test(expectedExceptions = SQLException.class)
- public void test12() throws Exception {
- brs.setConcurrency(ResultSet.CLOSE_CURSORS_AT_COMMIT);
- }
-
- /*
- * Validate that setFetchSize() throws a SQLException for an invalid value
- */
- @Test(expectedExceptions = SQLException.class)
- public void test13() throws Exception {
- brs.setFetchSize(-1);
- }
-
- /*
- * Validate that setFetchSize() throws a SQLException for a
- * value greater than getMaxRows()
- */
- @Test(expectedExceptions = SQLException.class)
- public void test14() throws Exception {
- brs.setMaxRows(5);
- brs.setFetchSize(brs.getMaxRows() + 1);
- }
-
- /*
- * Validate that getFetchSize() returns the correct value after
- * setFetchSize() has been called
+ * Create a RowSetListener and validate that notifyCursorMoved is called
*/
- @Test
- public void test15() throws Exception {
- int maxRows = 150;
- brs.setFetchSize(0);
- assertTrue(brs.getFetchSize() == 0);
- brs.setFetchSize(100);
- assertTrue(brs.getFetchSize() == 100);
- brs.setMaxRows(maxRows);
- brs.setFetchSize(maxRows);
- assertTrue(brs.getFetchSize() == maxRows);
- }
-
- /*
- * Validate that setMaxFieldSize() throws a SQLException for an invalid value
- */
- @Test(expectedExceptions = SQLException.class)
- public void test16() throws Exception {
- brs.setMaxFieldSize(-1);
- }
-
- /*
- * Validate that getMaxFieldSize() returns the value set by
- * setMaxFieldSize()
- */
- @Test
- public void test17() throws Exception {
- brs.setMaxFieldSize(0);
- assertTrue(brs.getMaxFieldSize() == 0);
- brs.setMaxFieldSize(100);
- assertTrue(brs.getMaxFieldSize() == 100);
- brs.setMaxFieldSize(50);
- assertTrue(brs.getMaxFieldSize() == 50);
- }
-
- /*
- * Validate that isReadOnly() returns value set by
- * setReadOnly()
- */
- @Test(dataProvider = "trueFalse")
- public void test18(boolean val) throws Exception {
- brs.setReadOnly(val);
- assertTrue(brs.isReadOnly() == val);
+ @Test(dataProvider = "rowSetType")
+ public void baseRowSetTest0000(StubBaseRowSet rs) throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ rs.addRowSetListener(rsl);
+ rs.notifyCursorMoved();
+ assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED));
}
/*
- * Validate that getTransactionIsolation() returns value set by
- * setTransactionIsolation()
- */
- @Test(dataProvider = "isolationTypes")
- public void test19(int val) throws Exception {
- brs.setTransactionIsolation(val);
- assertTrue(brs.getTransactionIsolation() == val);
- }
-
- /*
- * Validate that getType() returns value set by setType()
- */
- @Test(dataProvider = "scrollTypes")
- public void test20(int val) throws Exception {
- brs.setType(val);
- assertTrue(brs.getType() == val);
- }
-
- /*
- * Validate that getEscapeProcessing() returns value set by
- * setEscapeProcessing()
- */
- @Test(dataProvider = "trueFalse")
- public void test21(boolean val) throws Exception {
- brs.setShowDeleted(val);
- assertTrue(brs.getShowDeleted() == val);
- }
-
- /*
- * Validate that getTypeMap() returns same value set by
- * setTypeMap()
- */
- @Test()
- public void test22() throws Exception {
- brs.setTypeMap(map);
- assertTrue(brs.getTypeMap().equals(map));
- }
-
- /*
- * Validate that getUsername() returns same value set by
- * setUsername()
+ * Create a RowSetListener and validate that notifyRowChanged is called
*/
- @Test()
- public void test23() throws Exception {
- brs.setUsername(user);
- assertTrue(brs.getUsername().equals(user));
- }
-
- /*
- * Validate that getPassword() returns same password set by
- * setPassword()
- */
- @Test()
- public void test24() throws Exception {
- brs.setPassword(password);
- assertTrue(brs.getPassword().equals(password));
- }
-
- /*
- * Validate that getQueryTimeout() returns same value set by
- * setQueryTimeout() and that 0 is a valid timeout value
- */
- @Test()
- public void test25() throws Exception {
- int timeout = 0;
- brs.setQueryTimeout(timeout);
- assertTrue(brs.getQueryTimeout() == timeout);
- }
-
- /*
- * Validate that getQueryTimeout() returns same value set by
- * setQueryTimeout() and that 0 is a valid timeout value
- */
- @Test()
- public void test26() throws Exception {
- int timeout = 10000;
- brs.setQueryTimeout(timeout);
- assertTrue(brs.getQueryTimeout() == timeout);
- }
-
- /*
- * Validate that setQueryTimeout() throws a SQLException for a timeout
- * value < 0
- */
- @Test(expectedExceptions = SQLException.class)
- public void test27() throws Exception {
- brs.setQueryTimeout(-1);
+ @Test(dataProvider = "rowSetType")
+ public void baseRowSetTest0001(StubBaseRowSet rs) throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ rs.addRowSetListener(rsl);
+ rs.notifyRowChanged();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
}
/*
* Create a RowSetListener and validate that notifyRowSetChanged is called
*/
- @Test()
- public void test28() throws Exception {
- TestRowSetListener rsl = new TestRowSetListener();
- brs.addRowSetListener(rsl);
- brs.notifyRowSetChanged();
- assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
- }
-
- /*
- * Create a RowSetListener and validate that notifyRowChanged is called
- */
- @Test()
- public void test29() throws Exception {
+ @Test(dataProvider = "rowSetType")
+ public void baseRowSetTest0002(StubBaseRowSet rs) throws Exception {
TestRowSetListener rsl = new TestRowSetListener();
- brs.addRowSetListener(rsl);
- brs.notifyRowChanged();
- assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
- }
-
- /*
- * Create a RowSetListener and validate that notifyCursorMoved is called
- */
- @Test()
- public void test30() throws Exception {
- TestRowSetListener rsl = new TestRowSetListener();
- brs.addRowSetListener(rsl);
- brs.notifyCursorMoved();
- assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED));
- }
-
- /*
- * Create a RowSetListener and validate that notifyRowSetChanged,
- * notifyRowChanged() and notifyCursorMoved are called
- */
- @Test()
- public void test31() throws Exception {
- TestRowSetListener rsl = new TestRowSetListener();
- brs.addRowSetListener(rsl);
- brs.notifyRowSetChanged();
- brs.notifyRowChanged();
- brs.notifyCursorMoved();
- assertTrue(rsl.isNotified(
- TestRowSetListener.CURSOR_MOVED | TestRowSetListener.ROWSET_CHANGED
- | TestRowSetListener.ROW_CHANGED));
+ rs.addRowSetListener(rsl);
+ rs.notifyRowSetChanged();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
}
/*
* Create multiple RowSetListeners and validate that notifyRowSetChanged
* is called on all listeners
*/
- @Test()
- public void test32() throws Exception {
+ @Test(dataProvider = "rowSetType")
+ public void baseRowSetTest0003(StubBaseRowSet rs) throws Exception {
TestRowSetListener rsl = new TestRowSetListener();
TestRowSetListener rsl2 = new TestRowSetListener();
- brs.addRowSetListener(rsl);
- brs.addRowSetListener(rsl2);
- brs.notifyRowSetChanged();
+ rs.addRowSetListener(rsl);
+ rs.addRowSetListener(rsl2);
+ rs.notifyRowSetChanged();
assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
assertTrue(rsl2.isNotified(TestRowSetListener.ROWSET_CHANGED));
}
@@ -453,13 +116,13 @@
* Create multiple RowSetListeners and validate that notifyRowChanged
* is called on all listeners
*/
- @Test()
- public void test33() throws Exception {
+ @Test(dataProvider = "rowSetType")
+ public void baseRowSetTest0004(StubBaseRowSet rs) throws Exception {
TestRowSetListener rsl = new TestRowSetListener();
TestRowSetListener rsl2 = new TestRowSetListener();
- brs.addRowSetListener(rsl);
- brs.addRowSetListener(rsl2);
- brs.notifyRowChanged();
+ rs.addRowSetListener(rsl);
+ rs.addRowSetListener(rsl2);
+ rs.notifyRowChanged();
assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
assertTrue(rsl2.isNotified(TestRowSetListener.ROW_CHANGED));
}
@@ -468,30 +131,47 @@
* Create multiple RowSetListeners and validate that notifyCursorMoved
* is called on all listeners
*/
- @Test()
- public void test34() throws Exception {
+ @Test(dataProvider = "rowSetType")
+ public void baseRowSetTest0005(StubBaseRowSet rs) throws Exception {
TestRowSetListener rsl = new TestRowSetListener();
TestRowSetListener rsl2 = new TestRowSetListener();
- brs.addRowSetListener(rsl);
- brs.addRowSetListener(rsl2);
- brs.notifyCursorMoved();
+ rs.addRowSetListener(rsl);
+ rs.addRowSetListener(rsl2);
+ rs.notifyCursorMoved();
assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED));
assertTrue(rsl2.isNotified(TestRowSetListener.CURSOR_MOVED));
}
/*
+ * Create a RowSetListener and validate that notifyRowSetChanged,
+ * notifyRowChanged() and notifyCursorMoved are called
+ */
+ @Test(dataProvider = "rowSetType")
+ public void baseRowSetTest0006(StubBaseRowSet rs) throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ rs.addRowSetListener(rsl);
+ rs.notifyRowSetChanged();
+ rs.notifyRowChanged();
+ rs.notifyCursorMoved();
+ assertTrue(rsl.isNotified(
+ TestRowSetListener.CURSOR_MOVED | TestRowSetListener.ROWSET_CHANGED
+ | TestRowSetListener.ROW_CHANGED));
+ }
+
+
+ /*
* Create multiple RowSetListeners and validate that notifyRowSetChanged,
* notifyRowChanged() and notifyCursorMoved are called on all listeners
*/
- @Test()
- public void test35() throws Exception {
+ @Test(dataProvider = "rowSetType")
+ public void baseRowSetTest0007(StubBaseRowSet rs) throws Exception {
TestRowSetListener rsl = new TestRowSetListener();
TestRowSetListener rsl2 = new TestRowSetListener();
- brs.addRowSetListener(rsl);
- brs.addRowSetListener(rsl2);
- brs.notifyRowSetChanged();
- brs.notifyRowChanged();
- brs.notifyCursorMoved();
+ rs.addRowSetListener(rsl);
+ rs.addRowSetListener(rsl2);
+ rs.notifyRowSetChanged();
+ rs.notifyRowChanged();
+ rs.notifyCursorMoved();
assertTrue(rsl.isNotified(
TestRowSetListener.CURSOR_MOVED | TestRowSetListener.ROWSET_CHANGED
| TestRowSetListener.ROW_CHANGED));
@@ -505,55 +185,25 @@
* remove the listener, invoke notifyRowSetChanged again and verify the
* listner is not called
*/
- @Test()
- public void test36() throws Exception {
+ @Test(dataProvider = "rowSetType")
+ public void baseRowSetTest0008(StubBaseRowSet rs) throws Exception {
TestRowSetListener rsl = new TestRowSetListener();
- brs.addRowSetListener(rsl);
- brs.notifyRowSetChanged();
+ rs.addRowSetListener(rsl);
+ rs.notifyRowSetChanged();
assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
// Clear the flag indicating the listener has been called
rsl.resetFlag();
- brs.removeRowSetListener(rsl);
- brs.notifyRowSetChanged();
+ rs.removeRowSetListener(rsl);
+ rs.notifyRowSetChanged();
assertFalse(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
}
/*
- * Validate addRowSetListener does not throw an Exception when null is
- * passed as the parameter
- */
- @Test()
- public void test37() throws Exception {
- brs.addRowSetListener(null);
- }
-
- /*
- * Validate removeRowSetListener does not throw an Exception when null is
- * passed as the parameter
- */
- @Test()
- public void test38() throws Exception {
- brs.removeRowSetListener(null);
- }
-
- /*
- * Set two parameters and then validate clearParameters() will clear them
- */
- @Test()
- public void test39() throws Exception {
- brs.setInt(1, 1);
- brs.setString(2, query);
- assertTrue(brs.getParams().length == 2);
- brs.clearParameters();
- assertTrue(brs.getParams().length == 0);
- }
-
- /*
* Set the base parameters and validate that the value set is
* the correct type and value
*/
@Test(dataProvider = "testBaseParameters")
- public void test40(int pos, Object o) throws Exception {
+ public void baseRowSetTest0009(int pos, Object o) throws Exception {
assertTrue(getParam(pos, o).getClass().isInstance(o));
assertTrue(o.equals(getParam(pos, o)));
}
@@ -563,7 +213,7 @@
* the correct type
*/
@Test(dataProvider = "testAdvancedParameters")
- public void test41(int pos, Object o) throws Exception {
+ public void baseRowSetTest0010(int pos, Object o) throws Exception {
assertTrue(getParam(pos, o).getClass().isInstance(o));
}
@@ -571,7 +221,8 @@
* Validate setNull specifying the supported type values
*/
@Test(dataProvider = "jdbcTypes")
- public void test42(Integer type) throws Exception {
+ public void baseRowSetTest0011(Integer type) throws Exception {
+ brs = new StubBaseRowSet();
brs.setNull(1, type);
assertTrue(checkNullParam(1, type, null));
}
@@ -581,7 +232,8 @@
* typeName is set internally
*/
@Test(dataProvider = "jdbcTypes")
- public void test43(Integer type) throws Exception {
+ public void baseRowSetTest0012(Integer type) throws Exception {
+ brs = new StubBaseRowSet();
brs.setNull(1, type, "SUPERHERO");
assertTrue(checkNullParam(1, type, "SUPERHERO"));
}
@@ -590,8 +242,10 @@
* Validate that setDate sets the specified Calendar internally
*/
@Test()
- public void test44() throws Exception {
- brs.setDate(1, aDate, cal);
+ public void baseRowSetTest0013() throws Exception {
+ Calendar cal = Calendar.getInstance();
+ brs = new StubBaseRowSet();
+ brs.setDate(1, Date.valueOf(LocalDate.now()), cal);
assertTrue(checkCalendarParam(1, cal));
}
@@ -599,8 +253,10 @@
* Validate that setTime sets the specified Calendar internally
*/
@Test()
- public void test45() throws Exception {
- brs.setTime(1, aTime, cal);
+ public void baseRowSetTest0014() throws Exception {
+ Calendar cal = Calendar.getInstance();
+ brs = new StubBaseRowSet();
+ brs.setTime(1, Time.valueOf(LocalTime.now()), cal);
assertTrue(checkCalendarParam(1, cal));
}
@@ -608,564 +264,23 @@
* Validate that setTimestamp sets the specified Calendar internally
*/
@Test()
- public void test46() throws Exception {
- brs.setTimestamp(1, ts, cal);
+ public void baseRowSetTest0015() throws Exception {
+ Calendar cal = Calendar.getInstance();
+ brs = new StubBaseRowSet();
+ brs.setTimestamp(1, Timestamp.valueOf(LocalDateTime.now()), cal);
assertTrue(checkCalendarParam(1, cal));
}
/*
- * Validate that getURL() returns same value set by
- * setURL()
- */
- @Test()
- public void test47() throws Exception {
- brs.setUrl(url);
- assertTrue(brs.getUrl().equals(url));
- }
-
- /*
* Validate that initParams() initializes the parameters
*/
- @Test()
- public void test48() throws Exception {
- brs.setInt(1, 1);
- brs.initParams();
- assertTrue(brs.getParams().length == 0);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
-
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test100() throws Exception {
- brs1.setAsciiStream(1, is);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test101() throws Exception {
- brs1.setAsciiStream("one", is);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test102() throws Exception {
- brs1.setAsciiStream("one", is, query.length());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test103() throws Exception {
- brs1.setBinaryStream(1, is);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test104() throws Exception {
- brs1.setBinaryStream("one", is);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test105() throws Exception {
- brs1.setBinaryStream("one", is, query.length());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test106() throws Exception {
- brs1.setBigDecimal("one", BigDecimal.ONE);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test107() throws Exception {
- brs1.setBlob(1, is);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test108() throws Exception {
- brs1.setBlob("one", is);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test109() throws Exception {
- brs1.setBlob("one", is, query.length());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test110() throws Exception {
- brs1.setBlob("one", aBlob);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test111() throws Exception {
- brs1.setBoolean("one", true);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test112() throws Exception {
- byte b = 1;
- brs1.setByte("one", b);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test113() throws Exception {
- byte b = 1;
- brs1.setBytes("one", bytes);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test114() throws Exception {
- brs1.setCharacterStream("one", rdr, query.length());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test115() throws Exception {
- brs1.setCharacterStream("one", rdr);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test116() throws Exception {
- brs1.setCharacterStream(1, rdr);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test117() throws Exception {
- brs1.setClob(1, rdr);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test118() throws Exception {
- brs1.setClob("one", rdr);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test119() throws Exception {
- brs1.setClob("one", rdr, query.length());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test120() throws Exception {
- brs1.setClob("one", aClob);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test121() throws Exception {
- brs1.setDate("one", aDate);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test122() throws Exception {
- brs1.setDate("one", aDate, cal);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test123() throws Exception {
- brs1.setTime("one", aTime);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test124() throws Exception {
- brs1.setTime("one", aTime, cal);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test125() throws Exception {
- brs1.setTimestamp("one", ts);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test126() throws Exception {
- brs1.setTimestamp("one", ts, cal);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test127() throws Exception {
- brs1.setDouble("one", 2.0d);
+ @Test(dataProvider = "rowSetType")
+ public void baseRowSetTest0016(StubBaseRowSet rs) throws Exception {
+ rs.setInt(1, 1);
+ rs.initParams();
+ assertTrue(rs.getParams().length == 0);
}
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test128() throws Exception {
- brs1.setFloat("one", 2.0f);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test129() throws Exception {
- brs1.setInt("one", 21);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test130() throws Exception {
- brs1.setLong("one", 21l);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test131() throws Exception {
- brs1.setNCharacterStream("one", rdr, query.length());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test132() throws Exception {
- brs1.setNCharacterStream("one", rdr);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test133() throws Exception {
- brs1.setNCharacterStream(1, rdr);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test134() throws Exception {
- brs1.setNCharacterStream(1, rdr, query.length());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test135() throws Exception {
- brs1.setClob("one", rdr);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test136() throws Exception {
- brs1.setClob("one", rdr, query.length());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test137() throws Exception {
- brs1.setNClob("one", new StubNClob());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test138() throws Exception {
- brs1.setNClob(1, rdr);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test139() throws Exception {
- brs1.setNClob(1, rdr, query.length());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test140() throws Exception {
- brs1.setNClob(1, new StubNClob());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test141() throws Exception {
- brs1.setNString(1, query);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test142() throws Exception {
- brs1.setNull("one", Types.INTEGER);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test143() throws Exception {
- brs1.setNull("one", Types.INTEGER, "my.type");
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test144() throws Exception {
- brs1.setObject("one", query, Types.VARCHAR);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test145() throws Exception {
- brs1.setObject("one", query, Types.VARCHAR, 0);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test146() throws Exception {
- brs1.setObject("one", query);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test147() throws Exception {
- brs1.setRowId("one", aRowid);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test148() throws Exception {
- brs1.setSQLXML("one", new StubSQLXML());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test149() throws Exception {
- brs1.setSQLXML(1, new StubSQLXML());
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test150() throws Exception {
- brs1.setNString(1, query);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test151() throws Exception {
- brs1.setNString("one", query);
- }
-
- /*
- * This method is currently not implemented in BaseRowSet and will
- * throw a SQLFeatureNotSupportedException
- */
- @Test(expectedExceptions = SQLFeatureNotSupportedException.class)
- public void test152() throws Exception {
- short val = 21;
- brs1.setShort("one", val);
- }
-
- /*
- * DataProvider used to specify the value to set and check for
- * methods using transaction isolation types
- */
- @DataProvider(name = "isolationTypes")
- private Object[][] isolationTypes() {
- return new Object[][]{
- {Connection.TRANSACTION_NONE},
- {Connection.TRANSACTION_READ_COMMITTED},
- {Connection.TRANSACTION_READ_UNCOMMITTED},
- {Connection.TRANSACTION_REPEATABLE_READ},
- {Connection.TRANSACTION_SERIALIZABLE}
- };
- }
-
- /*
- * DataProvider used to specify the value to set and check for the
- * methods for fetch direction
- */
- @DataProvider(name = "fetchDirection")
- private Object[][] fetchDirection() {
- return new Object[][]{
- {ResultSet.FETCH_FORWARD},
- {ResultSet.FETCH_REVERSE},
- {ResultSet.FETCH_UNKNOWN}
- };
- }
-
- /*
- * DataProvider used to specify the value to set and check for the
- * methods for Concurrency
- */
- @DataProvider(name = "concurTypes")
- private Object[][] concurTypes() {
- return new Object[][]{
- {ResultSet.CONCUR_READ_ONLY},
- {ResultSet.CONCUR_UPDATABLE}
- };
- }
-
- /*
- * DataProvider used to specify the value to set and check for the
- * methods for Cursor Scroll Type
- */
- @DataProvider(name = "scrollTypes")
- private Object[][] scrollTypes() {
- return new Object[][]{
- {ResultSet.TYPE_FORWARD_ONLY},
- {ResultSet.TYPE_SCROLL_INSENSITIVE},
- {ResultSet.TYPE_SCROLL_SENSITIVE}
- };
- }
/*
* DataProvider used to set parameters for basic types that are supported
@@ -1177,29 +292,33 @@
Short aShort = Short.MIN_VALUE;
BigDecimal bd = BigDecimal.ONE;
Double aDouble = Double.MAX_VALUE;
+ Date aDate = Date.valueOf(LocalDate.now());
+ Time aTime = Time.valueOf(LocalTime.now());
+ Timestamp aTimeStamp = Timestamp.valueOf(LocalDateTime.now());
+ Calendar cal = Calendar.getInstance();
Boolean aBoolean = true;
Float aFloat = 1.5f;
Byte aByte = 1;
+ brs = new StubBaseRowSet();
- brs1.clearParameters();
- brs1.setInt(1, aInt);
- brs1.setString(2, query);
- brs1.setLong(3, aLong);
- brs1.setBoolean(4, aBoolean);
- brs1.setShort(5, aShort);
- brs1.setDouble(6, aDouble);
- brs1.setBigDecimal(7, bd);
- brs1.setFloat(8, aFloat);
- brs1.setByte(9, aByte);
- brs1.setDate(10, aDate);
- brs1.setTime(11, aTime);
- brs1.setTimestamp(12, ts);
- brs1.setDate(13, aDate, cal);
- brs1.setTime(14, aTime, cal);
- brs1.setTimestamp(15, ts);
- brs1.setObject(16, query);
- brs1.setObject(17, query, Types.CHAR);
- brs1.setObject(18, query, Types.CHAR, 0);
+ brs.setInt(1, aInt);
+ brs.setString(2, query);
+ brs.setLong(3, aLong);
+ brs.setBoolean(4, aBoolean);
+ brs.setShort(5, aShort);
+ brs.setDouble(6, aDouble);
+ brs.setBigDecimal(7, bd);
+ brs.setFloat(8, aFloat);
+ brs.setByte(9, aByte);
+ brs.setDate(10, aDate);
+ brs.setTime(11, aTime);
+ brs.setTimestamp(12, aTimeStamp);
+ brs.setDate(13, aDate, cal);
+ brs.setTime(14, aTime, cal);
+ brs.setTimestamp(15, aTimeStamp);
+ brs.setObject(16, query);
+ brs.setObject(17, query, Types.CHAR);
+ brs.setObject(18, query, Types.CHAR, 0);
return new Object[][]{
{1, aInt},
@@ -1213,10 +332,10 @@
{9, aByte},
{10, aDate},
{11, aTime},
- {12, ts},
+ {12, aTimeStamp},
{13, aDate},
{14, aTime},
- {15, ts},
+ {15, aTimeStamp},
{16, query},
{17, query},
{18, query}
@@ -1230,16 +349,23 @@
@DataProvider(name = "testAdvancedParameters")
private Object[][] testAdvancedParameters() throws SQLException {
- brs1.clearParameters();
- brs1.setBytes(1, bytes);
- brs1.setAsciiStream(2, is, query.length());
- brs1.setRef(3, aRef);
- brs1.setArray(4, aArray);
- brs1.setBlob(5, aBlob);
- brs1.setClob(6, aClob);
- brs1.setBinaryStream(7, is, query.length());
- brs1.setUnicodeStream(8, is, query.length());
- brs1.setCharacterStream(9, rdr, query.length());
+ byte[] bytes = new byte[10];
+ Ref aRef = new SerialRef(new StubRef("INTEGER", query));
+ Array aArray = new SerialArray(new StubArray("INTEGER", new Object[1]));
+ Blob aBlob = new SerialBlob(new StubBlob());
+ Clob aClob = new SerialClob(new StubClob());
+ Reader rdr = new StringReader(query);
+ InputStream is = new StringBufferInputStream(query);;
+ brs = new StubBaseRowSet();
+ brs.setBytes(1, bytes);
+ brs.setAsciiStream(2, is, query.length());
+ brs.setRef(3, aRef);
+ brs.setArray(4, aArray);
+ brs.setBlob(5, aBlob);
+ brs.setClob(6, aClob);
+ brs.setBinaryStream(7, is, query.length());
+ brs.setUnicodeStream(8, is, query.length());
+ brs.setCharacterStream(9, rdr, query.length());
return new Object[][]{
{1, bytes},
@@ -1261,7 +387,7 @@
*/
@SuppressWarnings("unchecked")
private <T> T getParam(int pos, T o) throws SQLException {
- Object[] params = brs1.getParams();
+ Object[] params = brs.getParams();
if (params[pos - 1] instanceof Object[]) {
Object[] param = (Object[]) params[pos - 1];
return (T) param[0];
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/test/rowset/CommonRowSetTests.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,1372 @@
+/*
+ * 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 test.rowset;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.sql.RowSet;
+import javax.sql.rowset.BaseRowSet;
+import javax.sql.rowset.CachedRowSet;
+import javax.sql.rowset.RowSetFactory;
+import javax.sql.rowset.RowSetMetaDataImpl;
+import javax.sql.rowset.RowSetProvider;
+import org.testng.Assert;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.StubBlob;
+import util.StubClob;
+import util.StubNClob;
+import util.StubSQLXML;
+
+public abstract class CommonRowSetTests extends BaseTest {
+
+ protected final String stubProvider = "util.StubSyncProvider";
+ protected final String query = "SELECT * FROM SUPERHEROS";
+ private final String url = "jdbc:derby://localhost:1527/myDB";
+ private final String dsName = "jdbc/myDB";
+ private final String user = "Bruce Wayne";
+ private final String password = "The Dark Knight";
+ protected final String COFFEE_HOUSES_TABLE = "COFFEE_HOUSES";
+ protected final String COFFEES_TABLE = "COFFEES";
+ protected final int COFFEE_HOUSES_ROWS = 14;
+ protected final int COFFEES_ROWS = 5;
+ protected final Object[] COFFEES_PRIMARY_KEYS = {1, 2, 3, 4, 5};
+ protected final Object[] COFFEE_HOUSES_PRIMARY_KEYS = {
+ 10023, 33002, 10040, 32001, 10042, 10024, 10039, 10041,
+ 33005, 33010, 10035, 10037, 10034, 32004
+ };
+
+ /*
+ * COFFEES_HOUSES Table column names
+ */
+ protected final String[] COFFEE_HOUSES_COLUMN_NAMES = {
+ "STORE_ID", "CITY", "COFFEE", "MERCH", "TOTAL"
+ };
+
+ /*
+ * COFFEES Table column names
+ */
+ protected final String[] COFFEES_COLUMN_NAMES = {
+ "COF_ID", "COF_NAME", "SUP_ID", "PRICE", "SALES", "TOTAL"
+ };
+
+ protected RowSetFactory rsf;
+
+ public CommonRowSetTests() {
+ try {
+ rsf = RowSetProvider.newFactory();
+ } catch (SQLException ex) {
+ Assert.fail(ex.getMessage());
+ }
+ }
+
+ // Create an instance of the RowSet we are using
+ protected abstract <T extends RowSet> T newInstance() throws SQLException;
+
+ //DataProvider to use for common tests
+
+ /*
+ * DataProvider used to specify the value to set and check for the
+ * methods for fetch direction
+ */
+ @DataProvider(name = "rowSetFetchDirection")
+ protected Object[][] rowSetFetchDirection() throws Exception {
+ RowSet rs = newInstance();
+ return new Object[][]{
+ {rs, ResultSet.FETCH_FORWARD},
+ {rs, ResultSet.FETCH_REVERSE},
+ {rs, ResultSet.FETCH_UNKNOWN}
+ };
+ }
+
+ /*
+ * DataProvider used to specify the value to set and check for the
+ * methods for Cursor Scroll Type
+ */
+ @DataProvider(name = "rowSetScrollTypes")
+ protected Object[][] rowSetScrollTypes() throws Exception {
+ RowSet rs = newInstance();
+
+ return new Object[][]{
+ {rs, ResultSet.TYPE_FORWARD_ONLY},
+ {rs, ResultSet.TYPE_SCROLL_INSENSITIVE},
+ {rs, ResultSet.TYPE_SCROLL_SENSITIVE}
+ };
+ }
+
+ /*
+ * DataProvider used to specify the value to set and check for
+ * methods using transaction isolation types
+ */
+ @DataProvider(name = "rowSetIsolationTypes")
+ protected Object[][] rowSetIsolationTypes() throws Exception {
+ RowSet rs = newInstance();
+
+ return new Object[][]{
+ {rs, Connection.TRANSACTION_NONE},
+ {rs, Connection.TRANSACTION_READ_COMMITTED},
+ {rs, Connection.TRANSACTION_READ_UNCOMMITTED},
+ {rs, Connection.TRANSACTION_REPEATABLE_READ},
+ {rs, Connection.TRANSACTION_SERIALIZABLE}
+ };
+ }
+
+ /*
+ * DataProvider used to specify the value to set and check for the
+ * methods for Concurrency
+ */
+ @DataProvider(name = "rowSetConcurrencyTypes")
+ protected Object[][] rowSetConcurrencyTypes() throws Exception {
+ RowSet rs = newInstance();
+ return new Object[][]{
+ {rs, ResultSet.CONCUR_READ_ONLY},
+ {rs, ResultSet.CONCUR_UPDATABLE}
+ };
+ }
+
+ /*
+ * DataProvider used to specify the value to set and check for
+ * methods using boolean values
+ */
+ @DataProvider(name = "rowSetTrueFalse")
+ protected Object[][] rowSetTrueFalse() throws Exception {
+ RowSet rs = newInstance();
+ return new Object[][]{
+ {rs, true},
+ {rs, false}
+ };
+ }
+ /*
+ * DataProvider used to specify the type of RowSet to use. We also must
+ * initialize the RowSet
+ */
+ @DataProvider(name = "rowSetType")
+ protected Object[][] rowSetType() throws Exception {
+
+ RowSet rs = newInstance();
+ return new Object[][]{
+ {rs}
+ };
+ }
+
+ /*
+ * Initializes a RowSet containing the COFFEE_HOUSES data
+ */
+ protected <T extends RowSet> T createCoffeeHousesRowSet() throws SQLException {
+ T rs = (T) newInstance();
+ initCoffeeHousesMetaData((CachedRowSet) rs);
+ createCoffeeHouseRows(rs);
+ // Make sure you are not on the insertRow
+ rs.moveToCurrentRow();
+ return rs;
+ }
+
+ /*
+ * Initializes a RowSet containing the COFFEE_HOUSES data
+ */
+ protected <T extends RowSet> T createCoffeesRowSet() throws SQLException {
+ T rs = (T) newInstance();
+ initCoffeesMetaData((CachedRowSet) rs);
+ createCoffeesRows(rs);
+ // Make sure you are not on the insertRow
+ rs.moveToCurrentRow();
+ return rs;
+ }
+
+ /*
+ * Initializes the COFFEE_HOUSES metadata
+ */
+ private void initCoffeeHousesMetaData(CachedRowSet crs) throws SQLException {
+ RowSetMetaDataImpl rsmd = new RowSetMetaDataImpl();
+ crs.setType(RowSet.TYPE_SCROLL_INSENSITIVE);
+
+ /*
+ * CREATE TABLE COFFEE_HOUSES(
+ * STORE_ID Integer NOT NULL,
+ * CITY VARCHAR(32),
+ * COFFEE INTEGER NOT NULL,
+ * MERCH INTEGER NOT NULL,
+ * TOTAL INTEGER NOT NULL,
+ * PRIMARY KEY (STORE_ID))
+ */
+ rsmd.setColumnCount(COFFEE_HOUSES_COLUMN_NAMES.length);
+ for(int i = 1; i <= COFFEE_HOUSES_COLUMN_NAMES.length; i++){
+ rsmd.setColumnName(i, COFFEE_HOUSES_COLUMN_NAMES[i-1]);
+ rsmd.setColumnLabel(i, rsmd.getColumnName(i));
+ }
+
+ rsmd.setColumnType(1, Types.INTEGER);
+ rsmd.setColumnType(2, Types.VARCHAR);
+ rsmd.setColumnType(3, Types.INTEGER);
+ rsmd.setColumnType(4, Types.INTEGER);
+ rsmd.setColumnType(5, Types.INTEGER);
+ crs.setMetaData(rsmd);
+ crs.setTableName(COFFEE_HOUSES_TABLE);
+
+ }
+
+ /*
+ * Add rows to COFFEE_HOUSES table
+ */
+ protected void createCoffeeHouseRows(RowSet rs) throws SQLException {
+
+ // insert into COFFEE_HOUSES values(10023, 'Mendocino', 3450, 2005, 5455)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 10023);
+ rs.updateString(2, "Mendocino");
+ rs.updateInt(3, 3450);
+ rs.updateInt(4, 2005);
+ rs.updateInt(5, 5455);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(33002, 'Seattle', 4699, 3109, 7808)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 33002);
+ rs.updateString(2, "Seattle");
+ rs.updateInt(3, 4699);
+ rs.updateInt(4, 3109);
+ rs.updateInt(5, 7808);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(10040, 'SF', 5386, 2841, 8227)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 10040);
+ rs.updateString(2, "SF");
+ rs.updateInt(3, 5386);
+ rs.updateInt(4, 2841);
+ rs.updateInt(5, 8227);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(32001, 'Portland', 3147, 3579, 6726)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 32001);
+ rs.updateString(2, "Portland");
+ rs.updateInt(3, 3147);
+ rs.updateInt(4, 3579);
+ rs.updateInt(5, 6726);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(10042, 'SF', 2863, 1874, 4710)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 10042);
+ rs.updateString(2, "SF");
+ rs.updateInt(3, 2863);
+ rs.updateInt(4, 1874);
+ rs.updateInt(5, 4710);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(10024, 'Sacramento', 1987, 2341, 4328)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 10024);
+ rs.updateString(2, "Sacramento");
+ rs.updateInt(3, 1987);
+ rs.updateInt(4, 2341);
+ rs.updateInt(5, 4328);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(10039, 'Carmel', 2691, 1121, 3812)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 10039);
+ rs.updateString(2, "Carmel");
+ rs.updateInt(3, 2691);
+ rs.updateInt(4, 1121);
+ rs.updateInt(5, 3812);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(10041, 'LA', 1533, 1007, 2540)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 10041);
+ rs.updateString(2, "LA");
+ rs.updateInt(3, 1533);
+ rs.updateInt(4, 1007);
+ rs.updateInt(5, 2540);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(33005, 'Olympia', 2733, 1550, 1550)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 33005);
+ rs.updateString(2, "Olympia");
+ rs.updateInt(3, 2733);
+ rs.updateInt(4, 1550);
+ rs.updateInt(5, 1550);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(33010, 'Seattle', 3210, 2177, 5387)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 33010);
+ rs.updateString(2, "Seattle");
+ rs.updateInt(3, 3210);
+ rs.updateInt(4, 2177);
+ rs.updateInt(5, 5387);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(10035, 'SF', 1922, 1056, 2978)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 10035);
+ rs.updateString(2, "SF");
+ rs.updateInt(3, 1922);
+ rs.updateInt(4, 1056);
+ rs.updateInt(5, 2978);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(10037, 'LA', 2143, 1876, 4019)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 10037);
+ rs.updateString(2, "LA");
+ rs.updateInt(3, 2143);
+ rs.updateInt(4, 1876);
+ rs.updateInt(5, 4019);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(10034, 'San_Jose', 1234, 1032, 2266)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 10034);
+ rs.updateString(2, "San Jose");
+ rs.updateInt(3, 1234);
+ rs.updateInt(4, 1032);
+ rs.updateInt(5, 2266);
+ rs.insertRow();
+ // insert into COFFEE_HOUSES values(32004, 'Eugene', 1356, 1112, 2468)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 32004);
+ rs.updateString(2, "Eugene");
+ rs.updateInt(3, 1356);
+ rs.updateInt(4, 1112);
+ rs.updateInt(5, 2468);
+ rs.insertRow();
+ rs.moveToCurrentRow();
+ }
+
+ /*
+ * Initializes the COFFEES metadata
+ */
+ protected void initCoffeesMetaData(CachedRowSet crs) throws SQLException {
+ RowSetMetaDataImpl rsmd = new RowSetMetaDataImpl();
+ crs.setType(RowSet.TYPE_SCROLL_INSENSITIVE);
+
+ /*
+ * CREATE TABLE COFFEES (
+ * COF_ID INTEGER NOT NULL,
+ * COF_NAME VARCHAR(32) NOT NULL,
+ * SUP_ID INTEGER NOT NULL,
+ * PRICE NUMBERIC(10,2 NOT NULL,
+ * SALES INTEGER NOT NULL,
+ * TOTAL INTEGER NOT NULL,
+ * PRIMARY KEY (COF_ID),
+ * FOREIGN KEY (SUP_ID) REFERENCES SUPPLIERS (SUP_ID) )
+ */
+ rsmd.setColumnCount(COFFEES_COLUMN_NAMES.length);
+ for(int i = 1; i <= COFFEES_COLUMN_NAMES.length; i++){
+ rsmd.setColumnName(i, COFFEES_COLUMN_NAMES[i-1]);
+ rsmd.setColumnLabel(i, rsmd.getColumnName(i));
+ }
+
+ rsmd.setColumnType(1, Types.INTEGER);
+ rsmd.setColumnType(2, Types.VARCHAR);
+ rsmd.setColumnType(3, Types.INTEGER);
+ rsmd.setColumnType(4, Types.NUMERIC);
+ rsmd.setPrecision(4, 10);
+ rsmd.setScale(4, 2);
+ rsmd.setColumnType(5, Types.INTEGER);
+ rsmd.setColumnType(6, Types.INTEGER);
+ crs.setMetaData(rsmd);
+ crs.setTableName(COFFEES_TABLE);
+
+ }
+
+ /*
+ * Add rows to COFFEES table
+ */
+ protected void createCoffeesRows(RowSet rs) throws SQLException {
+
+ // insert into COFFEES values(1, 'Colombian', 101, 7.99, 0, 0)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 1);
+ rs.updateString(2, "Colombian");
+ rs.updateInt(3, 101);
+ rs.updateBigDecimal(4, BigDecimal.valueOf(7.99));
+ rs.updateInt(5, 0);
+ rs.updateInt(6, 0);
+ rs.insertRow();
+ // insert into COFFEES values(2, 'French_Roast', 49, 8.99, 0, 0)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 2);
+ rs.updateString(2, "French_Roast");
+ rs.updateInt(3, 49);
+ rs.updateBigDecimal(4, BigDecimal.valueOf(8.99));
+ rs.updateInt(5, 0);
+ rs.updateInt(6, 0);
+ rs.insertRow();
+ // insert into COFFEES values(3, 'Espresso', 150, 9.99, 0, 0)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 3);
+ rs.updateString(2, "Espresso");
+ rs.updateInt(3, 150);
+ rs.updateBigDecimal(4, BigDecimal.valueOf(9.99));
+ rs.updateInt(5, 0);
+ rs.updateInt(6, 0);
+ rs.insertRow();
+ // insert into COFFEES values(4, 'Colombian_Decaf', 101, 8.99, 0, 0)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 4);
+ rs.updateString(2, "Colombian_Decaf");
+ rs.updateInt(3, 101);
+ rs.updateBigDecimal(4, BigDecimal.valueOf(8.99));
+ rs.updateInt(5, 0);
+ rs.updateInt(6, 0);
+ rs.insertRow();
+ // insert into COFFEES values(5, 'French_Roast_Decaf', 049, 9.99, 0, 0)
+ rs.moveToInsertRow();
+ rs.updateInt(1, 5);
+ rs.updateString(2, "French_Roast_Decaf");
+ rs.updateInt(3, 49);
+ rs.updateBigDecimal(4, BigDecimal.valueOf(9.99));
+ rs.updateInt(5, 0);
+ rs.updateInt(6, 0);
+ rs.insertRow();
+
+ }
+
+
+ /*
+ * Utility method to return the Primary Keys for a RowSet. The Primary
+ * keys are assumed to be in the first column of the RowSet
+ */
+ protected Object[] getPrimaryKeys(ResultSet rs) throws SQLException {
+ List<? super Object> result = new ArrayList<>();
+ if (rs == null) {
+ return null;
+ }
+ rs.beforeFirst();
+ while (rs.next()) {
+ result.add(rs.getInt(1));
+ }
+ return result.toArray();
+ }
+
+ /*
+ * Utility method to display the RowSet and will return the row count
+ * it found
+ */
+ protected int displayResults(ResultSet rs) throws SQLException {
+ int rows = 0;
+ ResultSetMetaData rsmd = rs.getMetaData();
+ int cols = rsmd.getColumnCount();
+ if (rs != null) {
+ rs.beforeFirst();
+ while (rs.next()) {
+ rows++;
+
+ for (int i = 0; i < cols; i++) {
+ System.out.print(rs.getString(i + 1) + " ");
+ }
+ System.out.println();
+ }
+ }
+
+ return rows;
+ }
+
+
+ // Insert common tests here
+
+ /*
+ * Validate that getCommand() returns null by default
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0000(RowSet rs) {
+ assertNull(rs.getCommand());
+ }
+
+ /*
+ * Validate that getCommand() returns command specified to setCommand
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0001(RowSet rs) throws Exception {
+ rs.setCommand(query);
+ assertTrue(rs.getCommand().equals(query));
+ }
+
+
+ /*
+ * Validate that getCurrency() returns the correct default value
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0002(RowSet rs) throws Exception {
+ assertTrue(rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE);
+ }
+
+ /*
+ * Validate that getCurrency() returns the correct value
+ * after a call to setConcurrency())
+ */
+ @Test(dataProvider = "rowSetConcurrencyTypes")
+ public void commonRowSetTest0003(RowSet rs, int concurType) throws Exception {
+ rs.setConcurrency(concurType);
+ assertTrue(rs.getConcurrency() == concurType);
+ }
+
+ /*
+ * Validate that getCurrency() throws a SQLException for an invalid value
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonRowSetTest0004(RowSet rs) throws Exception {
+ rs.setConcurrency(ResultSet.CLOSE_CURSORS_AT_COMMIT);
+ }
+
+ /*
+ * Validate that getDataSourceName() returns null by default
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0005(RowSet rs) throws Exception {
+ assertTrue(rs.getDataSourceName() == null);
+ }
+
+ /*
+ * Validate that getDataSourceName() returns the value specified
+ * by setDataSourceName() and getUrl() returns null
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0006(RowSet rs) throws Exception {
+ rs.setUrl(url);
+ rs.setDataSourceName(dsName);
+ assertTrue(rs.getDataSourceName().equals(dsName));
+ assertNull(rs.getUrl());
+ }
+
+ /*
+ * Validate that setDataSourceName() throws a SQLException for an empty
+ * String specified for the data source name
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonRowSetTest0007(RowSet rs) throws Exception {
+ String dsname = "";
+ rs.setDataSourceName(dsname);
+ }
+
+ /*
+ * Validate that getEscapeProcessing() returns false by default
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0008(RowSet rs) throws Exception {
+ assertTrue(rs.getEscapeProcessing());
+ }
+
+ /*
+ * Validate that getEscapeProcessing() returns value set by
+ * setEscapeProcessing()
+ */
+ @Test(dataProvider = "rowSetTrueFalse")
+ public void commonRowSetTest0009(RowSet rs, boolean val) throws Exception {
+ rs.setEscapeProcessing(val);
+ assertTrue(rs.getEscapeProcessing() == val);
+ }
+
+ /*
+ * Validate that getFetchDirection() returns the correct default value
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0010(RowSet rs) throws Exception {
+ assertTrue(rs.getFetchDirection() == ResultSet.FETCH_FORWARD);
+ }
+
+ /*
+ * Validate that getFetchDirection() returns the value set by
+ * setFetchDirection()
+ */
+ @Test(dataProvider = "rowSetFetchDirection")
+ public void commonRowSetTest0011(RowSet rs, int direction) throws Exception {
+ rs.setFetchDirection(direction);
+ assertTrue(rs.getFetchDirection() == direction);
+ }
+
+ /*
+ * Validate that setFetchSize() throws a SQLException for an invalid value
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonRowSetTest0013(RowSet rs) throws Exception {
+ rs.setFetchSize(-1);
+ }
+
+ /*
+ * Validate that setFetchSize() throws a SQLException for a
+ * value greater than getMaxRows()
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonRowSetTest0014(RowSet rs) throws Exception {
+ rs.setMaxRows(5);
+ rs.setFetchSize(rs.getMaxRows() + 1);
+ }
+
+ /*
+ * Validate that getFetchSize() returns the correct value after
+ * setFetchSize() has been called
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0015(RowSet rs) throws Exception {
+ int maxRows = 150;
+ rs.setFetchSize(0);
+ assertTrue(rs.getFetchSize() == 0);
+ rs.setFetchSize(100);
+ assertTrue(rs.getFetchSize() == 100);
+ rs.setMaxRows(maxRows);
+ rs.setFetchSize(maxRows);
+ assertTrue(rs.getFetchSize() == maxRows);
+ }
+
+ /*
+ * Validate that setMaxFieldSize() throws a SQLException for an invalid value
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonRowSetTest0016(RowSet rs) throws Exception {
+ rs.setMaxFieldSize(-1);
+ }
+
+ /*
+ * Validate that getMaxFieldSize() returns the value set by
+ * setMaxFieldSize()
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0017(RowSet rs) throws Exception {
+ rs.setMaxFieldSize(0);
+ assertTrue(rs.getMaxFieldSize() == 0);
+ rs.setMaxFieldSize(100);
+ assertTrue(rs.getMaxFieldSize() == 100);
+ rs.setMaxFieldSize(50);
+ assertTrue(rs.getMaxFieldSize() == 50);
+ }
+
+ /*
+ * Validate that isReadOnly() returns value set by
+ * setReadOnly()
+ */
+ @Test(dataProvider = "rowSetTrueFalse")
+ public void commonRowSetTest0018(RowSet rs, boolean val) throws Exception {
+ rs.setReadOnly(val);
+ assertTrue(rs.isReadOnly() == val);
+ }
+
+ /*
+ * Validate that getTransactionIsolation() returns value set by
+ * setTransactionIsolation()
+ */
+ @Test(dataProvider = "rowSetIsolationTypes")
+ public void commonRowSetTest0019(RowSet rs, int val) throws Exception {
+ rs.setTransactionIsolation(val);
+ assertTrue(rs.getTransactionIsolation() == val);
+ }
+
+ /*
+ * Validate that getType() returns value set by setType()
+ */
+ @Test(dataProvider = "rowSetScrollTypes")
+ public void commonRowSetTest0020(RowSet rs, int val) throws Exception {
+ rs.setType(val);
+ assertTrue(rs.getType() == val);
+ }
+
+ /*
+ * Validate that getEscapeProcessing() returns value set by
+ * setEscapeProcessing()
+ */
+ @Test(dataProvider = "rowSetTrueFalse")
+ public void commonRowSetTest0021(BaseRowSet rs, boolean val) throws Exception {
+ rs.setShowDeleted(val);
+ assertTrue(rs.getShowDeleted() == val);
+ }
+
+ /*
+ * Validate that getTypeMap() returns same value set by
+ * setTypeMap()
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0022(RowSet rs) throws Exception {
+ Map<String, Class<?>> map = new HashMap<>();
+ map.put("SUPERHERO", Class.forName("util.SuperHero"));
+ rs.setTypeMap(map);
+ assertTrue(rs.getTypeMap().equals(map));
+ }
+
+ /*
+ * Validate that getUsername() returns same value set by
+ * setUsername()
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0023(RowSet rs) throws Exception {
+ rs.setUsername(user);
+ assertTrue(rs.getUsername().equals(user));
+ }
+
+ /*
+ * Validate that getPassword() returns same password set by
+ * setPassword()
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0024(RowSet rs) throws Exception {
+ rs.setPassword(password);
+ assertTrue(rs.getPassword().equals(password));
+ }
+
+ /*
+ * Validate that getQueryTimeout() returns same value set by
+ * setQueryTimeout() and that 0 is a valid timeout value
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0025(RowSet rs) throws Exception {
+ int timeout = 0;
+ rs.setQueryTimeout(timeout);
+ assertTrue(rs.getQueryTimeout() == timeout);
+ }
+
+ /*
+ * Validate that getQueryTimeout() returns same value set by
+ * setQueryTimeout() and that 0 is a valid timeout value
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0026(RowSet rs) throws Exception {
+ int timeout = 10000;
+ rs.setQueryTimeout(timeout);
+ assertTrue(rs.getQueryTimeout() == timeout);
+ }
+
+ /*
+ * Validate that setQueryTimeout() throws a SQLException for a timeout
+ * value < 0
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonRowSetTest0027(RowSet rs) throws Exception {
+ rs.setQueryTimeout(-1);
+ }
+
+
+ /*
+ * Validate addRowSetListener does not throw an Exception when null is
+ * passed as the parameter
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0028(RowSet rs) throws Exception {
+ rs.addRowSetListener(null);
+ }
+
+ /*
+ * Validate removeRowSetListener does not throw an Exception when null is
+ * passed as the parameter
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0029(RowSet rs) throws Exception {
+ rs.removeRowSetListener(null);
+ }
+
+ /*
+ * Set two parameters and then validate clearParameters() will clear them
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0030(BaseRowSet rs) throws Exception {
+ rs.setInt(1, 1);
+ rs.setString(2, query);
+ assertTrue(rs.getParams().length == 2);
+ rs.clearParameters();
+ assertTrue(rs.getParams().length == 0);
+ }
+
+ /*
+ * Validate that getURL() returns same value set by
+ * setURL()
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonRowSetTest0031(RowSet rs) throws Exception {
+ rs.setUrl(url);
+ assertTrue(rs.getUrl().equals(url));
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0100(RowSet rs) throws Exception {
+ InputStream is = null;
+ rs.setAsciiStream(1, is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0101(RowSet rs) throws Exception {
+ InputStream is = null;
+ rs.setAsciiStream("one", is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0102(RowSet rs) throws Exception {
+ InputStream is = null;
+ rs.setAsciiStream("one", is, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0103(RowSet rs) throws Exception {
+ InputStream is = null;
+ rs.setBinaryStream(1, is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0104(RowSet rs) throws Exception {
+ InputStream is = null;
+ rs.setBinaryStream("one", is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0105(RowSet rs) throws Exception {
+ InputStream is = null;
+ rs.setBinaryStream("one", is, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0106(RowSet rs) throws Exception {
+ rs.setBigDecimal("one", BigDecimal.ONE);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0107(RowSet rs) throws Exception {
+ InputStream is = null;
+ rs.setBlob(1, is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0108(RowSet rs) throws Exception {
+ InputStream is = null;
+ rs.setBlob("one", is);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0109(RowSet rs) throws Exception {
+ InputStream is = null;
+ rs.setBlob("one", is, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0110(RowSet rs) throws Exception {
+ rs.setBlob("one", new StubBlob());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0111(RowSet rs) throws Exception {
+ rs.setBoolean("one", true);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0112(RowSet rs) throws Exception {
+ byte b = 1;
+ rs.setByte("one", b);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0113(RowSet rs) throws Exception {
+ byte b = 1;
+ rs.setBytes("one", new byte[10]);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0114(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setCharacterStream("one", rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0115(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setCharacterStream("one", rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0116(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setCharacterStream(1, rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0117(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setClob(1, rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0118(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setClob("one", rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0119(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setClob("one", rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0120(RowSet rs) throws Exception {
+ rs.setClob("one", new StubClob());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0121(RowSet rs) throws Exception {
+ rs.setDate("one", Date.valueOf(LocalDate.now()));
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0122(RowSet rs) throws Exception {
+ rs.setDate("one", Date.valueOf(LocalDate.now()),
+ Calendar.getInstance());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0123(RowSet rs) throws Exception {
+ rs.setTime("one", Time.valueOf(LocalTime.now()));
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0124(RowSet rs) throws Exception {
+ rs.setTime("one", Time.valueOf(LocalTime.now()),
+ Calendar.getInstance());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0125(RowSet rs) throws Exception {
+ rs.setTimestamp("one", Timestamp.valueOf(LocalDateTime.now()));
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0126(RowSet rs) throws Exception {
+ rs.setTimestamp("one", Timestamp.valueOf(LocalDateTime.now()),
+ Calendar.getInstance());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0127(RowSet rs) throws Exception {
+ rs.setDouble("one", 2.0d);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0128(RowSet rs) throws Exception {
+ rs.setFloat("one", 2.0f);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0129(RowSet rs) throws Exception {
+ rs.setInt("one", 21);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0130(RowSet rs) throws Exception {
+ rs.setLong("one", 21l);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0131(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setNCharacterStream("one", rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0132(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setNCharacterStream("one", rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0133(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setNCharacterStream(1, rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0134(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setNCharacterStream(1, rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0135(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setClob("one", rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0136(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setClob("one", rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0137(RowSet rs) throws Exception {
+ rs.setNClob("one", new StubNClob());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0138(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setNClob(1, rdr);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0139(RowSet rs) throws Exception {
+ Reader rdr = null;
+ rs.setNClob(1, rdr, query.length());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0140(RowSet rs) throws Exception {
+ rs.setNClob(1, new StubNClob());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0141(RowSet rs) throws Exception {
+ rs.setNString(1, query);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0142(RowSet rs) throws Exception {
+ rs.setNull("one", Types.INTEGER);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0143(RowSet rs) throws Exception {
+ rs.setNull("one", Types.INTEGER, "my.type");
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0144(RowSet rs) throws Exception {
+ rs.setObject("one", query, Types.VARCHAR);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0145(RowSet rs) throws Exception {
+ rs.setObject("one", query, Types.VARCHAR, 0);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0146(RowSet rs) throws Exception {
+ rs.setObject("one", query);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0147(RowSet rs) throws Exception {
+ RowId aRowid = null;
+ rs.setRowId("one", aRowid);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0148(RowSet rs) throws Exception {
+ rs.setSQLXML("one", new StubSQLXML());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0149(RowSet rs) throws Exception {
+ rs.setSQLXML(1, new StubSQLXML());
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0150(RowSet rs) throws Exception {
+ rs.setNString(1, query);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0151(RowSet rs) throws Exception {
+ rs.setNString("one", query);
+ }
+
+ /*
+ * This method is currently not implemented in BaseRowSet and will
+ * throw a SQLFeatureNotSupportedException
+ */
+ @Test(dataProvider = "rowSetType",
+ expectedExceptions = SQLFeatureNotSupportedException.class)
+ public void commonRowSetTest0152(RowSet rs) throws Exception {
+ short val = 21;
+ rs.setShort("one", val);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/test/rowset/cachedrowset/CachedRowSetTests.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,35 @@
+/*
+ * 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 test.rowset.cachedrowset;
+
+import java.sql.SQLException;
+import javax.sql.rowset.CachedRowSet;
+
+public class CachedRowSetTests extends CommonCachedRowSetTests {
+
+ @Override
+ protected CachedRowSet newInstance() throws SQLException {
+ return rsf.createCachedRowSet();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/test/rowset/cachedrowset/CommonCachedRowSetTests.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,1612 @@
+/*
+ * 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 test.rowset.cachedrowset;
+
+import java.math.BigDecimal;
+import java.sql.Array;
+import java.sql.Date;
+import java.sql.JDBCType;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.Collection;
+import javax.sql.RowSet;
+import javax.sql.rowset.CachedRowSet;
+import javax.sql.rowset.RowSetMetaDataImpl;
+import javax.sql.rowset.serial.SerialRef;
+import javax.sql.rowset.spi.SyncFactory;
+import javax.sql.rowset.spi.SyncProvider;
+import javax.sql.rowset.spi.SyncProviderException;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import test.rowset.CommonRowSetTests;
+import util.StubArray;
+import util.StubRef;
+import util.StubSyncProvider;
+import util.TestRowSetListener;
+
+public abstract class CommonCachedRowSetTests extends CommonRowSetTests {
+
+ /*
+ * DATATYPES Table column names
+ */
+ private final String[] DATATYPES_COLUMN_NAMES = {"AINTEGER", "ACHAR",
+ "AVARCHAR", "ALONG", "ABOOLEAN", "ASHORT", "ADOUBLE", "ABIGDECIMAL",
+ "AREAL", "ABYTE", "ADATE", "ATIME", "ATIMESTAMP", "ABYTES", "ARRAY",
+ "AREF", "AFLOAT"};
+
+ /*
+ * Initializes a RowSet containing the DATAYPES data
+ */
+ protected <T extends RowSet> T createDataTypesRowSet() throws SQLException {
+ T rs = (T) newInstance();
+ initDataTypesMetaData((CachedRowSet) rs);
+ createDataTypesRows(rs);
+ // Make sure you are not on the insertRow
+ rs.moveToCurrentRow();
+ return rs;
+ }
+
+ //DataProviders to use for common tests
+
+ /*
+ * DataProvider that uses a RowSet with the COFFEE_HOUSES Table
+ */
+ @DataProvider(name = "rowsetUsingCoffeeHouses")
+ protected Object[][] rowsetUsingCoffeeHouses() throws Exception {
+ RowSet rs = createCoffeeHousesRowSet();
+ return new Object[][]{
+ {rs}
+ };
+ }
+
+ /*
+ * DataProvider that uses a RowSet with the COFFEES Table
+ */
+ @DataProvider(name = "rowsetUsingCoffees")
+ protected Object[][] rowsetUsingCoffees() throws Exception {
+ RowSet rs = createCoffeesRowSet();
+ return new Object[][]{
+ {rs}
+ };
+ }
+
+ /*
+ * DataProvider that uses a RowSet with the DATAYPES Table and
+ * used to validate the various supported data types
+ */
+ @DataProvider(name = "rowsetUsingDataTypes")
+ protected Object[][] rowsetUsingDataTypes() throws Exception {
+
+ CachedRowSet rs = createDataTypesRowSet();
+ return new Object[][]{
+ {rs, JDBCType.INTEGER},
+ {rs, JDBCType.CHAR},
+ {rs, JDBCType.VARCHAR},
+ {rs, JDBCType.BIGINT},
+ {rs, JDBCType.BOOLEAN},
+ {rs, JDBCType.SMALLINT},
+ {rs, JDBCType.DOUBLE},
+ {rs, JDBCType.DECIMAL},
+ {rs, JDBCType.REAL},
+ {rs, JDBCType.TINYINT},
+ {rs, JDBCType.DATE},
+ {rs, JDBCType.TIME},
+ {rs, JDBCType.TIMESTAMP},
+ {rs, JDBCType.VARBINARY},
+ {rs, JDBCType.ARRAY},
+ {rs, JDBCType.REF},
+ {rs, JDBCType.FLOAT}
+ };
+ }
+
+ /*
+ * Initializes the DATAYPES table metadata
+ */
+ protected void initDataTypesMetaData(CachedRowSet crs) throws SQLException {
+ RowSetMetaDataImpl rsmd = new RowSetMetaDataImpl();
+ crs.setType(RowSet.TYPE_SCROLL_INSENSITIVE);
+
+ rsmd.setColumnCount(DATATYPES_COLUMN_NAMES.length);
+
+ for (int i = 1; i <= DATATYPES_COLUMN_NAMES.length; i++) {
+ rsmd.setColumnName(i, DATATYPES_COLUMN_NAMES[i - 1]);
+ rsmd.setColumnLabel(i, rsmd.getColumnName(i));
+ }
+
+ rsmd.setColumnType(1, Types.INTEGER);
+ rsmd.setColumnType(2, Types.CHAR);
+ rsmd.setColumnType(3, Types.VARCHAR);
+ rsmd.setColumnType(4, Types.BIGINT);
+ rsmd.setColumnType(5, Types.BOOLEAN);
+ rsmd.setColumnType(6, Types.SMALLINT);
+ rsmd.setColumnType(7, Types.DOUBLE);
+ rsmd.setColumnType(8, Types.DECIMAL);
+ rsmd.setColumnType(9, Types.REAL);
+ rsmd.setColumnType(10, Types.TINYINT);
+ rsmd.setColumnType(11, Types.DATE);
+ rsmd.setColumnType(12, Types.TIME);
+ rsmd.setColumnType(13, Types.TIMESTAMP);
+ rsmd.setColumnType(14, Types.VARBINARY);
+ rsmd.setColumnType(15, Types.ARRAY);
+ rsmd.setColumnType(16, Types.REF);
+ rsmd.setColumnType(17, Types.FLOAT);
+ crs.setMetaData(rsmd);
+
+ }
+
+ /*
+ * Add rows to DATAYPES table
+ */
+ protected void createDataTypesRows(RowSet crs) throws SQLException {
+
+ Integer aInteger = 100;
+ String aChar = "Oswald Cobblepot";
+ Long aLong = Long.MAX_VALUE;
+ Short aShort = Short.MAX_VALUE;
+ Double aDouble = Double.MAX_VALUE;
+ BigDecimal aBigDecimal = BigDecimal.ONE;
+ Boolean aBoolean = false;
+ Float aFloat = Float.MAX_VALUE;
+ Byte aByte = Byte.MAX_VALUE;
+ Date aDate = Date.valueOf(LocalDate.now());
+ Time aTime = Time.valueOf(LocalTime.now());
+ Timestamp aTimeStamp = Timestamp.valueOf(LocalDateTime.now());
+ Array aArray = new StubArray("INTEGER", new Object[1]);
+ Ref aRef = new SerialRef(new StubRef("INTEGER", query));
+ byte[] bytes = new byte[10];
+ crs.moveToInsertRow();
+ crs.updateInt(1, aInteger);
+ crs.updateString(2, aChar);
+ crs.updateString(3, aChar);
+ crs.updateLong(4, aLong);
+ crs.updateBoolean(5, aBoolean);
+ crs.updateShort(6, aShort);
+ crs.updateDouble(7, aDouble);
+ crs.updateBigDecimal(8, aBigDecimal);
+ crs.updateFloat(9, aFloat);
+ crs.updateByte(10, aByte);
+ crs.updateDate(11, aDate);
+ crs.updateTime(12, aTime);
+ crs.updateTimestamp(13, aTimeStamp);
+ crs.updateBytes(14, bytes);
+ crs.updateArray(15, aArray);
+ crs.updateRef(16, aRef);
+ crs.updateDouble(17, aDouble);
+ crs.insertRow();
+ crs.moveToCurrentRow();
+
+ }
+
+ /*
+ * Dermine if a Row exists in a ResultSet by its primary key
+ * If the parameter deleteRow is true, delete the row and validate
+ * the RowSet indicates it is deleted
+ */
+ protected boolean findRowByPrimaryKey(RowSet rs, int id, int idPos,
+ boolean deleteRow) throws Exception {
+ boolean foundRow = false;
+ rs.beforeFirst();
+ while (rs.next()) {
+ if (rs.getInt(idPos) == id) {
+ foundRow = true;
+ if (deleteRow) {
+ rs.deleteRow();
+ // validate row is marked as deleted
+ assertTrue(rs.rowDeleted());
+ }
+ break;
+ }
+ }
+ return foundRow;
+ }
+
+ /*
+ * Wrapper method to find if a row exists within a RowSet by its primary key
+ */
+ protected boolean findRowByPrimaryKey(RowSet rs, int id, int idPos) throws Exception {
+ return findRowByPrimaryKey(rs, id, idPos, false);
+ }
+
+ /*
+ * Wrapper method to find if a row exists within a RowSet by its primary key
+ * and delete it
+ */
+ protected boolean deleteRowByPrimaryKey(RowSet rs, int id, int idPos) throws Exception {
+ return findRowByPrimaryKey(rs, id, idPos, true);
+ }
+
+ /*
+ * Utility method that compares two ResultSetMetaDataImpls for containing
+ * the same values
+ */
+ private void compareMetaData(ResultSetMetaData rsmd,
+ ResultSetMetaData rsmd1) throws SQLException {
+
+ assertEquals(rsmd1.getColumnCount(), rsmd.getColumnCount());
+ int cols = rsmd.getColumnCount();
+ for (int i = 1; i <= cols; i++) {
+ assertTrue(rsmd1.getCatalogName(i).equals(rsmd.getCatalogName(i)));
+ assertTrue(rsmd1.getColumnClassName(i).equals(rsmd.getColumnClassName(i)));
+ assertTrue(rsmd1.getColumnDisplaySize(i) == rsmd.getColumnDisplaySize(i));
+ assertTrue(rsmd1.getColumnLabel(i).equals(rsmd.getColumnLabel(i)));
+ assertTrue(rsmd1.getColumnName(i).equals(rsmd.getColumnName(i)));
+ assertTrue(rsmd1.getColumnType(i) == rsmd.getColumnType(i));
+ assertTrue(rsmd1.getPrecision(i) == rsmd.getPrecision(i));
+ assertTrue(rsmd1.getScale(i) == rsmd.getScale(i));
+ assertTrue(rsmd1.getSchemaName(i).equals(rsmd.getSchemaName(i)));
+ assertTrue(rsmd1.getTableName(i).equals(rsmd.getTableName(i)));
+ assertTrue(rsmd1.isAutoIncrement(i) == rsmd.isAutoIncrement(i));
+ assertTrue(rsmd1.isCaseSensitive(i) == rsmd.isCaseSensitive(i));
+ assertTrue(rsmd1.isCurrency(i) == rsmd.isCurrency(i));
+ assertTrue(rsmd1.isDefinitelyWritable(i) == rsmd.isDefinitelyWritable(i));
+ assertTrue(rsmd1.isNullable(i) == rsmd.isNullable(i));
+ assertTrue(rsmd1.isReadOnly(i) == rsmd.isReadOnly(i));
+ assertTrue(rsmd1.isSearchable(i) == rsmd.isSearchable(i));
+ assertTrue(rsmd1.isSigned(i) == rsmd.isSigned(i));
+ assertTrue(rsmd1.isWritable(i) == rsmd.isWritable(i));
+
+ }
+ }
+
+ /*
+ * Utility method to compare two rowsets
+ */
+ private void compareRowSets(CachedRowSet crs, CachedRowSet crs1) throws Exception {
+
+ int rows = crs.size();
+ assertTrue(rows == crs1.size());
+
+ ResultSetMetaData rsmd = crs.getMetaData();
+
+ compareMetaData(rsmd, crs1.getMetaData());
+ int cols = rsmd.getColumnCount();
+
+ for (int row = 1; row <= rows; row++) {
+ crs.absolute((row));
+ crs1.absolute(row);
+ for (int col = 1; col <= cols; col++) {
+ compareColumnValue(JDBCType.valueOf(rsmd.getColumnType(col)),
+ crs, crs1, col);
+ }
+ }
+
+ }
+
+ /*
+ * Utility method to compare two columns
+ */
+ private void compareColumnValue(JDBCType type, ResultSet rs, ResultSet rs1,
+ int col) throws SQLException {
+
+ switch (type) {
+ case INTEGER:
+ assertTrue(rs.getInt(col) == rs1.getInt(col));
+ break;
+ case CHAR:
+ case VARCHAR:
+ assertTrue(rs.getString(col).equals(rs1.getString(col)));
+ break;
+ case BIGINT:
+ assertTrue(rs.getLong(col) == rs1.getLong(col));
+ break;
+ case BOOLEAN:
+ assertTrue(rs.getBoolean(col) == rs1.getBoolean(col));
+ break;
+ case SMALLINT:
+ assertTrue(rs.getShort(col) == rs1.getShort(col));
+ break;
+ case DOUBLE:
+ case FLOAT:
+ assertTrue(rs.getDouble(col) == rs1.getDouble(col));
+ break;
+ case DECIMAL:
+ assertTrue(rs.getBigDecimal(col).equals(rs1.getBigDecimal(col)));
+ break;
+ case REAL:
+ assertTrue(rs.getFloat(col) == rs1.getFloat(col));
+ break;
+ case TINYINT:
+ assertTrue(rs.getByte(col) == rs1.getByte(col));
+ break;
+ case DATE:
+ assertTrue(rs.getDate(col).equals(rs1.getDate(col)));
+ break;
+ case TIME:
+ assertTrue(rs.getTime(col).equals(rs1.getTime(col)));
+ break;
+ case TIMESTAMP:
+ assertTrue(rs.getTimestamp(col).equals(rs1.getTimestamp(col)));
+ break;
+ }
+ }
+
+ /*
+ * Validate SyncProviderException is thrown when acceptChanges is called
+ * but there is not a way to make a connection to the datasource
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SyncProviderException.class)
+ public void commonCachedRowSetTest0000(CachedRowSet rs) throws Exception {
+ rs.acceptChanges();
+ rs.close();
+ }
+
+ /*
+ * Validate SyncProviderException is thrown when acceptChanges is called
+ * when null is passed as the datasource
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SyncProviderException.class)
+ public void commonCachedRowSetTest0001(CachedRowSet rs) throws Exception {
+ rs.acceptChanges(null);
+ rs.close();
+ }
+
+ /*
+ * Validate that that RIOPtimsticProvider is the default SyncProvider
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonCachedRowSetTest0002(CachedRowSet rs) throws SQLException {
+ SyncProvider sp = rs.getSyncProvider();
+ assertTrue(sp instanceof com.sun.rowset.providers.RIOptimisticProvider);
+ rs.close();
+ }
+
+ /*
+ * Validate that you can specify a SyncProvider
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonCachedRowSetTest0003(CachedRowSet rs) throws SQLException {
+
+ // Register a provider and make sure it is avaiable
+ SyncFactory.registerProvider(stubProvider);
+ rs.setSyncProvider(stubProvider);
+ SyncProvider sp = rs.getSyncProvider();
+ assertTrue(sp instanceof StubSyncProvider);
+ SyncFactory.unregisterProvider(stubProvider);
+ rs.close();
+ }
+
+ /*
+ * Create a RowSetListener and validate that notifyRowSetChanged is called
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonCachedRowSetTest0004(CachedRowSet rs) throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ rs.addRowSetListener(rsl);
+ rs.release();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
+ rs.close();
+ }
+
+ /*
+ * Create a RowSetListener and validate that notifyRowSetChanged is called
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonCachedRowSetTest0005(CachedRowSet rs) throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ rs.addRowSetListener(rsl);
+ rs.restoreOriginal();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
+ rs.close();
+ }
+
+ /*
+ * Create a RowSetListener and validate that notifyRowChanged is called
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0006(RowSet rs) throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ rs.addRowSetListener(rsl);
+ rs.moveToInsertRow();
+ rs.updateInt(1, 10024);
+ rs.updateString(2, "Sacramento");
+ rs.updateInt(3, 1987);
+ rs.updateInt(4, 2341);
+ rs.updateInt(5, 4328);
+ rs.insertRow();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
+ rs.close();
+ }
+
+ /*
+ * Create a multiple RowSetListeners and validate that notifyRowChanged,
+ * notifiyMoved is called on all listners
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0007(RowSet rs) throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ TestRowSetListener rsl2 = new TestRowSetListener();
+ rs.addRowSetListener(rsl);
+ rs.addRowSetListener(rsl2);
+ rs.first();
+ rs.updateInt(1, 1961);
+ rs.updateString(2, "Pittsburgh");
+ rs.updateInt(3, 1987);
+ rs.updateInt(4, 2341);
+ rs.updateInt(5, 6689);
+ rs.updateRow();
+ assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED
+ | TestRowSetListener.ROW_CHANGED));
+ assertTrue(rsl2.isNotified(TestRowSetListener.CURSOR_MOVED
+ | TestRowSetListener.ROW_CHANGED));
+ rs.close();
+ }
+
+ /*
+ * Create a RowSetListener and validate that notifyRowChanged and
+ * notifyCursorMoved are called
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0008(CachedRowSet rs) throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ rs.addRowSetListener(rsl);
+
+ rs.first();
+ assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED));
+ rs.deleteRow();
+ assertTrue(
+ rsl.isNotified(TestRowSetListener.ROW_CHANGED | TestRowSetListener.CURSOR_MOVED));
+ rsl.resetFlag();
+ rs.setShowDeleted(true);
+ rs.undoDelete();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
+ rs.close();
+ }
+
+ /*
+ * Create a RowSetListener and validate that notifyCursorMoved is called
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonCachedRowSetTest0009(RowSet rs) throws Exception {
+ TestRowSetListener rsl = new TestRowSetListener();
+ rs.addRowSetListener(rsl);
+ rs.beforeFirst();
+ assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED));
+ rs.close();
+ }
+
+ /*
+ * Validate that getTableName() returns the proper values
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonCachedRowSetTest0010(CachedRowSet rs) throws Exception {
+ assertNull(rs.getTableName());
+ rs.setTableName(COFFEE_HOUSES_TABLE);
+ assertTrue(rs.getTableName().equals(COFFEE_HOUSES_TABLE));
+ rs.close();
+ }
+
+ /*
+ * Validate that getKeyColumns() returns the proper values
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonCachedRowSetTest0011(CachedRowSet rs) throws Exception {
+ int[] pkeys = {1, 3};
+ assertNull(rs.getKeyColumns());
+ rs.setKeyColumns(pkeys);
+ assertEquals(rs.getKeyColumns(), pkeys);
+ rs.close();
+ }
+
+ /*
+ * Validate that setMatchColumn throws a SQLException if the column
+ * index specified is out of range
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0012(CachedRowSet rs) throws Exception {
+ rs.setMatchColumn(-1);
+ rs.close();
+ }
+
+ /*
+ * Validate that setMatchColumn throws a SQLException if the column
+ * index specified is out of range
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0013(CachedRowSet rs) throws Exception {
+ int[] cols = {1, -1};
+ rs.setMatchColumn(cols);
+ rs.close();
+ }
+
+ /*
+ * Validate that setMatchColumn throws a SQLException if the column
+ * index specified is out of range
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0014(CachedRowSet rs) throws Exception {
+ rs.setMatchColumn((String) null);
+ rs.close();
+ }
+
+ /*
+ * Validate that setMatchColumn throws a SQLException if the column
+ * index specified is out of range
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0015(CachedRowSet rs) throws Exception {
+ String[] cols = {"ID", null};
+ rs.setMatchColumn(cols);
+ }
+
+ /*
+ * Validate that getMatchColumn returns the same value specified by
+ * setMatchColumn
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false)
+ public void commonCachedRowSetTest0016(CachedRowSet rs) throws Exception {
+ int[] expectedCols = {1};
+ String[] expectedColNames = {"ID"};
+ rs.setMatchColumn(1);
+ int[] actualCols = rs.getMatchColumnIndexes();
+ String[] actualColNames = rs.getMatchColumnNames();
+ for (int i = 0; i < actualCols.length; i++) {
+ System.out.println(actualCols[i]);
+ }
+ assertEquals(actualCols, expectedCols);
+ assertEquals(actualColNames, expectedColNames);
+ rs.close();
+ }
+
+ /*
+ * Validate that getMatchColumn returns the same value specified by
+ * setMatchColumn
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false)
+ public void commonCachedRowSetTest0017(CachedRowSet rs) throws Exception {
+ int[] expectedCols = {1};
+ String[] expectedColNames = {"ID"};
+ rs.setMatchColumn(expectedColNames[0]);
+ int[] actualCols = rs.getMatchColumnIndexes();
+ String[] actualColNames = rs.getMatchColumnNames();
+ assertEquals(actualCols, expectedCols);
+ assertEquals(actualColNames, expectedColNames);
+ rs.close();
+ }
+
+ /*
+ * Validate that getMatchColumn returns the same valid value specified by
+ * setMatchColumn
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false)
+ public void commonCachedRowSetTest0018(CachedRowSet rs) throws Exception {
+ int[] expectedCols = {1, 3};
+ String[] expectedColNames = {"COF_ID", "SUP_ID"};
+ rs.setMatchColumn(expectedCols);
+ int[] actualCols = rs.getMatchColumnIndexes();
+ String[] actualColNames = rs.getMatchColumnNames();
+ assertEquals(actualCols, expectedCols);
+ assertEquals(actualColNames, expectedColNames);
+ assertEquals(actualCols, expectedCols);
+ rs.close();
+ }
+
+ /*
+ * Validate that getMatchColumn returns the same valid value specified by
+ * setMatchColumn
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false)
+ public void commonCachedRowSetTest0019(CachedRowSet rs) throws Exception {
+ int[] expectedCols = {1, 3};
+ String[] expectedColNames = {"COF_ID", "SUP_ID"};
+ rs.setMatchColumn(expectedColNames);
+ int[] actualCols = rs.getMatchColumnIndexes();
+ String[] actualColNames = rs.getMatchColumnNames();
+ assertEquals(actualCols, expectedCols);
+ assertEquals(actualColNames, expectedColNames);
+ rs.close();
+ }
+
+ /*
+ * Validate that getMatchColumnIndexes throws a SQLException if
+ * unsetMatchColumn has been called
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0020(CachedRowSet rs) throws Exception {
+ rs.setMatchColumn(1);
+ int[] actualCols = rs.getMatchColumnIndexes();
+ assertTrue(actualCols != null);
+ rs.unsetMatchColumn(1);
+ actualCols = rs.getMatchColumnIndexes();
+ rs.close();
+ }
+
+ /*
+ * Validate that getMatchColumnNames throws a SQLException if
+ * unsetMatchColumn has been called
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0021(CachedRowSet rs) throws Exception {
+ String matchColumn = "ID";
+ rs.setMatchColumn(matchColumn);
+ String[] actualColNames = rs.getMatchColumnNames();
+ assertTrue(actualColNames != null);
+ rs.unsetMatchColumn(matchColumn);
+ actualColNames = rs.getMatchColumnNames();
+ rs.close();
+ }
+
+ /*
+ * Validate that getMatchColumnIndexes throws a SQLException if
+ * unsetMatchColumn has been called
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0022(CachedRowSet rs) throws Exception {
+ int[] expectedCols = {1, 3};
+ rs.setMatchColumn(expectedCols);
+ int[] actualCols = rs.getMatchColumnIndexes();
+ assertTrue(actualCols != null);
+ rs.unsetMatchColumn(expectedCols);
+ actualCols = rs.getMatchColumnIndexes();
+ rs.close();
+ }
+
+ /*
+ * Validate that getMatchColumnNames throws a SQLException if
+ * unsetMatchColumn has been called
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0023(CachedRowSet rs) throws Exception {
+ String[] expectedColNames = {"COF_ID", "SUP_ID"};
+ rs.setMatchColumn(expectedColNames);
+ String[] actualColNames = rs.getMatchColumnNames();
+ assertTrue(actualColNames != null);
+ rs.unsetMatchColumn(expectedColNames);
+ actualColNames = rs.getMatchColumnNames();
+ rs.close();
+ }
+
+ /*
+ * Validate size() returns the correct number of rows
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0024(CachedRowSet rs) throws Exception {
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
+ rs.close();
+ }
+
+ /*
+ * Validate that the correct rows are returned comparing the primary
+ * keys
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0025(RowSet rs) throws SQLException {
+ assertEquals(getPrimaryKeys(rs), COFFEE_HOUSES_PRIMARY_KEYS);
+ rs.close();
+ }
+
+ /*
+ * Delete a row within the RowSet using its primary key
+ * Validate the visibility of the row depending on the value of
+ * setShowdelete
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0026(CachedRowSet rs) throws Exception {
+ Object[] afterDelete = {
+ 10023, 33002, 10040, 32001, 10042, 10024, 10039, 10041,
+ 33005, 33010, 10037, 10034, 32004
+ };
+ int rowToDelete = 10035;
+ // All rows should be found
+ assertEquals(getPrimaryKeys(rs), COFFEE_HOUSES_PRIMARY_KEYS);
+ // Delete the row
+ assertTrue(deleteRowByPrimaryKey(rs, rowToDelete, 1));
+ // With setShowDeleted(false) which is the default,
+ // the deleted row should not be visible
+ assertFalse(findRowByPrimaryKey(rs, rowToDelete, 1));
+ assertEquals(getPrimaryKeys(rs), afterDelete);
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
+ // With setShowDeleted(true), the deleted row should be visible
+ rs.setShowDeleted(true);
+ assertTrue(findRowByPrimaryKey(rs, rowToDelete, 1));
+ rs.close();
+ }
+
+ /*
+ * Validate that there is no page size by default
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonCachedRowSetTest0027(CachedRowSet rs) throws Exception {
+ assertTrue(rs.getPageSize() == 0);
+ rs.close();
+ }
+
+ /*
+ * Validate the value you set via setPageSize is returned by getPageSize
+ * then reset to having no limit
+ */
+ @Test(dataProvider = "rowSetType")
+ public void commonCachedRowSetTest0028(CachedRowSet rs) throws Exception {
+ int rows = 100;
+ rs.setPageSize(rows);
+ assertTrue(rows == rs.getPageSize());
+ rs.setPageSize(0);
+ assertTrue(rs.getPageSize() == 0);
+ rs.close();
+ }
+
+ /*
+ * Validate SQLException is thrown when an invalid value is specified
+ * for setPageSize
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0029(CachedRowSet rs) throws Exception {
+ rs.setPageSize(-1);
+ rs.close();
+ }
+
+ /*
+ * Validate SQLException is thrown when nextPage is called without a
+ * call to populate or execute
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0030(CachedRowSet rs) throws Exception {
+ rs.nextPage();
+ rs.close();
+ }
+
+ /*
+ * Validate SQLException is thrown when previousPage is called without a
+ * call to populate or execute
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0031(CachedRowSet rs) throws Exception {
+ rs.previousPage();
+ rs.close();
+ }
+
+
+ /*
+ * Validate SQLException is thrown when execute is called
+ * but there is not a way to make a connection to the datasource
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0032(CachedRowSet rs) throws Exception {
+ rs.execute(null);
+ rs.close();
+ }
+
+ /*
+ * Validate SQLException is thrown when execute is called
+ * but there is not a way to make a connection to the datasource
+ */
+ @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0033(CachedRowSet rs) throws Exception {
+ rs.execute();
+ rs.close();
+ }
+
+ /*
+ * Validate that toCollection(<column>) returns the proper values
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0034(CachedRowSet rs) throws Exception {
+ Object[] cities = {"Mendocino", "Seattle", "SF", "Portland", "SF",
+ "Sacramento", "Carmel", "LA", "Olympia", "Seattle", "SF",
+ "LA", "San Jose", "Eugene"};
+ rs.beforeFirst();
+ assertEquals(rs.toCollection(2).toArray(), cities);
+ assertEquals(rs.toCollection("CITY").toArray(), cities);
+ rs.close();
+ }
+
+ /*
+ * Validate that toCollection() returns the proper values
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0035(CachedRowSet rs) throws Exception {
+ Collection<?> col = rs.toCollection();
+ assertTrue(rs.size() == col.size());
+ assertTrue(rs.toCollection().containsAll(col)
+ && col.containsAll(rs.toCollection()));
+ try ( // Validate that False is returned when compared to a different RowSet;
+ CachedRowSet crs1 = createCoffeesRowSet()) {
+ assertFalse(crs1.toCollection().containsAll(col)
+ && col.containsAll(crs1.toCollection()));
+ }
+ rs.close();
+
+ }
+
+ /*
+ * Validate that createCopy() returns the proper values
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0036(CachedRowSet rs) throws Exception {
+ try (CachedRowSet crs1 = rs.createCopy()) {
+ compareRowSets(rs, crs1);
+ }
+ rs.close();
+ }
+
+ /*
+ * Validate that createCopySchema() returns the proper values
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0037(CachedRowSet rs) throws Exception {
+ try (CachedRowSet crs1 = rs.createCopySchema()) {
+ assertTrue(crs1.size() == 0);
+ compareMetaData(crs1.getMetaData(), rs.getMetaData());
+ }
+ rs.close();
+ }
+
+ /*
+ * Validate that createCopyNoConstraints() returns the proper values
+ * and getMatchColumnIndexes should throw a SQLException. This test
+ * specifies setMatchColumn(int)
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0038(CachedRowSet rs) throws Exception {
+ rs.setMatchColumn(1);
+ try (CachedRowSet crs1 = rs.createCopyNoConstraints()) {
+ assertTrue(crs1.size() == COFFEE_HOUSES_ROWS);
+ compareRowSets(rs, crs1);
+ boolean recievedSQE = false;
+ try {
+ int[] indexes = crs1.getMatchColumnIndexes();
+ } catch (SQLException e) {
+ recievedSQE = true;
+ }
+ assertTrue(recievedSQE);
+ recievedSQE = false;
+ try {
+ String[] colNames = crs1.getMatchColumnNames();
+ } catch (SQLException e) {
+ recievedSQE = true;
+ }
+ assertTrue(recievedSQE);
+ }
+ rs.close();
+ }
+
+ /*
+ * Validate that createCopyNoConstraints() returns the proper values
+ * and getMatchColumnIndexes should throw a SQLException. This test
+ * specifies setMatchColumn(String)
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0039(CachedRowSet rs) throws Exception {
+ rs.setMatchColumn("ID");
+ try (CachedRowSet crs1 = rs.createCopyNoConstraints()) {
+ assertTrue(crs1.size() == COFFEE_HOUSES_ROWS);
+ compareRowSets(rs, crs1);
+ boolean recievedSQE = false;
+ try {
+ int[] indexes = crs1.getMatchColumnIndexes();
+ } catch (SQLException e) {
+ recievedSQE = true;
+ }
+ assertTrue(recievedSQE);
+ recievedSQE = false;
+ try {
+ String[] colNames = crs1.getMatchColumnNames();
+ } catch (SQLException e) {
+ recievedSQE = true;
+ }
+ assertTrue(recievedSQE);
+ }
+ rs.close();
+ }
+
+ /*
+ * Validate that columnUpdated works with the various datatypes specifying
+ * the column index
+ */
+ @Test(dataProvider = "rowsetUsingDataTypes")
+ public void commonCachedRowSetTest0040(CachedRowSet rs, JDBCType type) throws Exception {
+ rs.beforeFirst();
+ assertTrue(rs.next());
+ switch (type) {
+ case INTEGER:
+ assertFalse(rs.columnUpdated(1));
+ rs.updateInt(1, Integer.MIN_VALUE);
+ assertTrue(rs.columnUpdated(1));
+ break;
+ case CHAR:
+ assertFalse(rs.columnUpdated(2));
+ rs.updateString(2, "foo");
+ assertTrue(rs.columnUpdated(2));
+ break;
+ case VARCHAR:
+ assertFalse(rs.columnUpdated(3));
+ rs.updateString(3, "foo");
+ assertTrue(rs.columnUpdated(3));
+ break;
+ case BIGINT:
+ assertFalse(rs.columnUpdated(4));
+ rs.updateLong(4, Long.MIN_VALUE);
+ assertTrue(rs.columnUpdated(4));
+ break;
+ case BOOLEAN:
+ assertFalse(rs.columnUpdated(5));
+ rs.updateBoolean(5, false);
+ assertTrue(rs.columnUpdated(5));
+ break;
+ case SMALLINT:
+ assertFalse(rs.columnUpdated(6));
+ rs.updateShort(6, Short.MIN_VALUE);
+ assertTrue(rs.columnUpdated(6));
+ break;
+ case DOUBLE:
+ assertFalse(rs.columnUpdated(7));
+ rs.updateDouble(7, Double.MIN_VALUE);
+ assertTrue(rs.columnUpdated(7));
+ break;
+ case DECIMAL:
+ assertFalse(rs.columnUpdated(8));
+ rs.updateBigDecimal(8, BigDecimal.TEN);
+ assertTrue(rs.columnUpdated(8));
+ break;
+ case REAL:
+ assertFalse(rs.columnUpdated(9));
+ rs.updateFloat(9, Float.MIN_VALUE);
+ assertTrue(rs.columnUpdated(9));
+ break;
+ case TINYINT:
+ assertFalse(rs.columnUpdated(10));
+ rs.updateByte(10, Byte.MIN_VALUE);
+ assertTrue(rs.columnUpdated(10));
+ break;
+ case DATE:
+ assertFalse(rs.columnUpdated(11));
+ rs.updateDate(11, Date.valueOf(LocalDate.now()));
+ assertTrue(rs.columnUpdated(11));
+ break;
+ case TIME:
+ assertFalse(rs.columnUpdated(12));
+ rs.updateTime(12, Time.valueOf(LocalTime.now()));
+ assertTrue(rs.columnUpdated(12));
+ break;
+ case TIMESTAMP:
+ assertFalse(rs.columnUpdated(13));
+ rs.updateTimestamp(13, Timestamp.valueOf(LocalDateTime.now()));
+ assertTrue(rs.columnUpdated(13));
+ break;
+ case VARBINARY:
+ assertFalse(rs.columnUpdated(14));
+ rs.updateBytes(14, new byte[1]);
+ assertTrue(rs.columnUpdated(14));
+ break;
+ case ARRAY:
+ assertFalse(rs.columnUpdated(15));
+ rs.updateArray(15, new StubArray("VARCHAR", new Object[10]));
+ assertTrue(rs.columnUpdated(15));
+ break;
+ case REF:
+ assertFalse(rs.columnUpdated(16));
+ rs.updateRef(16, new StubRef("INTEGER", query));
+ assertTrue(rs.columnUpdated(16));
+ break;
+ case FLOAT:
+ assertFalse(rs.columnUpdated(17));
+ rs.updateDouble(17, Double.MIN_NORMAL);
+ assertTrue(rs.columnUpdated(17));
+ }
+
+ }
+
+ /*
+ * Validate that columnUpdated works with the various datatypes specifying
+ * the column name
+ */
+ @Test(dataProvider = "rowsetUsingDataTypes")
+ public void commonCachedRowSetTest0041(CachedRowSet rs, JDBCType type) throws Exception {
+ rs.beforeFirst();
+ assertTrue(rs.next());
+ switch (type) {
+ case INTEGER:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[0]));
+ rs.updateInt(DATATYPES_COLUMN_NAMES[0], Integer.MIN_VALUE);
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[0]));
+ break;
+ case CHAR:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[1]));
+ rs.updateString(DATATYPES_COLUMN_NAMES[1], "foo");
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[1]));
+ break;
+ case VARCHAR:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[2]));
+ rs.updateString(DATATYPES_COLUMN_NAMES[2], "foo");
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[2]));
+ break;
+ case BIGINT:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[3]));
+ rs.updateLong(DATATYPES_COLUMN_NAMES[3], Long.MIN_VALUE);
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[3]));
+ break;
+ case BOOLEAN:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[4]));
+ rs.updateBoolean(DATATYPES_COLUMN_NAMES[4], false);
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[4]));
+ break;
+ case SMALLINT:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[5]));
+ rs.updateShort(DATATYPES_COLUMN_NAMES[5], Short.MIN_VALUE);
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[5]));
+ break;
+ case DOUBLE:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[6]));
+ rs.updateDouble(DATATYPES_COLUMN_NAMES[6], Double.MIN_VALUE);
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[6]));
+ break;
+ case DECIMAL:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[7]));
+ rs.updateBigDecimal(DATATYPES_COLUMN_NAMES[7], BigDecimal.TEN);
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[7]));
+ break;
+ case REAL:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[8]));
+ rs.updateFloat(DATATYPES_COLUMN_NAMES[8], Float.MIN_VALUE);
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[8]));
+ break;
+ case TINYINT:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[9]));
+ rs.updateByte(DATATYPES_COLUMN_NAMES[9], Byte.MIN_VALUE);
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[9]));
+ break;
+ case DATE:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[10]));
+ rs.updateDate(DATATYPES_COLUMN_NAMES[10], Date.valueOf(LocalDate.now()));
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[10]));
+ break;
+ case TIME:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[11]));
+ rs.updateTime(DATATYPES_COLUMN_NAMES[11], Time.valueOf(LocalTime.now()));
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[11]));
+ break;
+ case TIMESTAMP:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[12]));
+ rs.updateTimestamp(DATATYPES_COLUMN_NAMES[12], Timestamp.valueOf(LocalDateTime.now()));
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[12]));
+ break;
+ case VARBINARY:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[13]));
+ rs.updateBytes(DATATYPES_COLUMN_NAMES[13], new byte[1]);
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[13]));
+ break;
+ case ARRAY:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[14]));
+ rs.updateArray(DATATYPES_COLUMN_NAMES[14], new StubArray("VARCHAR", new Object[10]));
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[14]));
+ break;
+ case REF:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[15]));
+ rs.updateRef(DATATYPES_COLUMN_NAMES[15], new StubRef("INTEGER", query));
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[15]));
+ break;
+ case FLOAT:
+ assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[16]));
+ rs.updateDouble(DATATYPES_COLUMN_NAMES[16], Double.MIN_NORMAL);
+ assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[16]));
+ break;
+ }
+
+ }
+
+ /*
+ * Validate isBeforeFirst(), isFirst() and first() return the correct
+ * results
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0042(RowSet rs) throws Exception {
+ assertFalse(rs.isBeforeFirst());
+ assertFalse(rs.isFirst());
+ rs.beforeFirst();
+ assertTrue(rs.isBeforeFirst());
+ assertFalse(rs.isFirst());
+ rs.next();
+ assertFalse(rs.isBeforeFirst());
+ assertTrue(rs.isFirst());
+ rs.next();
+ assertFalse(rs.isBeforeFirst());
+ assertFalse(rs.isFirst());
+ rs.first();
+ assertFalse(rs.isBeforeFirst());
+ assertTrue(rs.isFirst());
+ rs.close();
+ }
+
+ /*
+ * Validate isAfterLast(), isLast() and last() return the correct
+ * results
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0043(RowSet rs) throws Exception {
+ assertFalse(rs.isAfterLast());
+ assertFalse(rs.isLast());
+ rs.afterLast();
+ assertTrue(rs.isAfterLast());
+ assertFalse(rs.isLast());
+ rs.previous();
+ assertFalse(rs.isAfterLast());
+ assertTrue(rs.isLast());
+ rs.previous();
+ assertFalse(rs.isAfterLast());
+ assertFalse(rs.isLast());
+ rs.last();
+ assertFalse(rs.isAfterLast());
+ assertTrue(rs.isLast());
+ rs.close();
+ }
+
+ /*
+ * Validate a SQLException is thrown when undoDelete is called on the
+ * insertRow
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0044(CachedRowSet rs) throws Exception {
+ rs.insertRow();
+ rs.undoDelete();
+ rs.close();
+ }
+
+ /*
+ * Validate a SQLException is thrown when undoDelete is called when
+ * cursor is before the first row
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0045(CachedRowSet rs) throws Exception {
+ rs.setShowDeleted(true);
+ rs.beforeFirst();
+ rs.undoDelete();
+ rs.close();
+ }
+
+ /*
+ * Validate a SQLException is thrown when undoDelete is called when
+ * cursor is after the last row
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0046(CachedRowSet rs) throws Exception {
+ rs.setShowDeleted(true);
+ rs.afterLast();
+ rs.undoDelete();
+ rs.close();
+ }
+
+ /*
+ * Validate a SQLException is thrown when undoUpdate is called on the
+ * insertRow
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0047(CachedRowSet rs) throws Exception {
+ rs.insertRow();
+ rs.undoUpdate();
+ rs.close();
+ }
+
+ /*
+ * Validate a SQLException is thrown when undoUpdate is called when
+ * cursor is before the first row
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0048(CachedRowSet rs) throws Exception {
+ rs.setShowDeleted(true);
+ rs.beforeFirst();
+ rs.undoUpdate();
+ rs.close();
+ }
+
+ /*
+ * Validate a SQLException is thrown when undoUpdate is called when
+ * cursor is after the last row
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0049(CachedRowSet rs) throws Exception {
+ rs.setShowDeleted(true);
+ rs.afterLast();
+ rs.undoUpdate();
+ rs.close();
+ }
+
+ /*
+ * Validate a SQLException is thrown when undoInsert is called on the
+ * insertRow
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0050(CachedRowSet rs) throws Exception {
+ rs.insertRow();
+ rs.undoInsert();
+ rs.close();
+ }
+
+ /*
+ * Validate a SQLException is thrown when undoInsert is called when
+ * cursor is before the first row
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0051(CachedRowSet rs) throws Exception {
+ rs.setShowDeleted(true);
+ rs.beforeFirst();
+ rs.undoInsert();
+ rs.close();
+ }
+
+ /*
+ * Validate a SQLException is thrown when undoInsert is called when
+ * cursor is after the last row
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses",
+ expectedExceptions = SQLException.class)
+ public void commonCachedRowSetTest0052(CachedRowSet rs) throws Exception {
+ rs.setShowDeleted(true);
+ rs.afterLast();
+ rs.undoInsert();
+ rs.close();
+ }
+
+ /*
+ * Insert a row, then call undoInsert to roll back the insert and validate
+ * the row is not there
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0053(CachedRowSet rs) throws Exception {
+ int rowToInsert = 1961;
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
+ // Add new row
+ rs.moveToInsertRow();
+ rs.updateInt(1, rowToInsert);
+ rs.updateString(2, "GOTHAM");
+ rs.updateInt(3, 3450);
+ rs.updateInt(4, 2005);
+ rs.updateInt(5, 5455);
+ rs.insertRow();
+ rs.moveToCurrentRow();
+ // check that the number of rows has increased
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS + 1);
+ assertTrue(findRowByPrimaryKey(rs, rowToInsert, 1));
+ rs.undoInsert();
+ // Check to make sure the row is no longer there
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
+ assertFalse(findRowByPrimaryKey(rs, rowToInsert, 1));
+ rs.close();
+ }
+
+ /*
+ * Insert a row, delete the row and then call undoDelete to make sure it
+ * is comes back
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0054(CachedRowSet rs) throws Exception {
+ int rowToDelete = 1961;
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
+ // Add new row
+ rs.moveToInsertRow();
+ rs.updateInt(1, rowToDelete);
+ rs.updateString(2, "GOTHAM");
+ rs.updateInt(3, 3450);
+ rs.updateInt(4, 2005);
+ rs.updateInt(5, 5455);
+ rs.insertRow();
+ rs.moveToCurrentRow();
+ // check that the number of rows has increased
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS + 1);
+ assertTrue(findRowByPrimaryKey(rs, rowToDelete, 1));
+ rs.absolute(COFFEE_HOUSES_ROWS + 1);
+ rs.deleteRow();
+ // Check to make sure the row is no longer there
+ //assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
+ assertFalse(findRowByPrimaryKey(rs, rowToDelete, 1));
+ rs.setShowDeleted(true);
+ rs.absolute(COFFEE_HOUSES_ROWS + 1);
+ rs.undoDelete();
+ // check that the row is back
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS + 1);
+ assertTrue(findRowByPrimaryKey(rs, rowToDelete, 1));
+ rs.close();
+ }
+
+ /*
+ * Insert a row, modify a field and then call undoUpdate to revert the
+ * insert
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0055(CachedRowSet rs) throws Exception {
+ int rowToInsert = 1961;
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
+ // Add new row
+ rs.moveToInsertRow();
+ rs.updateInt(1, rowToInsert);
+ rs.updateString(2, "GOTHAM");
+ rs.updateInt(3, 3450);
+ rs.updateInt(4, 2005);
+ rs.updateInt(5, 5455);
+ rs.insertRow();
+ rs.moveToCurrentRow();
+ // check that the number of rows has increased
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS + 1);
+ assertTrue(findRowByPrimaryKey(rs, rowToInsert, 1));
+ rs.absolute(COFFEE_HOUSES_ROWS + 1);
+ // Save off the original column values
+ String f2 = rs.getString(2);
+ int f3 = rs.getInt(3);
+ rs.updateString(2, "SMALLVILLE");
+ rs.updateInt(3, 500);
+ // Validate the columns have been updated
+ assertTrue(rs.columnUpdated(2));
+ assertTrue(rs.columnUpdated(3));
+ // Undo the update and validate it has taken place
+ rs.absolute(COFFEE_HOUSES_ROWS + 1);
+ rs.undoUpdate();
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
+ assertFalse(findRowByPrimaryKey(rs, rowToInsert, 1));
+ rs.close();
+ }
+
+ /*
+ * Validate getOriginal returns a ResultSet which is a copy of the original
+ * RowSet
+ */
+ @Test(dataProvider = "rowsetUsingCoffees")
+ public void commonCachedRowSetTest0056(CachedRowSet rs) throws Exception {
+ String coffee = "Hazelnut";
+ int sales = 100;
+ int id = 200;
+ Object[] updatedPkeys = {1, id, 3, 4, 5};
+ // Change the coffee name and sales total for row 2 and save the
+ // previous values
+ rs.absolute(2);
+ int origId = rs.getInt(1);
+ String origCoffee = rs.getString(2);
+ int origSales = rs.getInt(5);
+ rs.updateInt(1, id);
+ rs.updateString(2, coffee);
+ rs.updateInt(5, sales);
+ // MetaData should match
+ try ( // Get the original original RowSet and validate that the changes
+ // are only made to the current, not the original
+ ResultSet rs1 = rs.getOriginal()) {
+ // MetaData should match
+ compareMetaData(rs.getMetaData(), rs1.getMetaData());
+ assertTrue(rs1.isBeforeFirst());
+ assertTrue(rs1.getConcurrency() == ResultSet.CONCUR_UPDATABLE);
+ assertTrue(rs1.getType() == ResultSet.TYPE_SCROLL_INSENSITIVE);
+ rs1.absolute(2);
+ // Check original rowset is not changed
+ assertTrue(rs1.getInt(1) == origId);
+ assertTrue(rs1.getString(2).equals(origCoffee));
+ assertTrue(rs1.getInt(5) == origSales);
+ assertEquals(getPrimaryKeys(rs1), COFFEES_PRIMARY_KEYS);
+ // Check current rowset
+ assertTrue(rs.getInt(1) == id);
+ assertTrue(rs.getString(2).equals(coffee));
+ assertTrue(rs.getInt(5) == sales);
+ assertEquals(getPrimaryKeys(rs), updatedPkeys);
+ }
+ rs.close();
+ }
+
+ /*
+ * Validate getOriginalRow returns a ResultSet which is a copy of the
+ * original row that was modified
+ */
+ @Test(dataProvider = "rowsetUsingCoffees")
+ public void commonCachedRowSetTest0057(CachedRowSet rs) throws Exception {
+ String coffee = "Hazelnut";
+ int sales = 100;
+ int id = 200;
+ Object[] updatedPkeys = {1, id, 3, 4, 5};
+ // Change the coffee name and sales total for row 2 and save the
+ // previous values
+ rs.absolute(2);
+ int origId = rs.getInt(1);
+ String origCoffee = rs.getString(2);
+ int origSales = rs.getInt(5);
+ rs.updateInt(1, id);
+ rs.updateString(2, coffee);
+ rs.updateInt(5, sales);
+ // MetaData should match
+ try ( // Get the original original row and validate that the changes
+ // are only made to the current, not the original
+ ResultSet rs1 = rs.getOriginalRow()) {
+ // MetaData should match
+ compareMetaData(rs.getMetaData(), rs1.getMetaData());
+ assertTrue(rs1.isBeforeFirst());
+ assertTrue(rs1.getConcurrency() == ResultSet.CONCUR_UPDATABLE);
+ assertTrue(rs1.getType() == ResultSet.TYPE_SCROLL_INSENSITIVE);
+ rs1.next();
+ assertTrue(rs1.isFirst() && rs1.isLast());
+ assertTrue(rs1.getRow() == 1);
+ // Check original row is not changed
+ assertTrue(rs1.getInt(1) == origId);
+ assertTrue(rs1.getString(2).equals(origCoffee));
+ assertTrue(rs1.getInt(5) == origSales);
+ // Check current row
+ assertTrue(rs.getInt(1) == id);
+ assertTrue(rs.getString(2).equals(coffee));
+ assertTrue(rs.getInt(5) == sales);
+ assertEquals(getPrimaryKeys(rs), updatedPkeys);
+ }
+ rs.close();
+ }
+
+ /*
+ * Validate that restoreOrginal will restore the RowSet to its
+ * state prior to the insert of a row
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0058(CachedRowSet rs) throws Exception {
+ int rowToInsert = 1961;
+ assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
+ try ( // Add new row
+ CachedRowSet crs1 = rsf.createCachedRowSet()) {
+ rs.beforeFirst();
+ crs1.populate(rs);
+ TestRowSetListener rsl = new TestRowSetListener();
+ crs1.addRowSetListener(rsl);
+ crs1.moveToInsertRow();
+ crs1.updateInt(1, rowToInsert);
+ crs1.updateString(2, "GOTHAM");
+ crs1.updateInt(3, 3450);
+ crs1.updateInt(4, 2005);
+ crs1.updateInt(5, 5455);
+ crs1.insertRow();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
+ crs1.moveToCurrentRow();
+ assertTrue(findRowByPrimaryKey(crs1, rowToInsert, 1));
+ // Restore back to our original state and the
+ // previously inserted row should not be there
+ rsl.resetFlag();
+ crs1.restoreOriginal();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
+ assertTrue(crs1.isBeforeFirst());
+ crs1.last();
+ assertFalse(crs1.rowInserted());
+ assertFalse(findRowByPrimaryKey(crs1, rowToInsert, 1));
+ }
+ rs.close();
+ }
+
+ /*
+ * Validate that restoreOrginal will restore the RowSet to its
+ * state prior to deleting a row
+ */
+ @Test(dataProvider = "rowsetUsingCoffees", enabled = true)
+ public void commonCachedRowSetTest0059(CachedRowSet rs) throws Exception {
+ int rowToDelete = 2;
+ try (CachedRowSet crs1 = rsf.createCachedRowSet()) {
+ rs.beforeFirst();
+ crs1.populate(rs);
+ TestRowSetListener rsl = new TestRowSetListener();
+ crs1.addRowSetListener(rsl);
+ // Delete a row, the PK is also the absolute position as a List
+ // backs the RowSet
+ crs1.absolute(rowToDelete);
+ crs1.deleteRow();
+ assertTrue(crs1.rowDeleted());
+ assertFalse(findRowByPrimaryKey(crs1, rowToDelete, 1));
+ // Restore back to our original state and the
+ // previously deleted row should be there
+ rsl.resetFlag();
+ crs1.restoreOriginal();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
+ assertTrue(crs1.isBeforeFirst());
+ crs1.absolute(rowToDelete);
+ assertFalse(crs1.rowDeleted());
+ assertTrue(findRowByPrimaryKey(crs1, rowToDelete, 1));
+ }
+ rs.close();
+ }
+
+ /*
+ * Validate that restoreOrginal will restore the RowSet to its
+ * state prior to updating a row
+ */
+ @Test(dataProvider = "rowsetUsingCoffees", enabled = true)
+ public void commonCachedRowSetTest0060(CachedRowSet rs) throws Exception {
+ int rowToUpdate = 2;
+ String coffee = "Hazelnut";
+ try (CachedRowSet crs1 = rsf.createCachedRowSet()) {
+ rs.beforeFirst();
+ crs1.populate(rs);
+ TestRowSetListener rsl = new TestRowSetListener();
+ crs1.addRowSetListener(rsl);
+ // Delete a row, the PK is also the absolute position as a List
+ // backs the RowSet
+ crs1.absolute(rowToUpdate);
+ String origCoffee = crs1.getString(2);
+ crs1.updateString(2, coffee);
+ assertTrue(crs1.columnUpdated(2));
+ crs1.updateRow();
+ assertTrue(crs1.rowUpdated());
+ assertFalse(origCoffee.equals(crs1.getString(2)));
+ // Restore back to our original state and the
+ // previous value for the column within the row should be there
+ rsl.resetFlag();
+ crs1.restoreOriginal();
+ assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
+ assertTrue(crs1.isBeforeFirst());
+ // absolute() is failing for some reason so need to look at this later
+ crs1.next();
+ crs1.next();
+ assertFalse(crs1.columnUpdated(2));
+ assertFalse(crs1.rowUpdated());
+ assertTrue(origCoffee.equals(crs1.getString(2)));
+ }
+ rs.close();
+ }
+
+ /*
+ * Initialize a RowSet via the populate method. Validate it matches
+ * the original ResultSet
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0061(CachedRowSet rs) throws Exception {
+ try (CachedRowSet crs1 = rsf.createCachedRowSet()) {
+ rs.beforeFirst();
+ crs1.populate(rs);
+ compareRowSets(rs, crs1);
+ }
+ rs.close();
+ }
+
+ /*
+ * Initialize a RowSet via the populate method specifying a starting row.
+ * Validate it matches the original ResultSet starting for the specofied
+ * offset
+ */
+ @Test(dataProvider = "rowsetUsingCoffeeHouses")
+ public void commonCachedRowSetTest0062(CachedRowSet rs) throws Exception {
+ Object[] expectedRows = {
+ 32001, 10042, 10024, 10039, 10041, 33005, 33010, 10035, 10037,
+ 10034, 32004
+ };
+ int startingRow = 4;
+ try (CachedRowSet crs1 = rsf.createCachedRowSet()) {
+ rs.beforeFirst();
+ crs1.populate(rs, startingRow);
+ assertEquals(crs1.size(), COFFEE_HOUSES_ROWS - startingRow + 1);
+ assertEquals(getPrimaryKeys(crs1), expectedRows);
+ }
+ rs.close();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/test/rowset/filteredrowset/CityFilter.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,100 @@
+/*
+ * 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 test.rowset.filteredrowset;
+
+import java.sql.SQLException;
+import javax.sql.RowSet;
+import javax.sql.rowset.Predicate;
+
+/*
+ * Simple implementation of Predicate which is used to filter rows based
+ * on a City.
+ */
+public class CityFilter implements Predicate {
+
+ private final String[] cities;
+ private String colName = null;
+ private int colNumber = -1;
+
+ public CityFilter(String[] cities, String colName) {
+ this.cities = cities;
+ this.colName = colName;
+ }
+
+ public CityFilter(String[] cities, int colNumber) {
+ this.cities = cities;
+ this.colNumber = colNumber;
+ }
+
+ public boolean evaluate(Object value, String colName) {
+
+ if (colName.equalsIgnoreCase(this.colName)) {
+ for (String city : cities) {
+ if (city.equalsIgnoreCase((String) value)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean evaluate(Object value, int colNumber) {
+
+ if (colNumber == this.colNumber) {
+ for (String city : this.cities) {
+ if (city.equalsIgnoreCase((String) value)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean evaluate(RowSet rs) {
+
+ boolean result = false;
+
+ if (rs == null) {
+ return false;
+ }
+
+ try {
+ for (String city : cities) {
+
+ String val = "";
+ if (colNumber > 0) {
+ val = (String) rs.getObject(colNumber);
+ } else if (colName != null) {
+ val = (String) rs.getObject(colName);
+ }
+
+ if (val.equalsIgnoreCase(city)) {
+ return true;
+ }
+ }
+ } catch (SQLException e) {
+ result = false;
+ }
+ return result;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/test/rowset/filteredrowset/FilteredRowSetTests.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,140 @@
+/*
+ * 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 test.rowset.filteredrowset;
+
+import java.sql.SQLException;
+import javax.sql.RowSet;
+import javax.sql.rowset.FilteredRowSet;
+import javax.sql.rowset.Predicate;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import test.rowset.webrowset.CommonWebRowSetTests;
+
+public class FilteredRowSetTests extends CommonWebRowSetTests {
+
+ private FilteredRowSet frs;
+
+ @BeforeMethod
+ public void setUpMethod() throws Exception {
+ frs = createCoffeeHousesRowSet();
+ }
+
+ @AfterMethod
+ public void tearDownMethod() throws Exception {
+ frs.close();
+ }
+
+ protected FilteredRowSet newInstance() throws SQLException {
+ return rsf.createFilteredRowSet();
+ }
+
+ /*
+ * Validate getFilter returns null if setFilter has not been called
+ */
+ @Test
+ public void FilteredRowSetTest0000() throws SQLException {
+ assertNull(frs.getFilter());
+ }
+
+ /*
+ * Call setFilter to set a Predicate and validate that getFilter
+ * returns the correct Predicate
+ */
+ @Test
+ public void FilteredRowSetTest0001() throws SQLException {
+ Predicate p = new PrimaryKeyFilter(0, 100030, 1);
+ frs.setFilter(p);
+ assertTrue(frs.getFilter().equals(p));
+ frs.setFilter(null);
+ assertNull(frs.getFilter());
+ }
+
+ /*
+ * Validate that the correct rows are returned when a Predicate using
+ * a column index is used
+ */
+ @Test
+ public void FilteredRowSetTest0002() throws SQLException {
+ Object[] expectedKeys = {
+ 10023, 10040, 10042, 10024, 10039, 10041, 10035, 10037, 10034
+ };
+ frs.setFilter(new PrimaryKeyFilter(10000, 10999, 1));
+ assertEquals(getPrimaryKeys(frs), expectedKeys);
+ }
+
+ /*
+ * Validate that the correct rows are returned when a Predicate using
+ * a column Label is used
+ */
+ @Test
+ public void FilteredRowSetTest0003() throws SQLException {
+ Object[] expectedKeys = {
+ 10023, 10040, 10042, 10024, 10039, 10041, 10035, 10037, 10034
+ };
+ frs.setFilter(new PrimaryKeyFilter(10000, 10999, "STORE_ID"));
+ assertEquals(getPrimaryKeys(frs), expectedKeys);
+
+ }
+
+ /*
+ * Validate that the correct rows are returned when a Predicate using
+ * a column index is used
+ */
+ @Test
+ public void FilteredRowSetTest0004() throws SQLException {
+ Object[] expectedKeys = {
+ 10040, 10042, 10041, 10035, 10037
+ };
+ String[] cityArray = {"SF", "LA"};
+ frs.setFilter(new CityFilter(cityArray, 2));
+ assertEquals(getPrimaryKeys(frs), expectedKeys);
+ }
+
+ /*
+ * Validate that the correct rows are returned when a Predicate using
+ * a column Label is used
+ */
+ @Test
+ public void FilteredRowSetTest0005() throws SQLException {
+ Object[] expectedKeys = {
+ 10040, 10042, 10041, 10035, 10037
+ };
+ String[] cityArray = {"SF", "LA"};
+ frs.setFilter(new CityFilter(cityArray, "CITY"));
+ assertEquals(getPrimaryKeys(frs), expectedKeys);
+ }
+
+
+ // Tests that are common but need to be disabled due to an implementation bug
+
+
+ @Test(dataProvider = "rowSetType", enabled = false)
+ public void commonCachedRowSetTest0043(RowSet rs) throws Exception {
+ // Need to fix bug in FilteredRowSets
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/test/rowset/filteredrowset/PrimaryKeyFilter.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,93 @@
+/*
+ * 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 test.rowset.filteredrowset;
+
+import javax.sql.RowSet;
+import javax.sql.rowset.Predicate;
+
+/*
+ * Simple implementation of Predicate which is used to filter rows based
+ * on the Primary Key.
+ */
+public class PrimaryKeyFilter implements Predicate {
+
+ private final int lo;
+ private final int hi;
+ private String colName = null;
+ private int colNumber = -1;
+
+ public PrimaryKeyFilter(int lo, int hi, int colNumber) {
+ this.lo = lo;
+ this.hi = hi;
+ this.colNumber = colNumber;
+ }
+
+ public PrimaryKeyFilter(int lo, int hi, String colName) {
+ this.lo = lo;
+ this.hi = hi;
+ this.colName = colName;
+ }
+
+ public boolean evaluate(Object value, String columnName) {
+
+ boolean result = false;
+ if (columnName.equalsIgnoreCase(this.colName)) {
+ int columnValue = ((Integer) value);
+ result = (columnValue >= this.lo) && (columnValue <= this.hi);
+ }
+ return result;
+ }
+
+ public boolean evaluate(Object value, int columnNumber) {
+
+ boolean result = false;
+ if (this.colNumber == columnNumber) {
+ int columnValue = (Integer) value;
+ result = (columnValue >= this.lo) && (columnValue <= this.hi);
+ }
+ return result;
+ }
+
+ public boolean evaluate(RowSet rs) {
+
+ boolean result = false;
+ try {
+ int columnValue = -1;
+
+ if (this.colNumber > 0) {
+ columnValue = rs.getInt(this.colNumber);
+ } else if (this.colName != null) {
+ columnValue = rs.getInt(this.colName);
+ }
+ if ((columnValue >= this.lo) && (columnValue <= this.hi)) {
+ result = true;
+ }
+
+ } catch (Exception e) {
+ System.out.println("Error:" + e.getMessage());
+ result = false;
+ }
+ return result;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/test/rowset/joinrowset/JoinRowSetTests.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,324 @@
+/*
+ * 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 test.rowset.joinrowset;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.List;
+import javax.sql.RowSet;
+import javax.sql.rowset.CachedRowSet;
+import javax.sql.rowset.JoinRowSet;
+import javax.sql.rowset.RowSetMetaDataImpl;
+import javax.sql.rowset.WebRowSet;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import test.rowset.webrowset.CommonWebRowSetTests;
+
+public class JoinRowSetTests extends CommonWebRowSetTests {
+
+ private final String SUPPLIERS_TABLE = "SUPPLIERS";
+ // Expected COF_IDs to be found
+ private final Object[] EXPECTED = {4, 1};
+ // SUPPLIERS Primary Key to use to validate the joins
+ private final int SUP_ID = 101;
+ // Join Column between the SUPPLIERS and COFFEES table
+ private final String JOIN_COLNAME = "SUP_ID";
+ // Column index in COFFEES table which contains SUP_ID
+ private final int COFFEES_JOIN_COLUMN_INDEX = 3;
+ // Column index in SUPPLIERS table which contains SUP_ID
+ private final int SUPPLIERS_JOIN_COLUMN_INDEX = 1;
+
+ @Override
+ protected JoinRowSet newInstance() throws SQLException {
+ return rsf.createJoinRowSet();
+ }
+
+ /*
+ * Initializes the SUPPLIERS metadata
+ */
+ private void initSuppliersMetaData(CachedRowSet crs) throws SQLException {
+ RowSetMetaDataImpl rsmd = new RowSetMetaDataImpl();
+
+ /*
+ * CREATE TABLE SUPPLIERS (
+ * SUP_ID INTEGER NOT NULL,
+ * SUP_NAME VARCHAR(32) NOT NULL,
+ * STREET VARCHAR(32) NOT NULL,
+ * CITY VARCHAR(32) NOT NULL,
+ * STATE CHAR(2) NOT NULL,
+ * ZIP CHAR(5) NOT NULL,
+ * PRIMARY KEY (SUP_ID))
+ */
+ rsmd.setColumnCount(6);
+ rsmd.setColumnName(1, "SUP_ID");
+ rsmd.setColumnName(2, "SUP_NAME");
+ rsmd.setColumnName(3, "STREET");
+ rsmd.setColumnName(4, "CITY");
+ rsmd.setColumnName(5, "STATE");
+ rsmd.setColumnName(6, "ZIP");
+
+ rsmd.setColumnType(1, Types.INTEGER);
+ rsmd.setColumnType(2, Types.VARCHAR);
+ rsmd.setColumnType(3, Types.VARCHAR);
+ rsmd.setColumnType(4, Types.VARCHAR);
+ rsmd.setColumnType(5, Types.CHAR);
+ rsmd.setColumnType(6, Types.CHAR);
+ crs.setMetaData(rsmd);
+ crs.setTableName(SUPPLIERS_TABLE);
+ }
+
+ /*
+ * Add rows to SUPPLIERS table
+ */
+ protected void createSuppiersRows(RowSet rs) throws SQLException {
+
+ // insert into SUPPLIERS values(49, 'Superior Coffee', '1 Party Place',
+ // 'Mendocino', 'CA', '95460')
+ rs.moveToInsertRow();
+ rs.updateInt(1, 49);
+ rs.updateString(2, "Superior Coffee");
+ rs.updateString(3, "1 Party Place");
+ rs.updateString(4, "Mendocino");
+ rs.updateString(5, "CA");
+ rs.updateString(6, "95460");
+ rs.insertRow();
+
+ // insert into SUPPLIERS values(101, 'Acme, Inc.', '99 Market Street',
+ // 'Groundsville', 'CA', '95199')
+ rs.moveToInsertRow();
+ rs.updateInt(1, 101);
+ rs.updateString(2, "Acme, Inc.");
+ rs.updateString(3, "99 Market Street");
+ rs.updateString(4, "Groundsville");
+ rs.updateString(5, "CA");
+ rs.updateString(6, "95199");
+ rs.insertRow();
+ // insert into SUPPLIERS values(150, 'The High Ground',
+ // '100 Coffee Lane', 'Meadows', 'CA', '93966')
+ rs.moveToInsertRow();
+ rs.updateInt(1, 150);
+ rs.updateString(2, "The High Ground");
+ rs.updateString(3, "100 Coffee Lane");
+ rs.updateString(4, "Meadows");
+ rs.updateString(5, "CA");
+ rs.updateString(6, "93966");
+ rs.insertRow();
+ // insert into SUPPLIERS values(456," 'Restaurant Supplies, Inc.',
+ // '200 Magnolia Street', 'Meadows', 'CA', '93966')
+ rs.moveToInsertRow();
+ rs.updateInt(1, 456);
+ rs.updateString(2, "Restaurant Supplies, Inc.");
+ rs.updateString(3, "200 Magnolia Stree");
+ rs.updateString(4, "Meadows");
+ rs.updateString(5, "CA");
+ rs.updateString(6, "93966");
+ rs.insertRow();
+ // insert into SUPPLIERS values(927, 'Professional Kitchen',
+ // '300 Daisy Avenue', 'Groundsville'," 'CA', '95199')
+ rs.moveToInsertRow();
+ rs.updateInt(1, 927);
+ rs.updateString(2, "Professional Kitchen");
+ rs.updateString(3, "300 Daisy Avenue");
+ rs.updateString(4, "Groundsville");
+ rs.updateString(5, "CA");
+ rs.updateString(6, "95199");
+ rs.insertRow();
+ }
+
+ /*
+ * DataProvider used to set parameters for basic types that are supported
+ */
+ @DataProvider(name = "createCachedRowSetsToUse")
+ private Object[][] createCachedRowSetsToUse() throws SQLException {
+ CachedRowSet crs = rsf.createCachedRowSet();
+ initCoffeesMetaData(crs);
+ createCoffeesRows(crs);
+ // Make sure you are not on the insertRow
+ crs.moveToCurrentRow();
+ CachedRowSet crs1 = rsf.createCachedRowSet();
+ initSuppliersMetaData(crs1);
+ createSuppiersRows(crs1);
+ // Make sure you are not on the insertRow
+ crs1.moveToCurrentRow();
+ return new Object[][]{
+ {crs, crs1}
+ };
+ }
+
+ /*
+ * Validate that the correct coffees are returned for SUP_ID
+ */
+ private void validateResults(final JoinRowSet jrs) throws SQLException {
+ List<Integer> results = new ArrayList<>();
+ jrs.beforeFirst();
+ while (jrs.next()) {
+ if (jrs.getInt(JOIN_COLNAME) == SUP_ID) {
+ results.add(jrs.getInt("COF_ID"));
+ }
+ }
+ assertEquals(results.toArray(), EXPECTED);
+ }
+
+ /*
+ * Join two CachedRowSets specifying a column name to join against
+ */
+ @Test(dataProvider = "createCachedRowSetsToUse")
+ public void joinRowSetTests0000(CachedRowSet crs, CachedRowSet crs1)
+ throws Exception {
+
+ try (JoinRowSet jrs = newInstance()) {
+ jrs.addRowSet(crs, JOIN_COLNAME);
+ jrs.addRowSet(crs1, JOIN_COLNAME);
+ validateResults(jrs);
+ crs.close();
+ crs1.close();
+ }
+ }
+
+ /*
+ * Join two CachedRowSets specifying a column index to join against
+ */
+ @Test(dataProvider = "createCachedRowSetsToUse")
+ public void joinRowSetTests0001(CachedRowSet crs, CachedRowSet crs1)
+ throws Exception {
+
+ try (JoinRowSet jrs = newInstance()) {
+ jrs.addRowSet(crs, COFFEES_JOIN_COLUMN_INDEX);
+ jrs.addRowSet(crs1, SUPPLIERS_JOIN_COLUMN_INDEX);
+ validateResults(jrs);
+ crs.close();
+ crs1.close();
+ }
+ }
+
+ /*
+ * Join two CachedRowSets specifying a column name to join against
+ */
+ @Test(dataProvider = "createCachedRowSetsToUse")
+ public void joinRowSetTests0002(CachedRowSet crs, CachedRowSet crs1)
+ throws Exception {
+
+ try (JoinRowSet jrs = newInstance()) {
+ RowSet[] rowsets = {crs, crs1};
+ String[] joinCols = {JOIN_COLNAME, JOIN_COLNAME};
+ jrs.addRowSet(rowsets, joinCols);
+ validateResults(jrs);
+ crs.close();
+ crs1.close();
+ }
+ }
+
+ /*
+ * Join two CachedRowSets specifying a column index to join against
+ */
+ @Test(dataProvider = "createCachedRowSetsToUse")
+ public void joinRowSetTests0003(CachedRowSet crs, CachedRowSet crs1)
+ throws Exception {
+
+ try (JoinRowSet jrs = newInstance()) {
+ RowSet[] rowsets = {crs, crs1};
+ int[] joinCols = {COFFEES_JOIN_COLUMN_INDEX,
+ SUPPLIERS_JOIN_COLUMN_INDEX};
+ jrs.addRowSet(rowsets, joinCols);
+ validateResults(jrs);
+ crs.close();
+ crs1.close();
+ }
+ }
+
+ /*
+ * Join two CachedRowSets specifying a column name to join against
+ */
+ @Test(dataProvider = "createCachedRowSetsToUse")
+ public void joinRowSetTests0005(CachedRowSet crs, CachedRowSet crs1)
+ throws Exception {
+
+ try (JoinRowSet jrs = newInstance()) {
+ crs.setMatchColumn(JOIN_COLNAME);
+ crs1.setMatchColumn(JOIN_COLNAME);
+ jrs.addRowSet(crs);
+ jrs.addRowSet(crs1);
+ validateResults(jrs);
+ crs.close();
+ crs1.close();
+ }
+ }
+
+ /*
+ * Join two CachedRowSets specifying a column index to join against
+ */
+ @Test(dataProvider = "createCachedRowSetsToUse")
+ public void joinRowSetTests0006(CachedRowSet crs, CachedRowSet crs1)
+ throws Exception {
+
+ try (JoinRowSet jrs = newInstance()) {
+ crs.setMatchColumn(COFFEES_JOIN_COLUMN_INDEX);
+ crs1.setMatchColumn(SUPPLIERS_JOIN_COLUMN_INDEX);
+
+ jrs.addRowSet(crs);
+ jrs.addRowSet(crs1);
+ validateResults(jrs);
+ crs.close();
+ crs1.close();
+ }
+ }
+
+ // Disabled tests due to bugs in JoinRowSet
+ @Test(dataProvider = "rowSetType", enabled = false)
+ public void commonCachedRowSetTest0004(CachedRowSet rs) throws Exception {
+ }
+
+ @Test(dataProvider = "rowSetType", enabled = false)
+ public void commonCachedRowSetTest0005(CachedRowSet rs) throws Exception {
+ }
+
+ @Test(dataProvider = "rowSetType", enabled = false)
+ public void commonCachedRowSetTest0008(CachedRowSet rs) throws Exception {
+ }
+
+ @Test(dataProvider = "rowSetType", enabled = false)
+ public void commonCachedRowSetTest0026(CachedRowSet rs) throws Exception {
+ }
+
+ @Test(dataProvider = "rowSetType", enabled = false)
+ public void commonCachedRowSetTest0027(CachedRowSet rs) throws Exception {
+ }
+
+ @Test(dataProvider = "rowSetType", enabled = false)
+ public void commonCachedRowSetTest0053(CachedRowSet rs) throws Exception {
+ }
+
+ @Test(dataProvider = "rowSetType", enabled = false)
+ public void commonCachedRowSetTest0054(CachedRowSet rs) throws Exception {
+ }
+
+ @Test(dataProvider = "rowSetType", enabled = false)
+ public void commonCachedRowSetTest0055(CachedRowSet rs) throws Exception {
+ }
+
+ @Test(dataProvider = "rowSetType")
+ public void WebRowSetTest0009(WebRowSet wrs1) throws Exception {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/test/rowset/webrowset/CommonWebRowSetTests.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,400 @@
+/*
+ * 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 test.rowset.webrowset;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStreamWriter;
+import java.math.BigDecimal;
+import java.sql.ResultSet;
+import java.util.Arrays;
+import javax.sql.rowset.WebRowSet;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertEqualsNoOrder;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+import test.rowset.cachedrowset.CommonCachedRowSetTests;
+
+public abstract class CommonWebRowSetTests extends CommonCachedRowSetTests {
+
+ protected final String XMLFILEPATH = System.getProperty("test.src", ".")
+ + File.separatorChar + "xml" + File.separatorChar;
+ protected final String COFFEE_ROWS_XML = XMLFILEPATH + "COFFEE_ROWS.xml";
+ protected final String DELETED_COFFEE_ROWS_XML
+ = XMLFILEPATH + "DELETED_COFFEE_ROWS.xml";
+ protected final String MODFIED_DELETED_COFFEE_ROWS_XML
+ = XMLFILEPATH + "MODFIED_DELETED_COFFEE_ROWS.xml";
+ protected final String UPDATED_COFFEE_ROWS_XML
+ = XMLFILEPATH + "UPDATED_COFFEE_ROWS.xml";
+ protected final String INSERTED_COFFEE_ROWS_XML
+ = XMLFILEPATH + "INSERTED_COFFEE_ROWS.xml";
+ protected final String UPDATED_INSERTED_COFFEE_ROWS_XML
+ = XMLFILEPATH + "UPDATED_INSERTED_COFFEE_ROWS.xml";
+
+
+ /*
+ * Utility method to write a WebRowSet XML file via an OutputStream
+ */
+ protected ByteArrayOutputStream writeWebRowSetWithOutputStream(WebRowSet rs) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ rs.writeXml(oos);
+ }
+ return baos;
+ }
+
+ /*
+ * Utility method to write a WebRowSet XML file via an OutputStream
+ * and populating the WebRowSet via a ResultSet
+ */
+ protected ByteArrayOutputStream writeWebRowSetWithOutputStream(ResultSet rs) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ WebRowSet wrs = rsf.createWebRowSet();
+ wrs.writeXml(rs, oos);
+ }
+ return baos;
+ }
+
+
+ /*
+ * Utility method to popoulate a WebRowSet via a InputStream
+ */
+ protected WebRowSet readWebRowSetWithOInputStream(ByteArrayOutputStream baos) throws Exception {
+ WebRowSet wrs1 = rsf.createWebRowSet();
+ try (ObjectInputStream ois
+ = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
+ wrs1.readXml(ois);
+ }
+ return wrs1;
+ }
+
+ /*
+ * Utility method to write a WebRowSet XML file via an Writer
+ */
+ protected ByteArrayOutputStream writeWebRowSetWithOutputStreamWithWriter(WebRowSet rs) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStreamWriter osw = new OutputStreamWriter(baos);
+ rs.writeXml(osw);
+ return baos;
+ }
+
+ /*
+ * Utility method to write a WebRowSet XML file via an Writer and populating
+ * the WebRowSet via a ResultSet
+ */
+ protected ByteArrayOutputStream writeWebRowSetWithOutputStreamWithWriter(ResultSet rs) throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStreamWriter osw = new OutputStreamWriter(baos);
+ WebRowSet wrs = rsf.createWebRowSet();
+ wrs.writeXml(rs, osw);
+ return baos;
+ }
+
+ /*
+ * Utility method to popoulate a WebRowSet via a Readar
+ */
+ protected WebRowSet readWebRowSetWithOInputStreamWithReader(ByteArrayOutputStream baos) throws Exception {
+ WebRowSet wrs1 = rsf.createWebRowSet();
+ InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(baos.toByteArray()));
+ wrs1.readXml(isr);
+ return wrs1;
+ }
+
+ /*
+ * Validate the expected Rows are contained within the RowSet
+ */
+ @Test(dataProvider = "rowsetUsingCoffees")
+ public void WebRowSetTest0000(WebRowSet wrs) throws Exception {
+ assertEquals(getPrimaryKeys(wrs), COFFEES_PRIMARY_KEYS);
+ assertEquals(wrs.size(), COFFEES_ROWS);
+ wrs.close();
+ }
+
+ /*
+ * Validate the expected Rows are contained within the RowSet
+ * populated by readXML(Reader)
+ */
+ @Test(dataProvider = "rowSetType")
+ public void WebRowSetTest0001(WebRowSet wrs1) throws Exception {
+
+ try (FileReader fr = new FileReader(COFFEE_ROWS_XML)) {
+ wrs1.readXml(fr);
+ }
+ assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS);
+ assertEquals(wrs1.size(), COFFEES_ROWS);
+ wrs1.close();
+
+ }
+
+ /*
+ * Validate the expected Rows are contained within the RowSet
+ * populated by readXML(InputStream)
+ */
+ @Test(dataProvider = "rowSetType")
+ public void WebRowSetTest0002(WebRowSet wrs1) throws Exception {
+ try (FileInputStream fis = new FileInputStream(COFFEE_ROWS_XML)) {
+ wrs1.readXml(fis);
+ }
+ assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS);
+ assertEquals(wrs1.size(), COFFEES_ROWS);
+ wrs1.close();
+ }
+
+ /*
+ * Write a WebRowSet via writeXML(OutputStream), read it
+ * back via readXML(InputStream) and validate the primary keys
+ * are the same
+ */
+ @Test(dataProvider = "rowsetUsingCoffees")
+ public void WebRowSetTest0003(WebRowSet wrs) throws Exception {
+ ByteArrayOutputStream baos = writeWebRowSetWithOutputStream(wrs);
+ try (WebRowSet wrs1 = readWebRowSetWithOInputStream(baos)) {
+ assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS);
+ assertEquals(wrs1.size(), COFFEES_ROWS);
+ }
+ }
+
+ /*
+ * Write a ResultSet via writeXML(OutputStream), read it
+ * back via readXML(InputStream) and validate the primary keys
+ * are the same
+ */
+ @Test(dataProvider = "rowsetUsingCoffees")
+ public void WebRowSetTest0004(WebRowSet wrs) throws Exception {
+ ResultSet rs = wrs;
+ rs.beforeFirst();
+ ByteArrayOutputStream baos = writeWebRowSetWithOutputStream(rs);
+ try (WebRowSet wrs1 = readWebRowSetWithOInputStream(baos)) {
+ assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS);
+ assertEquals(wrs1.size(), COFFEES_ROWS);
+ }
+ }
+
+ /*
+ * Write a WebRowSet via writeXML(Writer), read it
+ * back via readXML(Reader) and validate the primary keys
+ * are the same
+ */
+ @Test(dataProvider = "rowsetUsingCoffees")
+ public void WebRowSetTest0005(WebRowSet wrs) throws Exception {
+ ByteArrayOutputStream baos = writeWebRowSetWithOutputStreamWithWriter(wrs);
+ try (WebRowSet wrs1 = readWebRowSetWithOInputStreamWithReader(baos)) {
+ assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS);
+ assertEquals(wrs1.size(), COFFEES_ROWS);
+ }
+ }
+
+ /*
+ * Write a WebRowSet via writeXML(Writer), read it
+ * back via readXML(Reader) and validate the primary keys
+ * are the same
+ */
+ @Test(dataProvider = "rowsetUsingCoffees")
+ public void WebRowSetTest0006(WebRowSet wrs) throws Exception {
+ ResultSet rs = wrs;
+ rs.beforeFirst();
+ ByteArrayOutputStream baos = writeWebRowSetWithOutputStreamWithWriter(rs);
+ try (WebRowSet wrs1 = readWebRowSetWithOInputStreamWithReader(baos)) {
+ assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS);
+ assertEquals(wrs1.size(), COFFEES_ROWS);
+ }
+ }
+
+ /*
+ * Validate the expected Rows are contained within the RowSet
+ * after deleting the specified rows
+ */
+ @Test(dataProvider = "rowsetUsingCoffees", enabled = false)
+ public void WebRowSetTest0007(WebRowSet wrs) throws Exception {
+ assertEquals(getPrimaryKeys(wrs), COFFEES_PRIMARY_KEYS);
+ int[] rowsToDelete = {2, 4};
+ assertEquals(getPrimaryKeys(wrs), COFFEES_PRIMARY_KEYS);
+ for (int row : rowsToDelete) {
+ assertTrue(deleteRowByPrimaryKey(wrs, row, 1));
+ }
+
+ FileInputStream fis = new FileInputStream(MODFIED_DELETED_COFFEE_ROWS_XML);
+ try (WebRowSet wrs1 = rsf.createWebRowSet()) {
+ wrs1.readXml(fis);
+ // With setShowDeleted(false) which is the default,
+ // the deleted row should not be visible
+ for (int row : rowsToDelete) {
+ assertTrue(findRowByPrimaryKey(wrs1, row, 1));
+ }
+ assertTrue(wrs.size() == COFFEES_ROWS);
+ // With setShowDeleted(true), the deleted row should be visible
+ for (int row : rowsToDelete) {
+ assertTrue(findRowByPrimaryKey(wrs, row, 1));
+ }
+ }
+ }
+
+ /*
+ * Validate the expected Rows are contained within the RowSet
+ * that was populated by reading an xml file with all rows
+ * marked as a currentRow
+ */
+ @Test(dataProvider = "rowSetType")
+ public void WebRowSetTest0008(WebRowSet wrs1) throws Exception {
+ FileInputStream fis = new FileInputStream(COFFEE_ROWS_XML);
+ wrs1.readXml(fis);
+ assertTrue(wrs1.size() == COFFEES_ROWS);
+ assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS);
+ // Validate that the rows are not marked as deleted, inserted or updated
+ wrs1.beforeFirst();
+ while (wrs1.next()) {
+ assertFalse(wrs1.rowDeleted());
+ assertFalse(wrs1.rowInserted());
+ assertFalse(wrs1.rowUpdated());
+ }
+ wrs1.close();
+ }
+
+ /*
+ * Read an XML file to populate a WebRowSet and validate that the rows
+ * that are marked as deleted are marked as such in the WebRowSet
+ * Also validate that they are or are not visible based on the
+ * setShowDeleted value
+ */
+ @Test(dataProvider = "rowSetType")
+ public void WebRowSetTest0009(WebRowSet wrs1) throws Exception {
+ int[] rowsToDelete = {2, 4};
+ Object[] expectedRows = {1, 3, 5};
+ FileInputStream fis = new FileInputStream(DELETED_COFFEE_ROWS_XML);
+ wrs1.readXml(fis);
+ assertTrue(wrs1.size() == COFFEES_ROWS);
+ assertEquals(getPrimaryKeys(wrs1), expectedRows);
+ // With setShowDeleted(false) which is the default,
+ // the deleted row should not be visible
+ for (int row : rowsToDelete) {
+ assertFalse(findRowByPrimaryKey(wrs1, row, 1));
+ }
+ // With setShowDeleted(true), the deleted row should be visible
+ wrs1.setShowDeleted(true);
+ for (int row : rowsToDelete) {
+ assertTrue(findRowByPrimaryKey(wrs1, row, 1));
+ }
+ assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS);
+ wrs1.close();
+
+ }
+
+ /*
+ * Validate that the correct row in the WebRowSet that had been created
+ * from an xml file is marked as updated and contains the correct values
+ */
+ @Test(dataProvider = "rowSetType")
+ public void WebRowSetTest0010(WebRowSet wrs1) throws Exception {
+ FileInputStream fis = new FileInputStream(UPDATED_COFFEE_ROWS_XML);
+ wrs1.readXml(fis);
+ assertTrue(wrs1.size() == COFFEES_ROWS);
+ assertEquals(getPrimaryKeys(wrs1), COFFEES_PRIMARY_KEYS);
+ wrs1.beforeFirst();
+ while (wrs1.next()) {
+ if (wrs1.getInt(1) == 3) {
+ assertTrue(wrs1.rowUpdated());
+ assertTrue(wrs1.getInt(5) == 21 && wrs1.getInt(6) == 69);
+ assertFalse(wrs1.rowDeleted());
+ assertFalse(wrs1.rowInserted());
+ } else {
+ assertFalse(wrs1.rowUpdated());
+ assertFalse(wrs1.rowDeleted());
+ assertFalse(wrs1.rowInserted());
+ }
+ }
+ wrs1.close();
+ }
+
+ /*
+ * Validate the correct row is marked as inserted in a WebRowSet
+ * that is read from an xml file
+ */
+ @Test(dataProvider = "rowSetType")
+ public void WebRowSetTest0011(WebRowSet wrs1) throws Exception {
+ int expectedSize = COFFEES_ROWS + 2;
+ int addedRowPK = 15;
+ int addedRowPK2 = 20;
+ Object[] expected = Arrays.copyOf(COFFEES_PRIMARY_KEYS, expectedSize);
+ expected[expectedSize - 2] = addedRowPK;
+ expected[expectedSize - 1] = addedRowPK2;
+ FileInputStream fis = new FileInputStream(INSERTED_COFFEE_ROWS_XML);
+ wrs1.readXml(fis);
+ assertTrue(wrs1.size() == expectedSize);
+ assertEqualsNoOrder(getPrimaryKeys(wrs1), expected);
+ wrs1.beforeFirst();
+ while (wrs1.next()) {
+ if (wrs1.getInt(1) == 15 || wrs1.getInt(1) == 20) {
+ assertTrue(wrs1.rowInserted());
+ assertFalse(wrs1.rowDeleted());
+ assertFalse(wrs1.rowUpdated());
+ } else {
+ assertFalse(wrs1.rowInserted());
+ assertFalse(wrs1.rowDeleted());
+ assertFalse(wrs1.rowUpdated());
+ }
+ }
+ wrs1.close();
+ }
+
+ /*
+ * Read an xml file which contains a row that was inserted and updated
+ */
+ @Test(dataProvider = "rowSetType")
+ public void WebRowSetTest0012(WebRowSet wrs1) throws Exception {
+ int expectedSize = COFFEES_ROWS + 1;
+ int addedRowPK = 100;
+ Object[] expected = Arrays.copyOf(COFFEES_PRIMARY_KEYS, expectedSize);
+ expected[expectedSize - 1] = addedRowPK;
+ FileInputStream fis = new FileInputStream(UPDATED_INSERTED_COFFEE_ROWS_XML);
+ wrs1.readXml(fis);
+ assertTrue(wrs1.size() == expectedSize);
+ assertEquals(getPrimaryKeys(wrs1), expected);
+ wrs1.beforeFirst();
+ while (wrs1.next()) {
+ if (wrs1.getInt(1) == addedRowPK) {
+ // Row that was inserted and updated
+ assertTrue(wrs1.rowUpdated());
+ assertTrue(
+ wrs1.getBigDecimal(4).equals(BigDecimal.valueOf(12.99))
+ && wrs1.getInt(6) == 125);
+ assertFalse(wrs1.rowDeleted());
+ assertTrue(wrs1.rowInserted());
+ } else {
+ // Remaining rows should only be inserted
+ assertFalse(wrs1.rowUpdated());
+ assertFalse(wrs1.rowDeleted());
+ assertTrue(wrs1.rowInserted());
+ }
+ }
+ wrs1.close();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/test/rowset/webrowset/WebRowSetTests.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,35 @@
+/*
+ * 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 test.rowset.webrowset;
+
+import java.sql.SQLException;
+import javax.sql.rowset.WebRowSet;
+
+public class WebRowSetTests extends CommonWebRowSetTests {
+
+ @Override
+ protected WebRowSet newInstance() throws SQLException {
+ return rsf.createWebRowSet();
+ }
+
+}
--- a/jdk/test/javax/sql/testng/util/StubSyncProvider.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/javax/sql/testng/util/StubSyncProvider.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -51,12 +51,12 @@
@Override
public RowSetReader getRowSetReader() {
- throw new UnsupportedOperationException("Not supported yet.");
+ return null;
}
@Override
public RowSetWriter getRowSetWriter() {
- throw new UnsupportedOperationException("Not supported yet.");
+ return null;
}
@Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/xml/COFFEE_ROWS.xml Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,191 @@
+<?xml version="1.0"?>
+<webRowSet xmlns="http://java.sun.com/xml/ns/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://java.sun.com/xml/ns/jdbc http://java.sun.com/xml/ns/jdbc/webrowset.xsd">
+ <properties>
+ <command><null/></command>
+ <concurrency>1008</concurrency>
+ <datasource><null/></datasource>
+ <escape-processing>true</escape-processing>
+ <fetch-direction>1000</fetch-direction>
+ <fetch-size>0</fetch-size>
+ <isolation-level>2</isolation-level>
+ <key-columns>
+ </key-columns>
+ <map>
+ </map>
+ <max-field-size>0</max-field-size>
+ <max-rows>0</max-rows>
+ <query-timeout>0</query-timeout>
+ <read-only>true</read-only>
+ <rowset-type>ResultSet.TYPE_SCROLL_INSENSITIVE</rowset-type>
+ <show-deleted>false</show-deleted>
+ <table-name>COFFEES</table-name>
+ <url><null/></url>
+ <sync-provider>
+ <sync-provider-name>com.sun.rowset.providers.RIOptimisticProvider</sync-provider-name>
+ <sync-provider-vendor>Oracle Corporation</sync-provider-vendor>
+ <sync-provider-version>1.0</sync-provider-version>
+ <sync-provider-grade>2</sync-provider-grade>
+ <data-source-lock>1</data-source-lock>
+ </sync-provider>
+ </properties>
+ <metadata>
+ <column-count>6</column-count>
+ <column-definition>
+ <column-index>1</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>COF_NAME</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>2</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SUP_ID</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>12</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>3</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>PRICE</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>4</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SALES</column-name>
+ <schema-name></schema-name>
+ <column-precision>10</column-precision>
+ <column-scale>2</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>2</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>5</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>TOTAL</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>6</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name><null/></column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ </metadata>
+ <data>
+ <currentRow>
+ <columnValue>1</columnValue>
+ <columnValue>Colombian</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>7.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <currentRow>
+ <columnValue>2</columnValue>
+ <columnValue>French_Roast</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <currentRow>
+ <columnValue>3</columnValue>
+ <columnValue>Espresso</columnValue>
+ <columnValue>150</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <currentRow>
+ <columnValue>4</columnValue>
+ <columnValue>Colombian_Decaf</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <currentRow>
+ <columnValue>5</columnValue>
+ <columnValue>French_Roast_Decaf</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ </data>
+</webRowSet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/xml/DELETED_COFFEE_ROWS.xml Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,191 @@
+<?xml version="1.0"?>
+<webRowSet xmlns="http://java.sun.com/xml/ns/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://java.sun.com/xml/ns/jdbc http://java.sun.com/xml/ns/jdbc/webrowset.xsd">
+ <properties>
+ <command>SELECT * FROM COFFEES</command>
+ <concurrency>1008</concurrency>
+ <datasource><null/></datasource>
+ <escape-processing>true</escape-processing>
+ <fetch-direction>1000</fetch-direction>
+ <fetch-size>0</fetch-size>
+ <isolation-level>2</isolation-level>
+ <key-columns>
+ </key-columns>
+ <map>
+ </map>
+ <max-field-size>0</max-field-size>
+ <max-rows>0</max-rows>
+ <query-timeout>0</query-timeout>
+ <read-only>true</read-only>
+ <rowset-type>ResultSet.TYPE_SCROLL_INSENSITIVE</rowset-type>
+ <show-deleted>false</show-deleted>
+ <table-name>COFFEES</table-name>
+ <url>jdbc:derby://localhost:1527/testDB;create=true</url>
+ <sync-provider>
+ <sync-provider-name>com.sun.rowset.providers.RIOptimisticProvider</sync-provider-name>
+ <sync-provider-vendor>Oracle Corporation</sync-provider-vendor>
+ <sync-provider-version>1.0</sync-provider-version>
+ <sync-provider-grade>2</sync-provider-grade>
+ <data-source-lock>1</data-source-lock>
+ </sync-provider>
+ </properties>
+ <metadata>
+ <column-count>6</column-count>
+ <column-definition>
+ <column-index>1</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>COF_NAME</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>2</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SUP_ID</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>12</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>3</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>PRICE</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>4</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SALES</column-name>
+ <schema-name></schema-name>
+ <column-precision>10</column-precision>
+ <column-scale>2</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>2</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>5</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>TOTAL</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>6</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name><null/></column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ </metadata>
+ <data>
+ <currentRow>
+ <columnValue>1</columnValue>
+ <columnValue>Colombian</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>7.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <deleteRow>
+ <columnValue>2</columnValue>
+ <columnValue>French_Roast</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </deleteRow>
+ <currentRow>
+ <columnValue>3</columnValue>
+ <columnValue>Espresso</columnValue>
+ <columnValue>150</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <deleteRow>
+ <columnValue>4</columnValue>
+ <columnValue>Colombian_Decaf</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </deleteRow>
+ <currentRow>
+ <columnValue>5</columnValue>
+ <columnValue>French_Roast_Decaf</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ </data>
+</webRowSet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/xml/INSERTED_COFFEE_ROWS.xml Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,207 @@
+<?xml version="1.0"?>
+<webRowSet xmlns="http://java.sun.com/xml/ns/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://java.sun.com/xml/ns/jdbc http://java.sun.com/xml/ns/jdbc/webrowset.xsd">
+ <properties>
+ <command><null/></command>
+ <concurrency>1008</concurrency>
+ <datasource><null/></datasource>
+ <escape-processing>true</escape-processing>
+ <fetch-direction>1000</fetch-direction>
+ <fetch-size>0</fetch-size>
+ <isolation-level>2</isolation-level>
+ <key-columns>
+ </key-columns>
+ <map>
+ </map>
+ <max-field-size>0</max-field-size>
+ <max-rows>0</max-rows>
+ <query-timeout>0</query-timeout>
+ <read-only>true</read-only>
+ <rowset-type>ResultSet.TYPE_SCROLL_INSENSITIVE</rowset-type>
+ <show-deleted>false</show-deleted>
+ <table-name>COFFEES</table-name>
+ <url><null/></url>
+ <sync-provider>
+ <sync-provider-name>com.sun.rowset.providers.RIOptimisticProvider</sync-provider-name>
+ <sync-provider-vendor>Oracle Corporation</sync-provider-vendor>
+ <sync-provider-version>1.0</sync-provider-version>
+ <sync-provider-grade>2</sync-provider-grade>
+ <data-source-lock>1</data-source-lock>
+ </sync-provider>
+ </properties>
+ <metadata>
+ <column-count>6</column-count>
+ <column-definition>
+ <column-index>1</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>COF_NAME</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>2</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SUP_ID</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>12</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>3</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>PRICE</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>4</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SALES</column-name>
+ <schema-name></schema-name>
+ <column-precision>10</column-precision>
+ <column-scale>2</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>2</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>5</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>TOTAL</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>6</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name><null/></column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ </metadata>
+ <data>
+ <currentRow>
+ <columnValue>1</columnValue>
+ <columnValue>Colombian</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>7.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <currentRow>
+ <columnValue>2</columnValue>
+ <columnValue>French_Roast</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <currentRow>
+ <columnValue>3</columnValue>
+ <columnValue>Espresso</columnValue>
+ <columnValue>150</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <currentRow>
+ <columnValue>4</columnValue>
+ <columnValue>Colombian_Decaf</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <insertRow>
+ <columnValue>15</columnValue>
+ <columnValue>Hazelnut</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </insertRow>
+ <insertRow>
+ <columnValue>20</columnValue>
+ <columnValue>French Vanilla</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </insertRow>
+ <currentRow>
+ <columnValue>5</columnValue>
+ <columnValue>French_Roast_Decaf</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ </data>
+</webRowSet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/xml/MODFIED_DELETED_COFFEE_ROWS.xml Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,191 @@
+<?xml version="1.0"?>
+<webRowSet xmlns="http://java.sun.com/xml/ns/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://java.sun.com/xml/ns/jdbc http://java.sun.com/xml/ns/jdbc/webrowset.xsd">
+ <properties>
+ <command><null/></command>
+ <concurrency>1008</concurrency>
+ <datasource><null/></datasource>
+ <escape-processing>true</escape-processing>
+ <fetch-direction>1000</fetch-direction>
+ <fetch-size>0</fetch-size>
+ <isolation-level>2</isolation-level>
+ <key-columns>
+ </key-columns>
+ <map>
+ </map>
+ <max-field-size>0</max-field-size>
+ <max-rows>0</max-rows>
+ <query-timeout>0</query-timeout>
+ <read-only>true</read-only>
+ <rowset-type>ResultSet.TYPE_SCROLL_INSENSITIVE</rowset-type>
+ <show-deleted>false</show-deleted>
+ <table-name>COFFEES</table-name>
+ <url><null/></url>
+ <sync-provider>
+ <sync-provider-name>com.sun.rowset.providers.RIOptimisticProvider</sync-provider-name>
+ <sync-provider-vendor>Oracle Corporation</sync-provider-vendor>
+ <sync-provider-version>1.0</sync-provider-version>
+ <sync-provider-grade>2</sync-provider-grade>
+ <data-source-lock>1</data-source-lock>
+ </sync-provider>
+ </properties>
+ <metadata>
+ <column-count>6</column-count>
+ <column-definition>
+ <column-index>1</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>COF_NAME</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>2</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SUP_ID</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>12</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>3</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>PRICE</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>4</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SALES</column-name>
+ <schema-name></schema-name>
+ <column-precision>10</column-precision>
+ <column-scale>2</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>2</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>5</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>TOTAL</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>6</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name><null/></column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ </metadata>
+ <data>
+ <insertRow>
+ <columnValue>1</columnValue>
+ <columnValue>Colombian</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>7.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </insertRow>
+ <modifyRow>
+ <columnValue>2</columnValue>
+ <columnValue>French_Roast</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </modifyRow>
+ <insertRow>
+ <columnValue>3</columnValue>
+ <columnValue>Espresso</columnValue>
+ <columnValue>150</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </insertRow>
+ <modifyRow>
+ <columnValue>4</columnValue>
+ <columnValue>Colombian_Decaf</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </modifyRow>
+ <insertRow>
+ <columnValue>5</columnValue>
+ <columnValue>French_Roast_Decaf</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </insertRow>
+ </data>
+</webRowSet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/xml/UPDATED_COFFEE_ROWS.xml Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,193 @@
+<?xml version="1.0"?>
+<webRowSet xmlns="http://java.sun.com/xml/ns/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://java.sun.com/xml/ns/jdbc http://java.sun.com/xml/ns/jdbc/webrowset.xsd">
+ <properties>
+ <command>SELECT * FROM COFFEES</command>
+ <concurrency>1008</concurrency>
+ <datasource><null/></datasource>
+ <escape-processing>true</escape-processing>
+ <fetch-direction>1000</fetch-direction>
+ <fetch-size>0</fetch-size>
+ <isolation-level>2</isolation-level>
+ <key-columns>
+ </key-columns>
+ <map>
+ </map>
+ <max-field-size>0</max-field-size>
+ <max-rows>0</max-rows>
+ <query-timeout>0</query-timeout>
+ <read-only>true</read-only>
+ <rowset-type>ResultSet.TYPE_SCROLL_INSENSITIVE</rowset-type>
+ <show-deleted>false</show-deleted>
+ <table-name>COFFEES</table-name>
+ <url>jdbc:derby://localhost:1527/testDB;create=true</url>
+ <sync-provider>
+ <sync-provider-name>com.sun.rowset.providers.RIOptimisticProvider</sync-provider-name>
+ <sync-provider-vendor>Oracle Corporation</sync-provider-vendor>
+ <sync-provider-version>1.0</sync-provider-version>
+ <sync-provider-grade>2</sync-provider-grade>
+ <data-source-lock>1</data-source-lock>
+ </sync-provider>
+ </properties>
+ <metadata>
+ <column-count>6</column-count>
+ <column-definition>
+ <column-index>1</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>COF_NAME</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>2</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SUP_ID</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>12</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>3</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>PRICE</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>4</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SALES</column-name>
+ <schema-name></schema-name>
+ <column-precision>10</column-precision>
+ <column-scale>2</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>2</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>5</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>TOTAL</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>6</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name><null/></column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ </metadata>
+ <data>
+ <currentRow>
+ <columnValue>1</columnValue>
+ <columnValue>Colombian</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>7.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <currentRow>
+ <columnValue>2</columnValue>
+ <columnValue>French_Roast</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <currentRow>
+ <columnValue>3</columnValue>
+ <columnValue>Espresso</columnValue>
+ <columnValue>150</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <updateRow>21</updateRow>
+ <columnValue>0</columnValue>
+ <updateRow>69</updateRow>
+ </currentRow>
+ <currentRow>
+ <columnValue>4</columnValue>
+ <columnValue>Colombian_Decaf</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ <currentRow>
+ <columnValue>5</columnValue>
+ <columnValue>French_Roast_Decaf</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </currentRow>
+ </data>
+</webRowSet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/xml/UPDATED_INSERTED_COFFEE_ROWS.xml Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,201 @@
+<?xml version="1.0"?>
+<webRowSet xmlns="http://java.sun.com/xml/ns/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://java.sun.com/xml/ns/jdbc http://java.sun.com/xml/ns/jdbc/webrowset.xsd">
+ <properties>
+ <command><null/></command>
+ <concurrency>1008</concurrency>
+ <datasource><null/></datasource>
+ <escape-processing>true</escape-processing>
+ <fetch-direction>1000</fetch-direction>
+ <fetch-size>0</fetch-size>
+ <isolation-level>2</isolation-level>
+ <key-columns>
+ </key-columns>
+ <map>
+ </map>
+ <max-field-size>0</max-field-size>
+ <max-rows>0</max-rows>
+ <query-timeout>0</query-timeout>
+ <read-only>true</read-only>
+ <rowset-type>ResultSet.TYPE_SCROLL_INSENSITIVE</rowset-type>
+ <show-deleted>false</show-deleted>
+ <table-name>COFFEES</table-name>
+ <url><null/></url>
+ <sync-provider>
+ <sync-provider-name>com.sun.rowset.providers.RIOptimisticProvider</sync-provider-name>
+ <sync-provider-vendor>Oracle Corporation</sync-provider-vendor>
+ <sync-provider-version>1.0</sync-provider-version>
+ <sync-provider-grade>2</sync-provider-grade>
+ <data-source-lock>1</data-source-lock>
+ </sync-provider>
+ </properties>
+ <metadata>
+ <column-count>6</column-count>
+ <column-definition>
+ <column-index>1</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>COF_NAME</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>2</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SUP_ID</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>12</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>3</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>PRICE</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>4</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>SALES</column-name>
+ <schema-name></schema-name>
+ <column-precision>10</column-precision>
+ <column-scale>2</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>2</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>5</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name>TOTAL</column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ <column-definition>
+ <column-index>6</column-index>
+ <auto-increment>false</auto-increment>
+ <case-sensitive>false</case-sensitive>
+ <currency>false</currency>
+ <nullable>0</nullable>
+ <signed>false</signed>
+ <searchable>false</searchable>
+ <column-display-size>0</column-display-size>
+ <column-label><null/></column-label>
+ <column-name><null/></column-name>
+ <schema-name></schema-name>
+ <column-precision>0</column-precision>
+ <column-scale>0</column-scale>
+ <table-name></table-name>
+ <catalog-name></catalog-name>
+ <column-type>4</column-type>
+ <column-type-name><null/></column-type-name>
+ </column-definition>
+ </metadata>
+ <data>
+ <insertRow>
+ <columnValue>1</columnValue>
+ <columnValue>Colombian</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>7.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </insertRow>
+ <insertRow>
+ <columnValue>2</columnValue>
+ <columnValue>French_Roast</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </insertRow>
+ <insertRow>
+ <columnValue>3</columnValue>
+ <columnValue>Espresso</columnValue>
+ <columnValue>150</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </insertRow>
+ <insertRow>
+ <columnValue>4</columnValue>
+ <columnValue>Colombian_Decaf</columnValue>
+ <columnValue>101</columnValue>
+ <columnValue>8.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </insertRow>
+ <insertRow>
+ <columnValue>5</columnValue>
+ <columnValue>French_Roast_Decaf</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>9.99</columnValue>
+ <columnValue>0</columnValue>
+ <columnValue>0</columnValue>
+ </insertRow>
+ <insertRow>
+ <columnValue>100</columnValue>
+ <columnValue>Mocha</columnValue>
+ <columnValue>49</columnValue>
+ <columnValue>9.99</columnValue>
+ <updateRow>12.99</updateRow>
+ <columnValue>20</columnValue>
+ <columnValue>35</columnValue>
+ <updateRow>125</updateRow>
+ </insertRow>
+ </data>
+</webRowSet>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JButton/4796987/bug4796987.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4796987
+ * @summary XP Only: JButton.setBorderPainted() does not work with XP L&F
+ * @author Alexander Scherbatiy
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main bug4796987
+ */
+
+import java.awt.*;
+import javax.swing.*;
+import sun.awt.OSInfo;
+import sun.awt.SunToolkit;
+import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
+
+public class bug4796987 {
+
+ private static JButton button1;
+ private static JButton button2;
+
+ public static void main(String[] args) throws Exception {
+ if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS
+ && OSInfo.getWindowsVersion() == OSInfo.WINDOWS_XP) {
+ UIManager.setLookAndFeel(new WindowsLookAndFeel());
+ testButtonBorder();
+ }
+ }
+
+ private static void testButtonBorder() throws Exception {
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+
+ toolkit.realSync();
+ Thread.sleep(500);
+
+ Point p1 = Util.getCenterPoint(button1);
+ Point p2 = Util.getCenterPoint(button2);
+
+ Color color = robot.getPixelColor(p1.x, p2.x);
+ for (int dx = p1.x; dx < p2.x - p1.x; dx++) {
+ robot.mouseMove(p1.x + dx, p1.y);
+ if (!color.equals(robot.getPixelColor(p1.x + dx, p1.y))) {
+ throw new RuntimeException("Button has border and background!");
+ }
+ }
+ }
+
+ private static JButton getButton() {
+ JButton button = new JButton();
+ button.setBorderPainted(false);
+ button.setFocusable(false);
+ return button;
+ }
+
+ private static void createAndShowGUI() {
+ JFrame frame = new JFrame("Test");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setSize(200, 200);
+
+ JButton button = new JButton();
+ button.setBorder(null);
+
+ JPanel panel = new JPanel(new BorderLayout(50, 50));
+ panel.add(getButton(), BorderLayout.CENTER);
+ panel.add(button1 = getButton(), BorderLayout.WEST);
+ panel.add(button2 = getButton(), BorderLayout.EAST);
+ frame.getContentPane().add(panel);
+ frame.setVisible(true);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/8062561/bug8062561.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,210 @@
+/*
+ * 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 java.awt.Robot;
+import java.awt.event.KeyEvent;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.concurrent.TimeUnit;
+import javax.swing.JFileChooser;
+import javax.swing.SwingUtilities;
+import javax.swing.filechooser.FileSystemView;
+import sun.awt.OSInfo;
+
+/**
+ * @test
+ * @bug 8062561
+ * @summary File system view returns null default directory
+ * @run main/othervm bug8062561 GENERATE_POLICY
+ * @run main/othervm/policy=security.policy bug8062561 CHECK_DEFAULT_DIR run
+ */
+public class bug8062561 {
+
+ private static final String POLICY_FILE = "security2.policy";
+ private static volatile boolean fileChooserIsShown = false;
+
+ public static void main(String[] args) throws Exception {
+
+ String test = args[0];
+
+ switch (test) {
+ case "GENERATE_POLICY":
+ generatePolicyFile();
+ break;
+ case "CHECK_DEFAULT_DIR":
+ checkDefaultDirectory();
+ break;
+ case "CHECK_FILE_CHOOSER":
+ checkFileChooser();
+ break;
+ default:
+ throw new RuntimeException("Wrong argument!");
+ }
+ }
+
+ private static void checkDefaultDirectory() {
+ if (System.getSecurityManager() == null) {
+ throw new RuntimeException("Security manager is not set!");
+ }
+
+ File defaultDirectory = FileSystemView.getFileSystemView().
+ getDefaultDirectory();
+ if (defaultDirectory != null) {
+ throw new RuntimeException("File system default directory is null!");
+ }
+ }
+ private static volatile JFileChooser fileChooser;
+
+ private static void checkFileChooser() throws Exception {
+ if (System.getSecurityManager() == null) {
+ throw new RuntimeException("Security manager is not set!");
+ }
+
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+
+ SwingUtilities.invokeLater(new Runnable() {
+
+ public void run() {
+ fileChooser = new JFileChooser();
+ fileChooser.showOpenDialog(null);
+ fileChooserIsShown = true;
+ System.out.println("Start file chooser: " + fileChooserIsShown);
+ }
+ });
+
+ long time = System.currentTimeMillis();
+ while (fileChooser == null) {
+ if (System.currentTimeMillis() - time >= 10000) {
+ throw new RuntimeException("FileChoser is not shown!");
+ }
+ Thread.sleep(500);
+ }
+
+ Thread.sleep(500);
+ robot.keyPress(KeyEvent.VK_ESCAPE);
+ robot.keyRelease(KeyEvent.VK_ESCAPE);
+ System.exit(0);
+ }
+
+ private static void generatePolicyFile() throws Exception {
+ if (System.getSecurityManager() != null) {
+ throw new RuntimeException("Security manager should be null!");
+ }
+
+ if (!OSInfo.getOSType().equals(OSInfo.OSType.WINDOWS)) {
+ return;
+ }
+
+ File defaultDirectory = FileSystemView.getFileSystemView().
+ getDefaultDirectory();
+
+ if (defaultDirectory == null) {
+ throw new RuntimeException("Default directory is null!");
+ }
+
+ File policyFile = new File(POLICY_FILE);
+ if (!policyFile.exists()) {
+ policyFile.createNewFile();
+ }
+
+ try (PrintWriter writer = new PrintWriter(policyFile, "UTF-8")) {
+ writer.println("grant {");
+ String documents = defaultDirectory.getCanonicalPath();
+ documents = documents.replace('\\', '/');
+ // Documents permission
+ writer.print(" permission java.io.FilePermission");
+ writer.print(" \"" + documents + "\",");
+ writer.println(" \"read\";");
+ // Desktop permission
+ writer.print(" permission java.io.FilePermission");
+ writer.print(" \"" + documents.replace("Documents", "Desktop") + "\",");
+ writer.println(" \"read\";");
+ // robot permission // "java.awt.AWTPermission" "createRobot"
+ writer.print(" permission java.awt.AWTPermission");
+ writer.println(" \"createRobot\";");
+ writer.println("};");
+ }
+
+ performTest();
+ }
+
+ private static void performTest() throws Exception {
+ String javaPath = System.getProperty("java.home", "");
+ String command = javaPath + File.separator + "bin" + File.separator + "java"
+ + " -Djava.security.manager -Djava.security.policy=" + POLICY_FILE
+ + " bug8062561 CHECK_FILE_CHOOSER";
+ System.out.println(command);
+ boolean processExit = false;
+
+ Process process = Runtime.getRuntime().exec(command);
+
+ try {
+ processExit = process.waitFor(20, TimeUnit.SECONDS);
+ } catch (IllegalThreadStateException e) {
+ throw new RuntimeException(e);
+ }
+ System.out.println("[RESULT] : "
+ + "The sub process has cleanly exited : PASS");
+
+ InputStream errorStream = process.getErrorStream();
+ System.out.println("========= Child process stderr ========");
+ boolean exception = dumpStream(errorStream);
+ if (exception) {
+ throw new RuntimeException("[RESULT] :"
+ + " Exception in child process : FAIL");
+ }
+ System.out.println("=======================================");
+
+ InputStream processInputStream = process.getInputStream();
+ System.out.println("========= Child process output ========");
+ dumpStream(processInputStream);
+ System.out.println("=======================================");
+
+ if (!processExit) {
+ process.destroy();
+ throw new RuntimeException("[RESULT] : "
+ + "The sub process has not exited : FAIL");
+ }
+ }
+
+ public static boolean dumpStream(InputStream in) throws IOException {
+ String tempString;
+ int count = in.available();
+ boolean exception = false;
+ while (count > 0) {
+ byte[] b = new byte[count];
+ in.read(b);
+ tempString = new String(b);
+ if (!exception) {
+ exception = tempString.indexOf("Exception") != -1;
+ }
+ System.out.println(tempString);
+ count = in.available();
+ }
+
+ return exception;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/8062561/security.policy Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,5 @@
+grant {
+
+ permission java.util.PropertyPermission "user.home", "read";
+ permission java.util.PropertyPermission "user.dir", "read";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JFileChooser/8062561/security2.policy Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,1 @@
+// Autogenerated file
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JToolTip/6219960/bug6219960.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,210 @@
+/*
+ * 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 java.awt.Component;
+import java.awt.Container;
+import java.awt.GridLayout;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.AWTException;
+import java.awt.IllegalComponentStateException;
+import java.awt.event.InputEvent;
+import javax.swing.JButton;
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
+import javax.swing.table.DefaultTableModel;
+
+/**
+ * @test
+ * @bug 6219960
+ * @summary null reference in ToolTipManager
+ * @run main bug6219960
+ */
+public class bug6219960 {
+
+ private static final String QUESTION = "Question";
+
+ static volatile JFrame frame;
+ static JTable table;
+
+ public static void main(String[] args) throws Exception {
+ Robot robot = new Robot();
+ SwingUtilities.invokeAndWait(bug6219960::createAndShowGUI);
+ robot.waitForIdle();
+ showModal("The tooltip should be showing. Press ok with mouse. And don't move it.");
+ robot.waitForIdle();
+ showModal("Now press ok and move the mouse inside the table (don't leave it).");
+ robot.waitForIdle();
+ }
+
+ private static void createAndShowGUI() {
+ ToolTipManager.sharedInstance().setDismissDelay(10 * 60 * 1000);
+ frame = new JFrame();
+ frame.setLocation(20, 20);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ JDesktopPane desk = new JDesktopPane();
+ JInternalFrame iframe = new JInternalFrame();
+ iframe.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE);
+ desk.add(iframe);
+ JButton save = new JButton();
+ save.setToolTipText("Wait for dialog to show.");
+ save.setText("Wait for the tooltip to show.");
+ JPanel panel = new JPanel(new GridLayout(1, 2));
+ panel.add(save);
+ table = createTable();
+ panel.add(new JScrollPane(table));
+ iframe.setContentPane(panel);
+ frame.getContentPane().add(desk);
+ frame.setSize(800, 600);
+ iframe.setSize(640, 480);
+ iframe.validate();
+ iframe.setVisible(true);
+ frame.validate();
+ frame.setVisible(true);
+ try {
+ iframe.setSelected(true);
+ } catch (Exception e) {
+ throw new AssertionError(e);
+ }
+
+ try {
+ Robot robot = new Robot();
+ Rectangle bounds = frame.getBounds();
+ int centerX = (int) (bounds.getX() + bounds.getWidth() / 6);
+ int centerY = (int) (bounds.getY() + bounds.getHeight() / 6);
+ robot.mouseMove(centerX, centerY);
+ } catch (AWTException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static void showModal(final String msg) throws Exception {
+
+ new Thread(() -> {
+
+ int timeout = 3000;
+ long endTime = System.currentTimeMillis() + timeout;
+
+ while (System.currentTimeMillis() <= endTime) {
+ if (pressOK(frame)) {
+ return;
+ }
+ }
+ throw new RuntimeException("Internal frame has not been found!");
+ }).start();
+
+ Thread.sleep(900);
+
+ SwingUtilities.invokeAndWait(() -> {
+ JOptionPane.showInternalMessageDialog(table, msg,
+ QUESTION,
+ JOptionPane.PLAIN_MESSAGE);
+ });
+ }
+
+ private static JTable createTable() {
+ DefaultTableModel model = new DefaultTableModel();
+ JTable table = new JTable(model);
+ table.setFillsViewportHeight(true);
+ return table;
+ }
+
+ private static boolean pressOK(Component comp) {
+
+ JInternalFrame internalFrame
+ = findModalInternalFrame(comp, QUESTION);
+
+ if (internalFrame == null) {
+ return false;
+ }
+
+ JButton button = (JButton) findButton(internalFrame);
+
+ if (button == null) {
+ return false;
+ }
+
+ try {
+ Robot robot = new Robot();
+ Point location = button.getLocationOnScreen();
+ Rectangle bounds = button.getBounds();
+ int centerX = (int) (location.getX() + bounds.getWidth() / 2);
+ int centerY = (int) (location.getY() + bounds.getHeight() / 2);
+ robot.mouseMove(centerX, centerY);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ } catch (IllegalComponentStateException ignore) {
+ return false;
+ } catch (AWTException e) {
+ throw new RuntimeException(e);
+ }
+ return true;
+ }
+
+ private static JInternalFrame findModalInternalFrame(Component comp, String title) {
+
+ if (comp instanceof JInternalFrame) {
+ JInternalFrame internalFrame = (JInternalFrame) comp;
+ if (internalFrame.getTitle().equals(title)) {
+ return (JInternalFrame) comp;
+ }
+ }
+
+ if (comp instanceof Container) {
+ Container cont = (Container) comp;
+ for (int i = 0; i < cont.getComponentCount(); i++) {
+ JInternalFrame result = findModalInternalFrame(cont.getComponent(i), title);
+ if (result != null) {
+ return result;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static JButton findButton(Component comp) {
+
+ if (comp instanceof JButton) {
+ return (JButton) comp;
+ }
+
+ if (comp instanceof Container) {
+ Container cont = (Container) comp;
+ for (int i = 0; i < cont.getComponentCount(); i++) {
+ JButton result = findButton(cont.getComponent(i));
+ if (result != null) {
+ return result;
+ }
+ }
+ }
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/UIDefaults/7180976/Pending.java Thu Jan 29 03:54:45 2015 +0000
@@ -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.
+ */
+
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+/**
+ * @test
+ * @bug 7180976
+ * @author Sergey Bylokhov
+ */
+public final class Pending implements Runnable {
+
+ private static volatile boolean passed;
+
+ public static void main(final String[] args) throws Exception {
+ SwingUtilities.invokeLater(new Pending());
+ Thread.sleep(10000);
+ if (!passed) {
+ throw new RuntimeException("Test failed");
+ }
+ }
+
+ @Override
+ public void run() {
+ UIManager.put("foobar", "Pending");
+ UIManager.get("foobar");
+ passed = true;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/transform/8062923/XslSubstringTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,104 @@
+/*
+ * 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 8062923 8062924
+ * @run testng XslSubstringTest
+ * @summary Test xsl substring function with negative, Inf and
+ * NaN length and few other use cases
+ */
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class XslSubstringTest {
+
+ final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test></test>";
+ final String xslPre = "<xsl:stylesheet version='1.0'"
+ + " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"
+ + "<xsl:output method='xml' indent='yes' omit-xml-declaration='yes'/>"
+ + "<xsl:template match='/'><t>";
+ final String xslPost = "</t></xsl:template></xsl:stylesheet>";
+
+ private String testTransform(String xsl) throws Exception {
+ //Prepare sources for transormation
+ Source src = new StreamSource(new StringReader(xml));
+ Source xslsrc = new StreamSource(new StringReader(xslPre + xsl + xslPost));
+ //Create factory, template and transformer
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Templates tmpl = tf.newTemplates(xslsrc);
+ Transformer t = tmpl.newTransformer();
+ //Prepare output stream
+ StringWriter xmlResultString = new StringWriter();
+ StreamResult xmlResultStream = new StreamResult(xmlResultString);
+ //Transform
+ t.transform(src, xmlResultStream);
+ return xmlResultString.toString().trim();
+ }
+
+ @Test
+ public void test8062923() throws Exception {
+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2,-1)\"/>|"),
+ "<t>||</t>");
+ }
+
+ @Test
+ public void test8062924() throws Exception {
+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2,-1 div 0)\"/>|"),
+ "<t>||</t>");
+ }
+
+ @Test
+ public void testGeneral1() throws Exception {
+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, 1)\"/>|"),
+ "<t>|s|</t>");
+ }
+
+ @Test
+ public void testGeneral2() throws Exception {
+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, 1 div 0)\"/>|"),
+ "<t>|sdf|</t>");
+ }
+
+ @Test
+ public void testGeneral3() throws Exception {
+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, -0 div 0)\"/>|"),
+ "<t>||</t>");
+ }
+
+ @Test
+ public void testGeneral4() throws Exception {
+ assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2, 0 div 0)\"/>|"),
+ "<t>||</t>");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/ws/8046817/GenerateEnumSchema.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,134 @@
+/*
+ * 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 8046817
+ * @summary schemagen fails to generate xsd for enum types
+ * @run main/othervm GenerateEnumSchema
+ */
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Paths;
+import java.util.Scanner;
+
+public class GenerateEnumSchema {
+
+ private static final String SCHEMA_OUTPUT_FILENAME = "schema1.xsd";
+ private static final File schemaOutputFile = new File(SCHEMA_OUTPUT_FILENAME);
+
+ public static void main(String[] args) throws Exception, IOException {
+ //Check schema generation for class type
+ runSchemaGen("TestClassType.java");
+ checkIfSchemaGenerated();
+ checkSchemaContent("<xs:complexType name=\"testClassType\">");
+ checkSchemaContent("<xs:element name=\"a\" type=\"xs:int\"/>");
+ schemaOutputFile.delete();
+ //Check schema generation for enum type
+ runSchemaGen("TestEnumType.java");
+ checkIfSchemaGenerated();
+ checkSchemaContent("<xs:simpleType name=\"testEnumType\">");
+ checkSchemaContent("<xs:enumeration value=\"ONE\"/>");
+ checkSchemaContent("<xs:enumeration value=\"TWO\"/>");
+ checkSchemaContent("<xs:enumeration value=\"THREE\"/>");
+ schemaOutputFile.delete();
+ }
+
+ private static void checkIfSchemaGenerated() {
+ if (!schemaOutputFile.exists()) {
+ throw new RuntimeException("FAIL:" + SCHEMA_OUTPUT_FILENAME + " was not generated by schemagen tool");
+ }
+ }
+
+ private static void checkSchemaContent(String exp_token) throws FileNotFoundException {
+ System.out.print("Check if generated schema contains '" + exp_token + "' string: ");
+ try (Scanner scanner = new Scanner(schemaOutputFile)) {
+ if (scanner.findWithinHorizon(exp_token, 0) != null) {
+ System.out.println("OK");
+ return;
+ }
+ }
+ System.out.println("FAIL");
+ throw new RuntimeException("The '" + exp_token + "' is not found in generated schema");
+
+ }
+
+ private static String getClassFilePath(String filename) {
+ String testSrc = System.getProperty("test.src");
+ if (testSrc == null) {
+ testSrc = ".";
+ }
+ return Paths.get(testSrc).resolve(filename).toString();
+ }
+
+ private static String getSchemagen() {
+ String javaHome = System.getProperty("java.home");
+ if (javaHome.endsWith("jre")) {
+ javaHome = new File(javaHome).getParent();
+ }
+ String schemagen = javaHome + File.separator + "bin" + File.separator + "schemagen";
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ schemagen = schemagen.concat(".exe");
+ }
+ return schemagen;
+ }
+
+ private static void logOutput(Process p) throws IOException {
+ BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String s = r.readLine();
+ while (s != null) {
+ System.out.println(s.trim());
+ s = r.readLine();
+ }
+ }
+
+ private static void runSchemaGen(String classFile) {
+ String schemagen = getSchemagen();
+
+ try {
+ System.out.println("Call to schemagen: " + schemagen + " " + classFile);
+ String[] schemagen_args = {
+ schemagen,
+ getClassFilePath(classFile)
+ };
+
+ ProcessBuilder pb = new ProcessBuilder(schemagen_args);
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+ logOutput(p);
+ int result = p.waitFor();
+ p.destroy();
+
+ if (result != 0) {
+ throw new RuntimeException("schemagen failed");
+ }
+ } catch (IOException | InterruptedException e) {
+ System.err.println("Can't run schemagen tool. Exception:");
+ e.printStackTrace(System.err);
+ throw new RuntimeException("Error launching schemagen tool");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/ws/8046817/TestClassType.java Thu Jan 29 03:54:45 2015 +0000
@@ -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.
+ */
+
+import javax.xml.bind.annotation.XmlType;
+
+@XmlType
+public class TestClassType {
+ public int a;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/ws/8046817/TestEnumType.java Thu Jan 29 03:54:45 2015 +0000
@@ -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.
+ */
+
+import javax.xml.bind.annotation.XmlEnum;
+
+@XmlEnum(String.class)
+public enum TestEnumType {
+ ONE, TWO, THREE
+}
--- a/jdk/test/jdk/nio/zipfs/ZipFSTester.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/jdk/nio/zipfs/ZipFSTester.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -45,6 +45,7 @@
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.spi.FileSystemProvider;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
@@ -67,7 +68,7 @@
*
* @test
* @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596
- * 7157656 8002390 7012868 7012856 8015728 8038500 8040059
+ * 7157656 8002390 7012868 7012856 8015728 8038500 8040059 8069211
* @summary Test Zip filesystem provider
* @run main ZipFSTester
* @run main/othervm/java.security.policy=test.policy ZipFSTester
@@ -89,6 +90,7 @@
test2(fs); // more tests
}
testTime(jarFile);
+ test8069211();
}
static void test0(FileSystem fs)
@@ -416,6 +418,29 @@
Files.delete(fsPath);
}
+ static void test8069211() throws Exception {
+ // create a new filesystem, copy this file into it
+ Map<String, Object> env = new HashMap<String, Object>();
+ env.put("create", "true");
+ Path fsPath = getTempPath();
+ try (FileSystem fs = newZipFileSystem(fsPath, env);) {
+ OutputStream out = Files.newOutputStream(fs.getPath("/foo"));
+ out.write("hello".getBytes());
+ out.close();
+ out.close();
+ }
+ try (FileSystem fs = newZipFileSystem(fsPath, new HashMap<String, Object>())) {
+ if (!Arrays.equals(Files.readAllBytes(fs.getPath("/foo")),
+ "hello".getBytes())) {
+ throw new RuntimeException("entry close() failed");
+ }
+ } catch (Exception x) {
+ throw new RuntimeException("entry close() failed", x);
+ } finally {
+ Files.delete(fsPath);
+ }
+ }
+
private static FileSystem newZipFileSystem(Path path, Map<String, ?> env)
throws Exception
{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JarUtils.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,119 @@
+/*
+ * 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 jdk.testlibrary;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+/**
+ * Common library for various test jar file utility functions.
+ */
+public final class JarUtils {
+
+ /**
+ * Create jar file with specified files.
+ */
+ public static void createJar(String dest, String... files)
+ throws IOException {
+ try (JarOutputStream jos = new JarOutputStream(
+ new FileOutputStream(dest), new Manifest())) {
+ for (String file : files) {
+ System.out.println(String.format("Adding %s to %s",
+ file, dest));
+
+ // add an archive entry, and write a file
+ jos.putNextEntry(new JarEntry(file));
+ try (FileInputStream fis = new FileInputStream(file)) {
+ fis.transferTo(jos);
+ }
+ }
+ }
+ System.out.println();
+ }
+
+ /**
+ * Add specified files to existing jar file.
+ */
+ public static void updateJar(String src, String dest, String... files)
+ throws IOException {
+ try (JarOutputStream jos = new JarOutputStream(
+ new FileOutputStream(dest))) {
+
+ // copy each old entry into destination unless the entry name
+ // is in the updated list
+ List<String> updatedFiles = new ArrayList<>();
+ try (JarFile srcJarFile = new JarFile(src)) {
+ Enumeration entries = srcJarFile.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = (JarEntry) entries.nextElement();
+ String name = entry.getName();
+ boolean found = false;
+ for (String file : files) {
+ if (name.equals(file)) {
+ updatedFiles.add(file);
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ System.out.println(String.format("Updating %s with %s",
+ dest, name));
+ jos.putNextEntry(new JarEntry(name));
+ try (FileInputStream fis = new FileInputStream(name)) {
+ fis.transferTo(jos);
+ }
+ } else {
+ System.out.println(String.format("Copying %s to %s",
+ name, dest));
+ jos.putNextEntry(entry);
+ srcJarFile.getInputStream(entry).transferTo(jos);
+ }
+ }
+ }
+
+ // append new files
+ for (String file : files) {
+ if (!updatedFiles.contains(file)) {
+ System.out.println(String.format("Adding %s with %s",
+ dest, file));
+ jos.putNextEntry(new JarEntry(file));
+ try (FileInputStream fis = new FileInputStream(file)) {
+ fis.transferTo(jos);
+ }
+ }
+ }
+ }
+ System.out.println();
+ }
+
+}
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.Map;
@@ -378,4 +379,40 @@
}
return cmd.toString().trim();
}
+
+ /**
+ * Executes a process, waits for it to finish, prints the process output
+ * to stdout, and returns the process output.
+ *
+ * The process will have exited before this method returns.
+ *
+ * @param cmds The command line to execute.
+ * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+ */
+ public static OutputAnalyzer executeCommand(String... cmds)
+ throws Throwable {
+ String cmdLine = Arrays.stream(cmds).collect(Collectors.joining(" "));
+ System.out.println("Command line: [" + cmdLine + "]");
+ OutputAnalyzer analyzer = ProcessTools.executeProcess(cmds);
+ System.out.println(analyzer.getOutput());
+ return analyzer;
+ }
+
+ /**
+ * Executes a process, waits for it to finish, prints the process output
+ * to stdout and returns the process output.
+ *
+ * The process will have exited before this method returns.
+ *
+ * @param pb The ProcessBuilder to execute.
+ * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+ */
+ public static OutputAnalyzer executeCommand(ProcessBuilder pb)
+ throws Throwable {
+ String cmdLine = pb.command().stream().collect(Collectors.joining(" "));
+ System.out.println("Command line: [" + cmdLine + "]");
+ OutputAnalyzer analyzer = ProcessTools.executeProcess(pb);
+ System.out.println(analyzer.getOutput());
+ return analyzer;
+ }
}
--- a/jdk/test/sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -48,14 +48,7 @@
static final File tmpFolder = new File(testClassesDir);
static {
- String javaHome = System.getProperty("java.home");
- if (javaHome.endsWith("jre")) {
- int index = javaHome.lastIndexOf(slash);
- if (index != -1)
- javaHome = javaHome.substring(0, index);
- }
-
- jar = javaHome + slash + "bin" + slash + "jar";
+ jar = System.getProperty("java.home") + slash + "bin" + slash + "jar";
}
public static void main(String[] args) throws Exception {
--- a/jdk/test/sun/misc/JarIndex/metaInfFilenames/Basic.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/misc/JarIndex/metaInfFilenames/Basic.java Thu Jan 29 03:54:45 2015 +0000
@@ -78,7 +78,6 @@
* URLClassLoader. Each request to the HTTP server is recorded to ensure
* only the correct amount of requests are being made.
*
- * Note: Needs jdk/lib/tools.jar in the classpath to compile and run.
*/
public class Basic {
@@ -160,14 +159,7 @@
static String jar;
static {
- String javaHome = System.getProperty("java.home");
- if (javaHome.endsWith("jre")) {
- int index = javaHome.lastIndexOf(slash);
- if (index != -1)
- javaHome = javaHome.substring(0, index);
- }
-
- jar = javaHome + slash+ "bin" + slash + "jar";
+ jar = System.getProperty("java.home") + slash+ "bin" + slash + "jar";
}
/* create the index */
--- a/jdk/test/sun/security/ec/TestEC.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/ec/TestEC.java Thu Jan 29 03:54:45 2015 +0000
@@ -59,6 +59,10 @@
public class TestEC {
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
// MD5 is used in this test case, don't disable MD5 algorithm.
Security.setProperty(
"jdk.certpath.disabledAlgorithms", "MD2, RSA keySize < 1024");
--- a/jdk/test/sun/security/krb5/config/ParseConfig.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/krb5/config/ParseConfig.java Thu Jan 29 03:54:45 2015 +0000
@@ -22,7 +22,7 @@
*/
/*
* @test
- * @bug 6319046
+ * @bug 6319046 8055045
* @compile -XDignore.symbol.file ParseConfig.java
* @run main/othervm ParseConfig
* @summary Problem with parsing krb5.conf
@@ -32,7 +32,8 @@
public class ParseConfig {
public static void main(String[] args) throws Exception {
- System.setProperty("java.security.krb5.conf", System.getProperty("test.src", ".") +"/krb5.conf");
+ System.setProperty("java.security.krb5.conf",
+ System.getProperty("test.src", ".") + "/krb5.conf");
Config config = Config.getInstance();
config.listTable();
@@ -44,5 +45,11 @@
expected + "\"");
}
}
+
+ // JDK-8055045: IOOBE when reading an empty value
+ config.get("empty1", "NOVAL.COM");
+ config.get("empty2", "NOVAL.COM");
+ config.get("quote1", "NOVAL.COM");
+ config.get("quote2", "NOVAL.COM");
}
}
--- a/jdk/test/sun/security/krb5/config/krb5.conf Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/krb5/config/krb5.conf Thu Jan 29 03:54:45 2015 +0000
@@ -27,3 +27,9 @@
}
}
+ NOVAL.COM = {
+ empty1 =
+ empty2 =.
+ quote1 = "
+ quote2 = '
+ }
--- a/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -43,6 +43,10 @@
private static String[] cmdArgs;
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
cmdArgs = args;
main(new ClientJSSEServerJSSE());
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/FileInputStreamPool/FileInputStreamPoolTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,166 @@
+/*
+ * 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 8047769
+ * @summary SecureRandom should be more frugal with file descriptors
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.Reference;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.Arrays;
+
+public class FileInputStreamPoolTest {
+
+ static final byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};
+
+ static void testCaching(File file) throws IOException {
+ InputStream in1 = TestProxy.FileInputStreamPool_getInputStream(file);
+ InputStream in2 = TestProxy.FileInputStreamPool_getInputStream(file);
+ assertTrue(in1 == in2,
+ "1st InputStream: " + in1 +
+ " is not same as 2nd: " + in2);
+
+ byte[] readBytes = new byte[bytes.length];
+ int nread = in1.read(readBytes);
+ assertTrue(bytes.length == nread,
+ "short read: " + nread +
+ " bytes of expected: " + bytes.length);
+ assertTrue(Arrays.equals(readBytes, bytes),
+ "readBytes: " + Arrays.toString(readBytes) +
+ " not equal to expected: " + Arrays.toString(bytes));
+ }
+
+ static void assertTrue(boolean test, String message) {
+ if (!test) {
+ throw new AssertionError(message);
+ }
+ }
+
+ static void processReferences() {
+ // make JVM process References
+ System.gc();
+ // help ReferenceHandler thread enqueue References
+ while (TestProxy.Reference_tryHandlePending(false)) {}
+ // help run Finalizers
+ System.runFinalization();
+ }
+
+ public static void main(String[] args) throws Exception {
+ // 1st create temporary file
+ File file = File.createTempFile("test", ".dat");
+ try (AutoCloseable acf = () -> {
+ // On Windows, failure to delete file is probably a consequence
+ // of the file still being opened - so the test should fail.
+ assertTrue(file.delete(),
+ "Can't delete: " + file + " (is it still open?)");
+ }) {
+ try (FileOutputStream out = new FileOutputStream(file)) {
+ out.write(bytes);
+ }
+
+ // test caching 1t time
+ testCaching(file);
+
+ processReferences();
+
+ // test caching 2nd time - this should only succeed if the stream
+ // is re-opened as a consequence of cleared WeakReference
+ testCaching(file);
+
+ processReferences();
+ }
+ }
+
+ /**
+ * A proxy for (package)private static methods:
+ * sun.security.provider.FileInputStreamPool.getInputStream
+ * java.lang.ref.Reference.tryHandlePending
+ */
+ static class TestProxy {
+ private static final Method getInputStreamMethod;
+ private static final Method tryHandlePendingMethod;
+
+ static {
+ try {
+ Class<?> fileInputStreamPoolClass =
+ Class.forName("sun.security.provider.FileInputStreamPool");
+ getInputStreamMethod =
+ fileInputStreamPoolClass.getDeclaredMethod(
+ "getInputStream", File.class);
+ getInputStreamMethod.setAccessible(true);
+
+ tryHandlePendingMethod = Reference.class.getDeclaredMethod(
+ "tryHandlePending", boolean.class);
+ tryHandlePendingMethod.setAccessible(true);
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+
+ static InputStream FileInputStreamPool_getInputStream(File file)
+ throws IOException {
+ try {
+ return (InputStream) getInputStreamMethod.invoke(null, file);
+ } catch (InvocationTargetException e) {
+ Throwable te = e.getTargetException();
+ if (te instanceof IOException) {
+ throw (IOException) te;
+ } else if (te instanceof RuntimeException) {
+ throw (RuntimeException) te;
+ } else if (te instanceof Error) {
+ throw (Error) te;
+ } else {
+ throw new UndeclaredThrowableException(te);
+ }
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static boolean Reference_tryHandlePending(boolean waitForNotify) {
+ try {
+ return (boolean) tryHandlePendingMethod
+ .invoke(null, waitForNotify);
+ } catch (InvocationTargetException e) {
+ Throwable te = e.getTargetException();
+ if (te instanceof RuntimeException) {
+ throw (RuntimeException) te;
+ } else if (te instanceof Error) {
+ throw (Error) te;
+ } else {
+ throw new UndeclaredThrowableException(te);
+ }
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/ClientHandshaker/LengthCheckTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,814 @@
+/*
+ * 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 8044860
+ * @summary Vectors and fixed length fields should be verified
+ * for allowed sizes.
+ * @run main/othervm LengthCheckTest
+ */
+
+/**
+ * A SSLEngine usage example which simplifies the presentation
+ * by removing the I/O and multi-threading concerns.
+ *
+ * The test creates two SSLEngines, simulating a client and server.
+ * The "transport" layer consists two byte buffers: think of them
+ * as directly connected pipes.
+ *
+ * Note, this is a *very* simple example: real code will be much more
+ * involved. For example, different threading and I/O models could be
+ * used, transport mechanisms could close unexpectedly, and so on.
+ *
+ * When this application runs, notice that several messages
+ * (wrap/unwrap) pass before any application data is consumed or
+ * produced. (For more information, please see the SSL/TLS
+ * specifications.) There may several steps for a successful handshake,
+ * so it's typical to see the following series of operations:
+ *
+ * client server message
+ * ====== ====== =======
+ * wrap() ... ClientHello
+ * ... unwrap() ClientHello
+ * ... wrap() ServerHello/Certificate
+ * unwrap() ... ServerHello/Certificate
+ * wrap() ... ClientKeyExchange
+ * wrap() ... ChangeCipherSpec
+ * wrap() ... Finished
+ * ... unwrap() ClientKeyExchange
+ * ... unwrap() ChangeCipherSpec
+ * ... unwrap() Finished
+ * ... wrap() ChangeCipherSpec
+ * ... wrap() Finished
+ * unwrap() ... ChangeCipherSpec
+ * unwrap() ... Finished
+ */
+
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.security.*;
+import java.nio.*;
+import java.util.List;
+import java.util.ArrayList;
+import sun.security.ssl.ProtocolVersion;
+
+public class LengthCheckTest {
+
+ /*
+ * Enables logging of the SSLEngine operations.
+ */
+ private static final boolean logging = true;
+
+ /*
+ * Enables the JSSE system debugging system property:
+ *
+ * -Djavax.net.debug=all
+ *
+ * This gives a lot of low-level information about operations underway,
+ * including specific handshake messages, and might be best examined
+ * after gaining some familiarity with this application.
+ */
+ private static final boolean debug = false;
+ private static final boolean dumpBufs = true;
+
+ private final SSLContext sslc;
+
+ private SSLEngine clientEngine; // client Engine
+ private ByteBuffer clientOut; // write side of clientEngine
+ private ByteBuffer clientIn; // read side of clientEngine
+
+ private SSLEngine serverEngine; // server Engine
+ private ByteBuffer serverOut; // write side of serverEngine
+ private ByteBuffer serverIn; // read side of serverEngine
+
+ private HandshakeTest handshakeTest;
+
+ /*
+ * For data transport, this example uses local ByteBuffers. This
+ * isn't really useful, but the purpose of this example is to show
+ * SSLEngine concepts, not how to do network transport.
+ */
+ private ByteBuffer cTOs; // "reliable" transport client->server
+ private ByteBuffer sTOc; // "reliable" transport server->client
+
+ /*
+ * The following is to set up the keystores.
+ */
+ private static final String pathToStores = "../../../../javax/net/ssl/etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String passwd = "passphrase";
+
+ private static final String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ private static final String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ // Define a few basic TLS record and message types we might need
+ private static final int TLS_RECTYPE_CCS = 0x14;
+ private static final int TLS_RECTYPE_ALERT = 0x15;
+ private static final int TLS_RECTYPE_HANDSHAKE = 0x16;
+ private static final int TLS_RECTYPE_APPDATA = 0x17;
+
+ private static final int TLS_HS_HELLO_REQUEST = 0x00;
+ private static final int TLS_HS_CLIENT_HELLO = 0x01;
+ private static final int TLS_HS_SERVER_HELLO = 0x02;
+ private static final int TLS_HS_CERTIFICATE = 0x0B;
+ private static final int TLS_HS_SERVER_KEY_EXCHG = 0x0C;
+ private static final int TLS_HS_CERT_REQUEST = 0x0D;
+ private static final int TLS_HS_SERVER_HELLO_DONE = 0x0E;
+ private static final int TLS_HS_CERT_VERIFY = 0x0F;
+ private static final int TLS_HS_CLIENT_KEY_EXCHG = 0x10;
+ private static final int TLS_HS_FINISHED = 0x14;
+
+ // We're not going to define all the alert types in TLS, just
+ // the ones we think we'll need to reference by name.
+ private static final int TLS_ALERT_LVL_WARNING = 0x01;
+ private static final int TLS_ALERT_LVL_FATAL = 0x02;
+
+ private static final int TLS_ALERT_UNEXPECTED_MSG = 0x0A;
+ private static final int TLS_ALERT_HANDSHAKE_FAILURE = 0x28;
+ private static final int TLS_ALERT_INTERNAL_ERROR = 0x50;
+
+ public interface HandshakeTest {
+ void execTest() throws Exception;
+ }
+
+ public final HandshakeTest servSendLongID = new HandshakeTest() {
+ @Override
+ public void execTest() throws Exception {
+ boolean gotException = false;
+ SSLEngineResult clientResult; // results from client's last op
+ SSLEngineResult serverResult; // results from server's last op
+
+ log("\n==== Test: Client receives 64-byte session ID ====");
+
+ // Send Client Hello
+ clientResult = clientEngine.wrap(clientOut, cTOs);
+ log("client wrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ cTOs.flip();
+ dumpByteBuffer("CLIENT-TO-SERVER", cTOs);
+
+ // Server consumes Client Hello
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
+ log("server unwrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ cTOs.compact();
+
+ // Server generates ServerHello/Cert/Done record
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ sTOc.flip();
+
+ // Intercept the ServerHello messages and instead send
+ // one that has a 64-byte session ID.
+ if (isTlsMessage(sTOc, TLS_RECTYPE_HANDSHAKE,
+ TLS_HS_SERVER_HELLO)) {
+ ArrayList<ByteBuffer> recList = splitRecord(sTOc);
+
+ // Use the original ServerHello as a template to craft one
+ // with a longer-than-allowed session ID.
+ ByteBuffer servHelloBuf =
+ createEvilServerHello(recList.get(0), 64);
+
+ recList.set(0, servHelloBuf);
+
+ // Now send each ByteBuffer (each being a complete
+ // TLS record) into the client-side unwrap.
+ for (ByteBuffer bBuf : recList) {
+ dumpByteBuffer("SERVER-TO-CLIENT", bBuf);
+ try {
+ clientResult = clientEngine.unwrap(bBuf, clientIn);
+ } catch (SSLProtocolException e) {
+ log("Received expected SSLProtocolException: " + e);
+ gotException = true;
+ }
+ log("client unwrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ }
+ } else {
+ dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
+ log("client unwrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ }
+ sTOc.compact();
+
+ // The Client should now send a TLS Alert
+ clientResult = clientEngine.wrap(clientOut, cTOs);
+ log("client wrap: ", clientResult);
+ runDelegatedTasks(clientResult, clientEngine);
+ cTOs.flip();
+ dumpByteBuffer("CLIENT-TO-SERVER", cTOs);
+
+ // At this point we can verify that both an exception
+ // was thrown and the proper action (a TLS alert) was
+ // sent back to the server.
+ if (gotException == false ||
+ !isTlsMessage(cTOs, TLS_RECTYPE_ALERT, TLS_ALERT_LVL_FATAL,
+ TLS_ALERT_INTERNAL_ERROR)) {
+ throw new SSLException(
+ "Client failed to throw Alert:fatal:internal_error");
+ }
+ }
+ };
+
+ public final HandshakeTest clientSendLongID = new HandshakeTest() {
+ @Override
+ public void execTest() throws Exception {
+ boolean gotException = false;
+ SSLEngineResult clientResult; // results from client's last op
+ SSLEngineResult serverResult; // results from server's last op
+
+ log("\n==== Test: Server receives 64-byte session ID ====");
+
+ // Send Client Hello
+ ByteBuffer evilClientHello = createEvilClientHello(64);
+ dumpByteBuffer("CLIENT-TO-SERVER", evilClientHello);
+
+ try {
+ // Server consumes Client Hello
+ serverResult = serverEngine.unwrap(evilClientHello, serverIn);
+ log("server unwrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ evilClientHello.compact();
+
+ // Under normal circumstances this should be a ServerHello
+ // But should throw an exception instead due to the invalid
+ // session ID.
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ sTOc.flip();
+ dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
+ } catch (SSLProtocolException ssle) {
+ log("Received expected SSLProtocolException: " + ssle);
+ gotException = true;
+ }
+
+ // We expect to see the server generate an alert here
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ sTOc.flip();
+ dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
+
+ // At this point we can verify that both an exception
+ // was thrown and the proper action (a TLS alert) was
+ // sent back to the client.
+ if (gotException == false ||
+ !isTlsMessage(sTOc, TLS_RECTYPE_ALERT, TLS_ALERT_LVL_FATAL,
+ TLS_ALERT_INTERNAL_ERROR)) {
+ throw new SSLException(
+ "Server failed to throw Alert:fatal:internal_error");
+ }
+ }
+ };
+
+
+ /*
+ * Main entry point for this test.
+ */
+ public static void main(String args[]) throws Exception {
+ List<LengthCheckTest> ccsTests = new ArrayList<>();
+
+ if (debug) {
+ System.setProperty("javax.net.debug", "ssl");
+ }
+
+ ccsTests.add(new LengthCheckTest("ServSendLongID"));
+ ccsTests.add(new LengthCheckTest("ClientSendLongID"));
+
+ for (LengthCheckTest test : ccsTests) {
+ test.runTest();
+ }
+
+ System.out.println("Test Passed.");
+ }
+
+ /*
+ * Create an initialized SSLContext to use for these tests.
+ */
+ public LengthCheckTest(String testName) throws Exception {
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ KeyStore ts = KeyStore.getInstance("JKS");
+
+ char[] passphrase = "passphrase".toCharArray();
+
+ ks.load(new FileInputStream(keyFilename), passphrase);
+ ts.load(new FileInputStream(trustFilename), passphrase);
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ts);
+
+ SSLContext sslCtx = SSLContext.getInstance("TLS");
+
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ sslc = sslCtx;
+
+ switch (testName) {
+ case "ServSendLongID":
+ handshakeTest = servSendLongID;
+ break;
+ case "ClientSendLongID":
+ handshakeTest = clientSendLongID;
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown test name: " +
+ testName);
+ }
+ }
+
+ /*
+ * Run the test.
+ *
+ * Sit in a tight loop, both engines calling wrap/unwrap regardless
+ * of whether data is available or not. We do this until both engines
+ * report back they are closed.
+ *
+ * The main loop handles all of the I/O phases of the SSLEngine's
+ * lifetime:
+ *
+ * initial handshaking
+ * application data transfer
+ * engine closing
+ *
+ * One could easily separate these phases into separate
+ * sections of code.
+ */
+ private void runTest() throws Exception {
+ boolean dataDone = false;
+
+ createSSLEngines();
+ createBuffers();
+
+ handshakeTest.execTest();
+ }
+
+ /*
+ * Using the SSLContext created during object creation,
+ * create/configure the SSLEngines we'll use for this test.
+ */
+ private void createSSLEngines() throws Exception {
+ /*
+ * Configure the serverEngine to act as a server in the SSL/TLS
+ * handshake. Also, require SSL client authentication.
+ */
+ serverEngine = sslc.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+ serverEngine.setNeedClientAuth(false);
+
+ /*
+ * Similar to above, but using client mode instead.
+ */
+ clientEngine = sslc.createSSLEngine("client", 80);
+ clientEngine.setUseClientMode(true);
+
+ // In order to make a test that will be backwards compatible
+ // going back to JDK 5, force the handshake to be TLS 1.0 and
+ // use one of the older cipher suites.
+ clientEngine.setEnabledProtocols(new String[]{"TLSv1"});
+ clientEngine.setEnabledCipherSuites(
+ new String[]{"TLS_RSA_WITH_AES_128_CBC_SHA"});
+ }
+
+ /*
+ * Create and size the buffers appropriately.
+ */
+ private void createBuffers() {
+
+ /*
+ * We'll assume the buffer sizes are the same
+ * between client and server.
+ */
+ SSLSession session = clientEngine.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ /*
+ * We'll make the input buffers a bit bigger than the max needed
+ * size, so that unwrap()s following a successful data transfer
+ * won't generate BUFFER_OVERFLOWS.
+ *
+ * We'll use a mix of direct and indirect ByteBuffers for
+ * tutorial purposes only. In reality, only use direct
+ * ByteBuffers when they give a clear performance enhancement.
+ */
+ clientIn = ByteBuffer.allocate(appBufferMax + 50);
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
+
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
+
+ clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
+ serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes());
+ }
+
+ /*
+ * If the result indicates that we have outstanding tasks to do,
+ * go ahead and run them in this thread.
+ */
+ private static void runDelegatedTasks(SSLEngineResult result,
+ SSLEngine engine) throws Exception {
+
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ log("\trunning delegated task...");
+ runnable.run();
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ log("\tnew HandshakeStatus: " + hsStatus);
+ }
+ }
+
+ private static boolean isEngineClosed(SSLEngine engine) {
+ return (engine.isOutboundDone() && engine.isInboundDone());
+ }
+
+ /*
+ * Simple check to make sure everything came across as expected.
+ */
+ private static void checkTransfer(ByteBuffer a, ByteBuffer b)
+ throws Exception {
+ a.flip();
+ b.flip();
+
+ if (!a.equals(b)) {
+ throw new Exception("Data didn't transfer cleanly");
+ } else {
+ log("\tData transferred cleanly");
+ }
+
+ a.position(a.limit());
+ b.position(b.limit());
+ a.limit(a.capacity());
+ b.limit(b.capacity());
+ }
+
+ /*
+ * Logging code
+ */
+ private static boolean resultOnce = true;
+
+ private static void log(String str, SSLEngineResult result) {
+ if (!logging) {
+ return;
+ }
+ if (resultOnce) {
+ resultOnce = false;
+ System.out.println("The format of the SSLEngineResult is: \n" +
+ "\t\"getStatus() / getHandshakeStatus()\" +\n" +
+ "\t\"bytesConsumed() / bytesProduced()\"\n");
+ }
+ HandshakeStatus hsStatus = result.getHandshakeStatus();
+ log(str +
+ result.getStatus() + "/" + hsStatus + ", " +
+ result.bytesConsumed() + "/" + result.bytesProduced() +
+ " bytes");
+ if (hsStatus == HandshakeStatus.FINISHED) {
+ log("\t...ready for application data");
+ }
+ }
+
+ private static void log(String str) {
+ if (logging) {
+ System.out.println(str);
+ }
+ }
+
+ /**
+ * Split a record consisting of multiple TLS handshake messages
+ * into individual TLS records, each one in a ByteBuffer of its own.
+ *
+ * @param tlsRecord A ByteBuffer containing the tls record data.
+ * The position of the buffer should be at the first byte
+ * in the TLS record data.
+ *
+ * @return An ArrayList consisting of one or more ByteBuffers. Each
+ * ByteBuffer will contain a single TLS record with one message.
+ * That message will be taken from the input record. The order
+ * of the messages in the ArrayList will be the same as they
+ * were in the input record.
+ */
+ private ArrayList<ByteBuffer> splitRecord(ByteBuffer tlsRecord) {
+ SSLSession session = clientEngine.getSession();
+ int netBufferMax = session.getPacketBufferSize();
+ ArrayList<ByteBuffer> recordList = new ArrayList<>();
+
+ if (tlsRecord.hasRemaining()) {
+ int type = Byte.toUnsignedInt(tlsRecord.get());
+ byte ver_major = tlsRecord.get();
+ byte ver_minor = tlsRecord.get();
+ int recLen = Short.toUnsignedInt(tlsRecord.getShort());
+ byte[] newMsgData = null;
+ while (tlsRecord.hasRemaining()) {
+ ByteBuffer newRecord = ByteBuffer.allocateDirect(netBufferMax);
+ switch (type) {
+ case TLS_RECTYPE_CCS:
+ case TLS_RECTYPE_ALERT:
+ case TLS_RECTYPE_APPDATA:
+ // None of our tests have multiple non-handshake
+ // messages coalesced into a single record.
+ break;
+ case TLS_RECTYPE_HANDSHAKE:
+ newMsgData = getHandshakeMessage(tlsRecord);
+ break;
+ }
+
+ // Put a new TLS record on the destination ByteBuffer
+ newRecord.put((byte)type);
+ newRecord.put(ver_major);
+ newRecord.put(ver_minor);
+ newRecord.putShort((short)newMsgData.length);
+
+ // Now add the message content itself and attach to the
+ // returned ArrayList
+ newRecord.put(newMsgData);
+ newRecord.flip();
+ recordList.add(newRecord);
+ }
+ }
+
+ return recordList;
+ }
+
+ private static ByteBuffer createEvilClientHello(int sessIdLen) {
+ ByteBuffer newRecord = ByteBuffer.allocateDirect(4096);
+
+ // Lengths will initially be place holders until we determine the
+ // finished length of the ByteBuffer. Then we'll go back and scribble
+ // in the correct lengths.
+
+ newRecord.put((byte)TLS_RECTYPE_HANDSHAKE); // Record type
+ newRecord.putShort((short)0x0301); // Protocol (TLS 1.0)
+ newRecord.putShort((short)0); // Length place holder
+
+ newRecord.putInt(TLS_HS_CLIENT_HELLO << 24); // HS type and length
+ newRecord.putShort((short)0x0301);
+ newRecord.putInt((int)(System.currentTimeMillis() / 1000));
+ SecureRandom sr = new SecureRandom();
+ byte[] randBuf = new byte[28];
+ sr.nextBytes(randBuf);
+ newRecord.put(randBuf); // Client Random
+ newRecord.put((byte)sessIdLen); // Session ID length
+ if (sessIdLen > 0) {
+ byte[] sessId = new byte[sessIdLen];
+ sr.nextBytes(sessId);
+ newRecord.put(sessId); // Session ID
+ }
+ newRecord.putShort((short)2); // 2 bytes of ciphers
+ newRecord.putShort((short)0x002F); // TLS_RSA_AES_CBC_SHA
+ newRecord.putShort((short)0x0100); // only null compression
+ newRecord.putShort((short)5); // 5 bytes of extensions
+ newRecord.putShort((short)0xFF01); // Renegotiation info
+ newRecord.putShort((short)1);
+ newRecord.put((byte)0); // No reneg info exts
+
+ // Go back and fill in the correct length values for the record
+ // and handshake message headers.
+ int recordLength = newRecord.position();
+ newRecord.putShort(3, (short)(recordLength - 5));
+ int newTypeAndLen = (newRecord.getInt(5) & 0xFF000000) |
+ ((recordLength - 9) & 0x00FFFFFF);
+ newRecord.putInt(5, newTypeAndLen);
+
+ newRecord.flip();
+ return newRecord;
+ }
+
+ private static ByteBuffer createEvilServerHello(ByteBuffer origHello,
+ int newSessIdLen) {
+ if (newSessIdLen < 0 || newSessIdLen > Byte.MAX_VALUE) {
+ throw new RuntimeException("Length must be 0 <= X <= 127");
+ }
+
+ ByteBuffer newRecord = ByteBuffer.allocateDirect(4096);
+ // Copy the bytes from the old hello to the new up to the session ID
+ // field. We will go back later and fill in a new length field in
+ // the record header. This includes the record header (5 bytes), the
+ // Handshake message header (4 bytes), protocol version (2 bytes),
+ // and the random (32 bytes).
+ ByteBuffer scratchBuffer = origHello.slice();
+ scratchBuffer.limit(43);
+ newRecord.put(scratchBuffer);
+
+ // Advance the position in the originial hello buffer past the
+ // session ID.
+ origHello.position(43);
+ int origIDLen = Byte.toUnsignedInt(origHello.get());
+ if (origIDLen > 0) {
+ // Skip over the session ID
+ origHello.position(origHello.position() + origIDLen);
+ }
+
+ // Now add our own sessionID to the new record
+ SecureRandom sr = new SecureRandom();
+ byte[] sessId = new byte[newSessIdLen];
+ sr.nextBytes(sessId);
+ newRecord.put((byte)newSessIdLen);
+ newRecord.put(sessId);
+
+ // Create another slice in the original buffer, based on the position
+ // past the session ID. Copy the remaining bytes into the new
+ // hello buffer. Then go back and fix up the length
+ newRecord.put(origHello.slice());
+
+ // Go back and fill in the correct length values for the record
+ // and handshake message headers.
+ int recordLength = newRecord.position();
+ newRecord.putShort(3, (short)(recordLength - 5));
+ int newTypeAndLen = (newRecord.getInt(5) & 0xFF000000) |
+ ((recordLength - 9) & 0x00FFFFFF);
+ newRecord.putInt(5, newTypeAndLen);
+
+ newRecord.flip();
+ return newRecord;
+ }
+
+ /**
+ * Look at an incoming TLS record and see if it is the desired
+ * record type, and where appropriate the correct subtype.
+ *
+ * @param srcRecord The input TLS record to be evaluated. This
+ * method will only look at the leading message if multiple
+ * TLS handshake messages are coalesced into a single record.
+ * @param reqRecType The requested TLS record type
+ * @param recParams Zero or more integer sub type fields. For CCS
+ * and ApplicationData, no params are used. For handshake records,
+ * one value corresponding to the HandshakeType is required.
+ * For Alerts, two values corresponding to AlertLevel and
+ * AlertDescription are necessary.
+ *
+ * @return true if the proper handshake message is the first one
+ * in the input record, false otherwise.
+ */
+ private boolean isTlsMessage(ByteBuffer srcRecord, int reqRecType,
+ int... recParams) {
+ boolean foundMsg = false;
+
+ if (srcRecord.hasRemaining()) {
+ srcRecord.mark();
+
+ // Grab the fields from the TLS Record
+ int recordType = Byte.toUnsignedInt(srcRecord.get());
+ byte ver_major = srcRecord.get();
+ byte ver_minor = srcRecord.get();
+ int recLen = Short.toUnsignedInt(srcRecord.getShort());
+
+ if (recordType == reqRecType) {
+ // For any zero-length recParams, making sure the requested
+ // type is sufficient.
+ if (recParams.length == 0) {
+ foundMsg = true;
+ } else {
+ switch (recordType) {
+ case TLS_RECTYPE_CCS:
+ case TLS_RECTYPE_APPDATA:
+ // We really shouldn't find ourselves here, but
+ // if someone asked for these types and had more
+ // recParams we can ignore them.
+ foundMsg = true;
+ break;
+ case TLS_RECTYPE_ALERT:
+ // Needs two params, AlertLevel and AlertDescription
+ if (recParams.length != 2) {
+ throw new RuntimeException(
+ "Test for Alert requires level and desc.");
+ } else {
+ int level = Byte.toUnsignedInt(srcRecord.get());
+ int desc = Byte.toUnsignedInt(srcRecord.get());
+ if (level == recParams[0] &&
+ desc == recParams[1]) {
+ foundMsg = true;
+ }
+ }
+ break;
+ case TLS_RECTYPE_HANDSHAKE:
+ // Needs one parameter, HandshakeType
+ if (recParams.length != 1) {
+ throw new RuntimeException(
+ "Test for Handshake requires only HS type");
+ } else {
+ // Go into the first handhshake message in the
+ // record and grab the handshake message header.
+ // All we need to do is parse out the leading
+ // byte.
+ int msgHdr = srcRecord.getInt();
+ int msgType = (msgHdr >> 24) & 0x000000FF;
+ if (msgType == recParams[0]) {
+ foundMsg = true;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ srcRecord.reset();
+ }
+
+ return foundMsg;
+ }
+
+ private byte[] getHandshakeMessage(ByteBuffer srcRecord) {
+ // At the start of this routine, the position should be lined up
+ // at the first byte of a handshake message. Mark this location
+ // so we can return to it after reading the type and length.
+ srcRecord.mark();
+ int msgHdr = srcRecord.getInt();
+ int type = (msgHdr >> 24) & 0x000000FF;
+ int length = msgHdr & 0x00FFFFFF;
+
+ // Create a byte array that has enough space for the handshake
+ // message header and body.
+ byte[] data = new byte[length + 4];
+ srcRecord.reset();
+ srcRecord.get(data, 0, length + 4);
+
+ return (data);
+ }
+
+ /**
+ * Hex-dumps a ByteBuffer to stdout.
+ */
+ private static void dumpByteBuffer(String header, ByteBuffer bBuf) {
+ if (dumpBufs == false) {
+ return;
+ }
+
+ int bufLen = bBuf.remaining();
+ if (bufLen > 0) {
+ bBuf.mark();
+
+ // We expect the position of the buffer to be at the
+ // beginning of a TLS record. Get the type, version and length.
+ int type = Byte.toUnsignedInt(bBuf.get());
+ int ver_major = Byte.toUnsignedInt(bBuf.get());
+ int ver_minor = Byte.toUnsignedInt(bBuf.get());
+ int recLen = Short.toUnsignedInt(bBuf.getShort());
+ ProtocolVersion pv = ProtocolVersion.valueOf(ver_major, ver_minor);
+
+ log("===== " + header + " (" + tlsRecType(type) + " / " +
+ pv + " / " + bufLen + " bytes) =====");
+ bBuf.reset();
+ for (int i = 0; i < bufLen; i++) {
+ if (i != 0 && i % 16 == 0) {
+ System.out.print("\n");
+ }
+ System.out.format("%02X ", bBuf.get(i));
+ }
+ log("\n===============================================");
+ bBuf.reset();
+ }
+ }
+
+ private static String tlsRecType(int type) {
+ switch (type) {
+ case 20:
+ return "Change Cipher Spec";
+ case 21:
+ return "Alert";
+ case 22:
+ return "Handshake";
+ case 23:
+ return "Application Data";
+ default:
+ return ("Unknown (" + type + ")");
+ }
+ }
+}
--- a/jdk/test/sun/security/ssl/ProtocolVersion/HttpsProtocols.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/ssl/ProtocolVersion/HttpsProtocols.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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 @@
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
+import java.security.Security;
public class HttpsProtocols implements HostnameVerifier {
@@ -177,6 +178,10 @@
volatile Exception clientException = null;
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
String keyFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + keyStoreFile;
--- a/jdk/test/sun/security/ssl/SSLContextImpl/CustomizedDefaultProtocols.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/ssl/SSLContextImpl/CustomizedDefaultProtocols.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -35,6 +35,7 @@
import javax.net.*;
import javax.net.ssl.*;
import java.util.Arrays;
+import java.security.Security;
public class CustomizedDefaultProtocols {
static enum ContextVersion {
@@ -93,6 +94,10 @@
}
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
boolean failed = false;
for (ContextVersion cv : ContextVersion.values()) {
System.out.println("Checking SSLContext of " + cv.contextVersion);
--- a/jdk/test/sun/security/ssl/SSLContextImpl/DefaultEnabledProtocols.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/ssl/SSLContextImpl/DefaultEnabledProtocols.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -34,6 +34,7 @@
import javax.net.*;
import javax.net.ssl.*;
import java.util.Arrays;
+import java.security.Security;
public class DefaultEnabledProtocols {
static enum ContextVersion {
@@ -92,6 +93,10 @@
}
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
boolean failed = false;
for (ContextVersion cv : ContextVersion.values()) {
System.out.println("Checking SSLContext of " + cv.contextVersion);
--- a/jdk/test/sun/security/ssl/SSLContextImpl/NoOldVersionContext.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/ssl/SSLContextImpl/NoOldVersionContext.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -35,6 +35,7 @@
import javax.net.*;
import javax.net.ssl.*;
import java.util.Arrays;
+import java.security.Security;
public class NoOldVersionContext {
static enum ContextVersion {
@@ -93,6 +94,10 @@
}
public static void main(String[] args) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
+
boolean failed = false;
for (ContextVersion cv : ContextVersion.values()) {
System.out.println("Checking SSLContext of " + cv.contextVersion);
--- a/jdk/test/sun/security/ssl/SSLEngineImpl/DelegatedTaskWrongException.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/ssl/SSLEngineImpl/DelegatedTaskWrongException.java Thu Jan 29 03:54:45 2015 +0000
@@ -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
@@ -115,6 +115,9 @@
}
public static void main(String args[]) throws Exception {
+ // reset the security property to make sure that the algorithms
+ // and keys used in this test are not disabled.
+ Security.setProperty("jdk.tls.disabledAlgorithms", "");
DelegatedTaskWrongException test;
--- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,12 @@
static final String defaultPolicyId = "2.3.4.5";
- static class Handler implements HttpHandler {
+ static class Handler implements HttpHandler, AutoCloseable {
+
+ private final HttpServer httpServer;
+ private final String keystore;
+
+ @Override
public void handle(HttpExchange t) throws IOException {
int len = 0;
for (String h: t.getRequestHeaders().keySet()) {
@@ -136,7 +141,9 @@
// Write TSResponse
System.err.println("\nResponse\n===================");
KeyStore ks = KeyStore.getInstance("JKS");
- ks.load(new FileInputStream(TSKS), "changeit".toCharArray());
+ try (FileInputStream fis = new FileInputStream(keystore)) {
+ ks.load(fis, "changeit".toCharArray());
+ }
String alias = "ts";
if (path == 6) alias = "tsbad1";
@@ -240,33 +247,74 @@
return out.toByteArray();
}
+
+ private Handler(HttpServer httpServer, String keystore) {
+ this.httpServer = httpServer;
+ this.keystore = keystore;
+ }
+
+ /**
+ * Initialize TSA instance.
+ *
+ * Extended Key Info extension of certificate that is used for
+ * signing TSA responses should contain timeStamping value.
+ */
+ static Handler init(int port, String keystore) throws IOException {
+ HttpServer httpServer = HttpServer.create(
+ new InetSocketAddress(port), 0);
+ Handler tsa = new Handler(httpServer, keystore);
+ httpServer.createContext("/", tsa);
+ return tsa;
+ }
+
+ /**
+ * Start TSA service.
+ */
+ void start() {
+ httpServer.start();
+ }
+
+ /**
+ * Stop TSA service.
+ */
+ void stop() {
+ httpServer.stop(0);
+ }
+
+ /**
+ * Return server port number.
+ */
+ int getPort() {
+ return httpServer.getAddress().getPort();
+ }
+
+ @Override
+ public void close() throws Exception {
+ stop();
+ }
}
public static void main(String[] args) throws Exception {
-
- Handler h = new Handler();
- HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
- int port = server.getAddress().getPort();
- HttpContext ctx = server.createContext("/", h);
- server.start();
+ try (Handler tsa = Handler.init(0, TSKS);) {
+ tsa.start();
+ int port = tsa.getPort();
- String cmd = null;
- // Use -J-Djava.security.egd=file:/dev/./urandom to speed up
- // nonce generation in timestamping request. Not avaibale on
- // Windows and defaults to thread seed generator, not too bad.
- if (System.getProperty("java.home").endsWith("jre")) {
- cmd = System.getProperty("java.home") + "/../bin/jarsigner";
- } else {
- cmd = System.getProperty("java.home") + "/bin/jarsigner";
- }
+ String cmd;
+ // Use -J-Djava.security.egd=file:/dev/./urandom to speed up
+ // nonce generation in timestamping request. Not avaibale on
+ // Windows and defaults to thread seed generator, not too bad.
+ if (System.getProperty("java.home").endsWith("jre")) {
+ cmd = System.getProperty("java.home") + "/../bin/jarsigner";
+ } else {
+ cmd = System.getProperty("java.home") + "/bin/jarsigner";
+ }
- cmd += " " + System.getProperty("test.tool.vm.opts") +
- " -J-Djava.security.egd=file:/dev/./urandom" +
- " -debug -keystore " + TSKS + " -storepass changeit" +
- " -tsa http://localhost:" + port + "/%d" +
- " -signedjar new_%d.jar " + JAR + " old";
+ cmd += " " + System.getProperty("test.tool.vm.opts")
+ + " -J-Djava.security.egd=file:/dev/./urandom"
+ + " -debug -keystore " + TSKS + " -storepass changeit"
+ + " -tsa http://localhost:" + port + "/%d"
+ + " -signedjar new_%d.jar " + JAR + " old";
- try {
if (args.length == 0) { // Run this test
jarsigner(cmd, 0, true); // Success, normal call
jarsigner(cmd, 1, false); // These 4 should fail
@@ -287,8 +335,6 @@
System.err.println("Press Enter to quit server");
System.in.read();
}
- } finally {
- server.stop(0);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary The test signs and verifies a jar file with -tsacert option
+ * @library /lib/testlibrary
+ * @run main TsacertOptionTest
+ */
+public class TsacertOptionTest {
+
+ private static final String FS = System.getProperty("file.separator");
+ private static final String JAVA_HOME = System.getProperty("java.home");
+ private static final String KEYTOOL = JAVA_HOME + FS + "bin" + FS
+ + "keytool";
+ private static final String JARSIGNER = JAVA_HOME + FS + "bin" + FS
+ + "jarsigner";
+ private static final String UNSIGNED_JARFILE = "unsigned.jar";
+ private static final String SIGNED_JARFILE = "signed.jar";
+ private static final String FILENAME = TsacertOptionTest.class.getName()
+ + ".txt";
+ private static final String PASSWORD = "changeit";
+ private static final String KEYSTORE = "ks.jks";
+ private static final String SIGNING_KEY_ALIAS = "sign_alias";
+ private static final String TSA_KEY_ALIAS = "ts";
+ private static final String KEY_ALG = "RSA";
+ private static final int KEY_SIZE = 2048;
+ private static final int VALIDITY = 365;
+ private static final String WARNING = "Warning:";
+ private static final String JAR_SIGNED = "jar signed.";
+ private static final String JAR_VERIFIED = "jar verified.";
+
+ /**
+ * The test signs and verifies a jar file with -tsacert option,
+ * and checks that no warning was shown.
+ * A certificate that is addressed in -tsacert option contains URL to TSA
+ * in Subject Information Access extension.
+ */
+ public static void main(String[] args) throws Throwable {
+ TsacertOptionTest test = new TsacertOptionTest();
+ test.start();
+ }
+
+ void start() throws Throwable {
+ // create a jar file that contains one file
+ Utils.createFiles(FILENAME);
+ JarUtils.createJar(UNSIGNED_JARFILE, FILENAME);
+
+ // look for free network port for TSA service
+ int port = jdk.testlibrary.Utils.getFreePort();
+ String host = jdk.testlibrary.Utils.getHostname();
+ String tsaUrl = "http://" + host + ":" + port;
+
+ // create key pair for jar signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", SIGNING_KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Test",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // create key pair for TSA service
+ // SubjectInfoAccess extension contains URL to TSA service
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-v",
+ "-alias", TSA_KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=TSA",
+ "-ext", "ExtendedkeyUsage:critical=timeStamping",
+ "-ext", "SubjectInfoAccess=timeStamping:URI:" + tsaUrl,
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ try (TimestampCheck.Handler tsa = TimestampCheck.Handler.init(port,
+ KEYSTORE);) {
+
+ // start TSA
+ tsa.start();
+
+ // sign jar file
+ // specify -tsadigestalg option because
+ // TSA server uses SHA-1 digest algorithm
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ "-tsacert", TSA_KEY_ALIAS,
+ "-tsadigestalg", "SHA-1",
+ UNSIGNED_JARFILE,
+ SIGNING_KEY_ALIAS);
+
+ analyzer.shouldHaveExitValue(0);
+ analyzer.stdoutShouldNotContain(WARNING);
+ analyzer.shouldContain(JAR_SIGNED);
+
+ // verify signed jar
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verbose",
+ "-verify",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ SIGNED_JARFILE);
+
+ analyzer.shouldHaveExitValue(0);
+ analyzer.stdoutShouldNotContain(WARNING);
+ analyzer.shouldContain(JAR_VERIFIED);
+ }
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/Utils.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.File;
+import java.io.IOException;
+
+/**
+ * Helper class.
+ */
+public class Utils {
+
+ static void createFiles(String... filenames) throws IOException {
+ for (String filename : filenames) {
+ new File(filename).createNewFile();
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/AliasNotInStoreTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Test for aliasNotInStore warning
+ * @library /lib/testlibrary ../
+ * @run main AliasNotInStoreTest
+ */
+public class AliasNotInStoreTest extends Test {
+
+ /**
+ * The test signs and verifies a jar that contains signed entries
+ * that are not signed by any alias in keystore (aliasNotInStore).
+ * Warning message is expected.
+ */
+ public static void main(String[] args) throws Throwable {
+ AliasNotInStoreTest test = new AliasNotInStoreTest();
+ test.start();
+ }
+
+ private void start() throws Throwable {
+ Utils.createFiles(FIRST_FILE, SECOND_FILE);
+ System.out.println(String.format("Create a %s that contains %s",
+ new Object[]{UNSIGNED_JARFILE, FIRST_FILE}));
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // create first key pair for signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", FIRST_KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", BOTH_KEYS_KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=First",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // create second key pair for signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", SECOND_KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", BOTH_KEYS_KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Second",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // sign jar with first key
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-keystore", BOTH_KEYS_KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ FIRST_KEY_ALIAS);
+
+ checkSigning(analyzer);
+
+ System.out.println(String.format("Copy %s to %s, and add %s",
+ new Object[] {SIGNED_JARFILE, UPDATED_SIGNED_JARFILE,
+ SECOND_FILE}));
+
+ JarUtils.updateJar(SIGNED_JARFILE, UPDATED_SIGNED_JARFILE, SECOND_FILE);
+
+ // sign jar with second key
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-keystore", BOTH_KEYS_KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ UPDATED_SIGNED_JARFILE,
+ SECOND_KEY_ALIAS);
+
+ checkSigning(analyzer);
+
+ // create keystore that contains only first key
+ ProcessTools.executeCommand(KEYTOOL,
+ "-importkeystore",
+ "-srckeystore", BOTH_KEYS_KEYSTORE,
+ "-srcalias", FIRST_KEY_ALIAS,
+ "-srcstorepass", PASSWORD,
+ "-srckeypass", PASSWORD,
+ "-destkeystore", FIRST_KEY_KEYSTORE,
+ "-destalias", FIRST_KEY_ALIAS,
+ "-deststorepass", PASSWORD,
+ "-destkeypass", PASSWORD).shouldHaveExitValue(0);
+
+ // verify jar with keystore that contains only first key in strict mode,
+ // so there is signed entry (FirstClass.class) that is not signed
+ // by any alias in the keystore
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-keystore", FIRST_KEY_KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ UPDATED_SIGNED_JARFILE);
+
+ checkVerifying(analyzer, 0, CHAIN_NOT_VALIDATED_VERIFYING_WARNING,
+ ALIAS_NOT_IN_STORE_VERIFYING_WARNING);
+
+ // verify jar with keystore that contains only first key in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-strict",
+ "-keystore", FIRST_KEY_KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ UPDATED_SIGNED_JARFILE);
+
+ int expectedExitCode = ALIAS_NOT_IN_STORE_EXIT_CODE
+ + CHAIN_NOT_VALIDATED_EXIT_CODE;
+ checkVerifying(analyzer, expectedExitCode,
+ CHAIN_NOT_VALIDATED_VERIFYING_WARNING,
+ ALIAS_NOT_IN_STORE_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Test for badExtendedKeyUsage warning
+ * @library /lib/testlibrary ../
+ * @run main BadExtendedKeyUsageTest
+ */
+public class BadExtendedKeyUsageTest extends Test {
+
+ /**
+ * The test signs and verifies a jar that contains entries
+ * whose signer certificate's ExtendedKeyUsage extension
+ * doesn't allow code signing (badExtendedKeyUsage).
+ * Warning message is expected.
+ */
+ public static void main(String[] args) throws Throwable {
+ BadExtendedKeyUsageTest test = new BadExtendedKeyUsageTest();
+ test.start();
+ }
+
+ private void start() throws Throwable {
+ // create a jar file that contains one class file
+ Utils.createFiles(FIRST_FILE);
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // create a certificate whose signer certificate's
+ // ExtendedKeyUsage extension doesn't allow code signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Test",
+ "-ext", "ExtendedkeyUsage=serverAuth",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // sign jar
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkSigning(analyzer, BAD_EXTENDED_KEY_USAGE_SIGNING_WARNING);
+
+ // verify signed jar
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE);
+
+ checkVerifying(analyzer, 0, BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING);
+
+ // verity signed jar in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE);
+
+ checkVerifying(analyzer, BAD_EXTENDED_KEY_USAGE_EXIT_CODE,
+ BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Test for badKeyUsage warning
+ * @library /lib/testlibrary ../
+ * @ignore until 8026393 is fixed
+ * @run main BadKeyUsageTest
+ */
+public class BadKeyUsageTest extends Test {
+
+ /**
+ * The test signs and verifies a jar that contains entries
+ * whose signer certificate's KeyUsage extension
+ * doesn't allow code signing (badKeyUsage).
+ * Warning message is expected.
+ */
+ public static void main(String[] args) throws Throwable {
+ BadKeyUsageTest test = new BadKeyUsageTest();
+ test.start();
+ }
+
+ private void start() throws Throwable {
+ // create a jar file that contains one class file
+ Utils.createFiles(FIRST_FILE);
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // create a certificate whose signer certificate's KeyUsage extension
+ // doesn't allow code signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Test",
+ "-ext", "KeyUsage=keyAgreement",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // sign jar
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkSigning(analyzer, BAD_KEY_USAGE_SIGNING_WARNING);
+
+ // verify signed jar
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE);
+
+ checkVerifying(analyzer, 0, BAD_KEY_USAGE_VERIFYING_WARNING);
+
+ // verify signed jar in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE);
+
+ checkVerifying(analyzer, BAD_KEY_USAGE_EXIT_CODE,
+ BAD_KEY_USAGE_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Base64;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Test for badNetscapeCertType warning
+ * @library /lib/testlibrary ../
+ * @run main BadNetscapeCertTypeTest
+ */
+public class BadNetscapeCertTypeTest extends Test {
+
+ private static final String NETSCAPE_KEYSTORE_BASE64 = TEST_SOURCES + FS
+ + "bad_netscape_cert_type.jks.base64";
+
+ private static final String NETSCAPE_KEYSTORE
+ = "bad_netscape_cert_type.jks";
+
+ /**
+ * The test signs and verifies a jar that contains entries
+ * whose signer certificate's NetscapeCertType extension
+ * doesn't allow code signing (badNetscapeCertType).
+ * Warning message is expected.
+ * Run bad_netscape_cert_type.sh script to create bad_netscape_cert_type.jks
+ */
+ public static void main(String[] args) throws Throwable {
+
+ Files.write(Paths.get(NETSCAPE_KEYSTORE),
+ Base64.getMimeDecoder().decode(
+ Files.readAllBytes(Paths.get(NETSCAPE_KEYSTORE_BASE64))));
+
+ BadNetscapeCertTypeTest test = new BadNetscapeCertTypeTest();
+ test.start();
+ }
+
+ private void start() throws Throwable {
+ // create a jar file that contains one class file
+ Utils.createFiles(FIRST_FILE);
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // sign jar
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verbose",
+ "-keystore", NETSCAPE_KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkSigning(analyzer, BAD_NETSCAPE_CERT_TYPE_SIGNING_WARNING);
+
+ // verify signed jar
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-keystore", NETSCAPE_KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE);
+
+ checkVerifying(analyzer, 0, BAD_NETSCAPE_CERT_TYPE_VERIFYING_WARNING);
+
+ // verify signed jar in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-strict",
+ "-keystore", NETSCAPE_KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE);
+
+ checkVerifying(analyzer, BAD_NETSCAPE_CERT_TYPE_EXIT_CODE,
+ BAD_NETSCAPE_CERT_TYPE_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.File;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Test for chainNotValidated warning
+ * @library /lib/testlibrary ../
+ * @run main ChainNotValidatedTest
+ */
+public class ChainNotValidatedTest extends Test {
+
+ private static final String CHAIN = "chain";
+
+ /**
+ * The test signs and verifies a jar that contains entries
+ * whose cert chain can't be correctly validated (chainNotValidated).
+ * Warning message is expected.
+ */
+ public static void main(String[] args) throws Throwable {
+ ChainNotValidatedTest test = new ChainNotValidatedTest();
+ test.start();
+ }
+
+ private void start() throws Throwable {
+ // create a jar file that contains one class file
+ Utils.createFiles(FIRST_FILE);
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // create self-signed certificate whose BasicConstraints extension
+ // is set to false, so the certificate may not be used
+ // as a parent certificate (certpath validation should fail)
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkeypair",
+ "-alias", CA_KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=CA",
+ "-ext", "BasicConstraints:critical=ca:false",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // create a certificate that is signed by self-signed certificate
+ // despite of it may not be used as a parent certificate
+ // (certpath validation should fail)
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkeypair",
+ "-alias", KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Test",
+ "-ext", "BasicConstraints:critical=ca:false",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ ProcessTools.executeCommand(KEYTOOL,
+ "-certreq",
+ "-alias", KEY_ALIAS,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-file", CERT_REQUEST_FILENAME).shouldHaveExitValue(0);
+
+ ProcessTools.executeCommand(KEYTOOL,
+ "-gencert",
+ "-alias", CA_KEY_ALIAS,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-infile", CERT_REQUEST_FILENAME,
+ "-validity", Integer.toString(VALIDITY),
+ "-outfile", CERT_FILENAME).shouldHaveExitValue(0);
+
+ ProcessTools.executeCommand(KEYTOOL,
+ "-importcert",
+ "-alias", KEY_ALIAS,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-file", CERT_FILENAME).shouldHaveExitValue(0);
+
+ ProcessBuilder pb = new ProcessBuilder(KEYTOOL,
+ "-export",
+ "-rfc",
+ "-alias", KEY_ALIAS,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD);
+ pb.redirectOutput(ProcessBuilder.Redirect.appendTo(new File(CHAIN)));
+ ProcessTools.executeCommand(pb).shouldHaveExitValue(0);
+
+ pb = new ProcessBuilder(KEYTOOL,
+ "-export",
+ "-rfc",
+ "-alias", CA_KEY_ALIAS,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD);
+ pb.redirectOutput(ProcessBuilder.Redirect.appendTo(new File(CHAIN)));
+ ProcessTools.executeCommand(pb).shouldHaveExitValue(0);
+
+ // remove CA certificate
+ ProcessTools.executeCommand(KEYTOOL,
+ "-delete",
+ "-alias", CA_KEY_ALIAS,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD).shouldHaveExitValue(0);
+
+ // sign jar
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-certchain", CHAIN,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkSigning(analyzer, CHAIN_NOT_VALIDATED_SIGNING_WARNING);
+
+ // verify signed jar
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-certchain", CHAIN,
+ SIGNED_JARFILE);
+
+ checkVerifying(analyzer, 0, CHAIN_NOT_VALIDATED_VERIFYING_WARNING);
+
+ // verify signed jar in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-certchain", CHAIN,
+ SIGNED_JARFILE);
+
+ checkVerifying(analyzer, CHAIN_NOT_VALIDATED_EXIT_CODE,
+ CHAIN_NOT_VALIDATED_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/HasExpiredCertTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Test for hasExpiredCert warning
+ * @library /lib/testlibrary ../
+ * @run main HasExpiredCertTest
+ */
+public class HasExpiredCertTest extends Test {
+
+ static final int SHORT_VALIDITY = 365;
+
+ /**
+ * The test signs and verifies a jar that contains entries
+ * whose signer certificate has expired (hasExpiredCert).
+ * Warning message is expected.
+ */
+ public static void main(String[] args) throws Throwable {
+ HasExpiredCertTest test = new HasExpiredCertTest();
+ test.start();
+ }
+
+ private void start() throws Throwable {
+ // create a jar file that contains one class file
+ Utils.createFiles(FIRST_FILE);
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // create key pair for jar signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Test",
+ "-startdate", "-" + SHORT_VALIDITY * 2 + "d",
+ "-validity", Integer.toString(SHORT_VALIDITY))
+ .shouldHaveExitValue(0);
+
+ // sign jar
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkSigning(analyzer, HAS_EXPIRED_CERT_SIGNING_WARNING);
+
+ // verify signed jar
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE);
+
+ checkVerifying(analyzer, 0, HAS_EXPIRED_CERT_VERIFYING_WARNING);
+
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE);
+
+ checkVerifying(analyzer, HAS_EXPIRED_CERT_EXIT_CODE,
+ HAS_EXPIRED_CERT_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Test for hasExpiringCert warning
+ * @library /lib/testlibrary ../
+ * @run main HasExpiringCertTest
+ */
+public class HasExpiringCertTest extends Test {
+
+ static final int SHORT_VALIDITY = 90; // less than 6 month
+
+ /**
+ * The test signs and verifies a jar that contains entries
+ * whose signer certificate will expire within six months (hasExpiringCert).
+ * Warning message is expected.
+ */
+ public static void main(String[] args) throws Throwable {
+ HasExpiringCertTest test = new HasExpiringCertTest();
+ test.start();
+ }
+
+ private void start() throws Throwable {
+ // create a jar file that contains one class file
+ Utils.createFiles(FIRST_FILE);
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // create key pair for jar signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Test",
+ "-validity", Integer.toString(SHORT_VALIDITY))
+ .shouldHaveExitValue(0);
+
+ // sign jar
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-keystore", KEYSTORE,
+ "-verbose",
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkSigning(analyzer, HAS_EXPIRING_CERT_SIGNING_WARNING);
+
+ // verify signed jar
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkVerifying(analyzer, 0, HAS_EXPIRING_CERT_VERIFYING_WARNING);
+
+ // verify signed jar in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkVerifying(analyzer, 0, HAS_EXPIRING_CERT_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Test for hasUnsignedEntry warning
+ * @library /lib/testlibrary ../
+ * @run main HasUnsignedEntryTest
+ */
+public class HasUnsignedEntryTest extends Test {
+
+ /**
+ * The test signs and verifies a jar that contains unsigned entries
+ * which have not been integrity-checked (hasUnsignedEntry).
+ * Warning message is expected.
+ */
+ public static void main(String[] args) throws Throwable {
+ HasUnsignedEntryTest test = new HasUnsignedEntryTest();
+ test.start();
+ }
+
+ private void start() throws Throwable {
+ System.out.println(String.format("Create a %s that contains %s",
+ UNSIGNED_JARFILE, FIRST_FILE));
+ Utils.createFiles(FIRST_FILE, SECOND_FILE);
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // create key pair for signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Test",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // sign jar
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkSigning(analyzer);
+
+ System.out.println(String.format("Copy %s to %s, and add %s.class, "
+ + "so it contains unsigned entry",
+ new Object[]{SIGNED_JARFILE, UPDATED_SIGNED_JARFILE,
+ SECOND_FILE}));
+
+ JarUtils.updateJar(SIGNED_JARFILE, UPDATED_SIGNED_JARFILE, SECOND_FILE);
+
+ // verify jar
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ UPDATED_SIGNED_JARFILE);
+
+ checkVerifying(analyzer, 0, HAS_UNSIGNED_ENTRY_VERIFYING_WARNING);
+
+ // verify jar in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ UPDATED_SIGNED_JARFILE);
+
+ checkVerifying(analyzer, HAS_UNSIGNED_ENTRY_EXIT_CODE,
+ HAS_UNSIGNED_ENTRY_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/MultipleWarningsTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Checks if jarsigner prints appropriate warnings
+ * @library /lib/testlibrary ../
+ * @run main MultipleWarningsTest
+ */
+public class MultipleWarningsTest extends Test {
+
+ /**
+ * The test signs and verifies a jar that:
+ * - contains entries whose signer certificate has expired
+ * - contains entries whose signer certificate's ExtendedKeyUsage
+ * extension doesn't allow code signing
+ * - contains unsigned entries which have not been integrity-checked
+ * - contains signed entries which are not signed by the specified alias
+ * Warning messages are expected.
+ */
+ public static void main(String[] args) throws Throwable {
+ MultipleWarningsTest test = new MultipleWarningsTest();
+ test.start();
+ }
+
+ private void start() throws Throwable {
+ Utils.createFiles(FIRST_FILE, SECOND_FILE);
+
+ // create a jar file that contains one class file
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // create first expired certificate
+ // whose ExtendedKeyUsage extension does not allow code signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", FIRST_KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=First",
+ "-ext", "ExtendedkeyUsage=serverAuth",
+ "-startdate", "-" + VALIDITY * 2 + "d",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // create second expired certificate
+ // whose KeyUsage extension does not allow code signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", SECOND_KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Second",
+ "-ext", "ExtendedkeyUsage=serverAuth",
+ "-startdate", "-" + VALIDITY * 2 + "d",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // sign jar with first key
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ FIRST_KEY_ALIAS);
+
+ checkSigning(analyzer, HAS_EXPIRED_CERT_SIGNING_WARNING,
+ BAD_EXTENDED_KEY_USAGE_SIGNING_WARNING);
+
+ // add a second class to created jar, so it contains unsigned entry
+ JarUtils.updateJar(SIGNED_JARFILE, UPDATED_SIGNED_JARFILE, SECOND_FILE);
+
+ // verify jar with second key
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ UPDATED_SIGNED_JARFILE,
+ SECOND_KEY_ALIAS);
+
+ checkVerifying(analyzer, 0, BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING,
+ HAS_EXPIRED_CERT_VERIFYING_WARNING,
+ HAS_UNSIGNED_ENTRY_VERIFYING_WARNING,
+ NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING);
+
+ // verify jar with second key in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ UPDATED_SIGNED_JARFILE,
+ SECOND_KEY_ALIAS);
+
+ int expectedExitCode = HAS_EXPIRED_CERT_EXIT_CODE
+ + BAD_EXTENDED_KEY_USAGE_EXIT_CODE
+ + HAS_UNSIGNED_ENTRY_EXIT_CODE
+ + NOT_SIGNED_BY_ALIAS_EXIT_CODE;
+ checkVerifying(analyzer, expectedExitCode,
+ BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING,
+ HAS_EXPIRED_CERT_VERIFYING_WARNING,
+ HAS_UNSIGNED_ENTRY_VERIFYING_WARNING,
+ NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING);
+
+ // verify jar with non-exisiting alias
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ UPDATED_SIGNED_JARFILE,
+ "bogus");
+
+ checkVerifying(analyzer, 0, BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING,
+ HAS_EXPIRED_CERT_VERIFYING_WARNING,
+ HAS_UNSIGNED_ENTRY_VERIFYING_WARNING,
+ NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING);
+
+ // verify jar with non-exisiting alias in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ UPDATED_SIGNED_JARFILE,
+ "bogus");
+
+ checkVerifying(analyzer, expectedExitCode,
+ BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING,
+ HAS_EXPIRED_CERT_VERIFYING_WARNING,
+ HAS_UNSIGNED_ENTRY_VERIFYING_WARNING,
+ NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/NoTimestampTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.Date;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Checks warnings if -tsa and -tsacert options are not specified
+ * @library /lib/testlibrary ../
+ * @run main NoTimestampTest
+ */
+public class NoTimestampTest extends Test {
+
+ /**
+ * The test signs and verifies a jar file without -tsa and -tsacert options,
+ * and checks that proper warnings are shown.
+ */
+ public static void main(String[] args) throws Throwable {
+ NoTimestampTest test = new NoTimestampTest();
+ test.start();
+ }
+
+ private void start() throws Throwable {
+ String timezone = System.getProperty("user.timezone");
+ System.out.println(String.format("Timezone = %s", timezone));
+
+ // create a jar file that contains one class file
+ Utils.createFiles(FIRST_FILE);
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // calculate certificate expiration date
+ Date expirationDate = new Date(System.currentTimeMillis() + VALIDITY
+ * 24 * 60 * 60 * 1000L);
+
+ // create key pair
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Test",
+ "-validity", Integer.toString(VALIDITY));
+
+ // sign jar file
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-J-Duser.timezone=" + timezone,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ KEY_ALIAS);
+
+ String warning = String.format(NO_TIMESTAMP_SIGNING_WARN_TEMPLATE,
+ expirationDate);
+ checkSigning(analyzer, warning);
+
+ // verify signed jar
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-J-Duser.timezone=" + timezone,
+ "-verify",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE,
+ KEY_ALIAS);
+
+ warning = String.format(NO_TIMESTAMP_VERIFYING_WARN_TEMPLATE, expirationDate);
+ checkVerifying(analyzer, 0, warning);
+
+ // verify signed jar in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-J-Duser.timezone=" + timezone,
+ "-verify",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkVerifying(analyzer, 0, warning);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Test for notSignedByAlias warning
+ * @library /lib/testlibrary ../
+ * @run main NotSignedByAliasTest
+ */
+public class NotSignedByAliasTest extends Test {
+
+ /**
+ * The test signs and verifies a jar that contains signed entries
+ * which are not signed by the specified alias(es) (notSignedByAlias).
+ * Warning message is expected.
+ */
+ public static void main(String[] args) throws Throwable {
+ NotSignedByAliasTest test = new NotSignedByAliasTest();
+ test.start();
+ }
+
+ protected void start() throws Throwable {
+ // create a jar file that contains one class file
+ Utils.createFiles(FIRST_FILE);
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // create first key pair for signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", FIRST_KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=First",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // create first key pair for signing
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", SECOND_KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Second",
+ "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
+
+ // sign jar with first key
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ FIRST_KEY_ALIAS);
+
+ checkSigning(analyzer);
+
+ // verify jar with second key
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE,
+ SECOND_KEY_ALIAS);
+
+ checkVerifying(analyzer, 0, NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING);
+
+ // verify jar with second key in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE,
+ SECOND_KEY_ALIAS);
+
+ checkVerifying(analyzer, NOT_SIGNED_BY_ALIAS_EXIT_CODE,
+ NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING);
+
+ // verify jar with non-existing alias
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE,
+ "bogus");
+
+ checkVerifying(analyzer, 0, NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING);
+
+ // verify jar with non-existing alias in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE,
+ "bogus");
+
+ checkVerifying(analyzer, NOT_SIGNED_BY_ALIAS_EXIT_CODE,
+ NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/NotYetValidCertTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.JarUtils;
+
+/**
+ * @test
+ * @bug 8024302 8026037
+ * @summary Test for notYetValidCert warning
+ * @library /lib/testlibrary ../
+ * @run main NotYetValidCertTest
+ */
+public class NotYetValidCertTest extends Test {
+
+ /**
+ * The test signs and verifies a jar that contains entries
+ * whose signer certificate is not yet valid (notYetValidCert).
+ * Warning message is expected.
+ */
+ public static void main(String[] args) throws Throwable {
+ NotYetValidCertTest test = new NotYetValidCertTest();
+ test.start();
+ }
+
+ protected void start() throws Throwable {
+ // create a jar file that contains one class file
+ Utils.createFiles(FIRST_FILE);
+ JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
+
+ // create certificate that will be valid only tomorrow
+ ProcessTools.executeCommand(KEYTOOL,
+ "-genkey",
+ "-alias", KEY_ALIAS,
+ "-keyalg", KEY_ALG,
+ "-keysize", Integer.toString(KEY_SIZE),
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-dname", "CN=Test",
+ "-startdate", "+1d",
+ "-validity", Integer.toString(VALIDITY));
+
+ // sign jar
+ OutputAnalyzer analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ "-signedjar", SIGNED_JARFILE,
+ UNSIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkSigning(analyzer, NOT_YET_VALID_CERT_SIGNING_WARNING);
+
+ // verify signed jar
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkVerifying(analyzer, 0, NOT_YET_VALID_CERT_VERIFYING_WARNING);
+
+ // verify jar in strict mode
+ analyzer = ProcessTools.executeCommand(JARSIGNER,
+ "-verify",
+ "-verbose",
+ "-strict",
+ "-keystore", KEYSTORE,
+ "-storepass", PASSWORD,
+ "-keypass", PASSWORD,
+ SIGNED_JARFILE,
+ KEY_ALIAS);
+
+ checkVerifying(analyzer, HAS_EXPIRED_CERT_EXIT_CODE,
+ NOT_YET_VALID_CERT_VERIFYING_WARNING);
+
+ System.out.println("Test passed");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/Test.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 jdk.testlibrary.OutputAnalyzer;
+
+/**
+ * Base class.
+ */
+public abstract class Test {
+
+ static final String TEST_SOURCES = System.getProperty("test.src", ".");
+ static final String TEST_CLASSES = System.getProperty("test.classes");
+ static final String FS = System.getProperty("file.separator");
+ static final String JAVA_HOME = System.getProperty("java.home");
+ static final String KEYTOOL = JAVA_HOME + FS + "bin" + FS + "keytool";
+ static final String JARSIGNER = JAVA_HOME + FS + "bin" + FS + "jarsigner";
+ static final String UNSIGNED_JARFILE = "unsigned.jar";
+ static final String SIGNED_JARFILE = "signed.jar";
+ static final String UPDATED_SIGNED_JARFILE = "updated_signed.jar";
+ static final String FIRST_FILE = "first.txt";
+ static final String SECOND_FILE = "second.txt";
+ static final String PASSWORD = "password";
+ static final String BOTH_KEYS_KEYSTORE = "both_keys.jks";
+ static final String FIRST_KEY_KEYSTORE = "first_key.jks";
+ static final String KEYSTORE = "keystore.jks";
+ static final String FIRST_KEY_ALIAS = "first";
+ static final String SECOND_KEY_ALIAS = "second";
+ static final String KEY_ALG = "RSA";
+ static final String KEY_ALIAS = "alias";
+ static final String CERT_REQUEST_FILENAME = "test.req";
+ static final String CERT_FILENAME = "test.crt";
+ static final String CA_KEY_ALIAS = "ca";
+ static final int KEY_SIZE = 2048;
+ static final int TIMEOUT = 6 * 60 * 1000; // in millis
+ static final int VALIDITY = 365;
+
+ static final String WARNING = "Warning:";
+
+ static final String CHAIN_NOT_VALIDATED_VERIFYING_WARNING
+ = "This jar contains entries "
+ + "whose certificate chain is not validated.";
+
+ static final String ALIAS_NOT_IN_STORE_VERIFYING_WARNING
+ = "This jar contains signed entries "
+ + "that are not signed by alias in this keystore.";
+
+ static final String BAD_EXTENDED_KEY_USAGE_SIGNING_WARNING
+ = "The signer certificate's ExtendedKeyUsage extension "
+ + "doesn't allow code signing.";
+
+ static final String BAD_EXTENDED_KEY_USAGE_VERIFYING_WARNING
+ = "This jar contains entries whose signer certificate's "
+ + "ExtendedKeyUsage extension doesn't allow code signing.";
+
+ static final String BAD_KEY_USAGE_SIGNING_WARNING
+ = "The signer certificate's KeyUsage extension "
+ + "doesn't allow code signing.";
+
+ static final String BAD_KEY_USAGE_VERIFYING_WARNING
+ = "This jar contains entries whose signer certificate's KeyUsage "
+ + "extension doesn't allow code signing.";
+
+ static final String BAD_NETSCAPE_CERT_TYPE_SIGNING_WARNING
+ = "The signer certificate's NetscapeCertType extension "
+ + "doesn't allow code signing.";
+
+ static final String BAD_NETSCAPE_CERT_TYPE_VERIFYING_WARNING
+ = "This jar contains entries "
+ + "whose signer certificate's NetscapeCertType extension "
+ + "doesn't allow code signing.";
+
+ static final String CHAIN_NOT_VALIDATED_SIGNING_WARNING
+ = "The signer's certificate chain is not validated.";
+
+ static final String HAS_EXPIRING_CERT_SIGNING_WARNING
+ = "The signer certificate will expire within six months.";
+
+ static final String HAS_EXPIRING_CERT_VERIFYING_WARNING
+ = "This jar contains entries "
+ + "whose signer certificate will expire within six months.";
+
+ static final String HAS_EXPIRED_CERT_SIGNING_WARNING
+ = "The signer certificate has expired.";
+
+ static final String HAS_EXPIRED_CERT_VERIFYING_WARNING
+ = "This jar contains entries whose signer certificate has expired.";
+
+ static final String HAS_UNSIGNED_ENTRY_VERIFYING_WARNING
+ = "This jar contains unsigned entries "
+ + "which have not been integrity-checked.";
+
+ static final String NOT_SIGNED_BY_ALIAS_VERIFYING_WARNING
+ = "This jar contains signed entries "
+ + "which are not signed by the specified alias(es).";
+
+ static final String NO_TIMESTAMP_SIGNING_WARN_TEMPLATE
+ = "No -tsa or -tsacert is provided "
+ + "and this jar is not timestamped. "
+ + "Without a timestamp, users may not be able to validate this jar "
+ + "after the signer certificate's expiration date "
+ + "(%1$tY-%1$tm-%1$td) or after any future revocation date.";
+
+ static final String NO_TIMESTAMP_VERIFYING_WARN_TEMPLATE
+ = "This jar contains signatures that does not include a timestamp. "
+ + "Without a timestamp, users may not be able to validate this jar "
+ + "after the signer certificate's expiration date "
+ + "(%1$tY-%1$tm-%1$td) or after any future revocation date.";
+
+ static final String NOT_YET_VALID_CERT_SIGNING_WARNING
+ = "The signer certificate is not yet valid.";
+
+ static final String NOT_YET_VALID_CERT_VERIFYING_WARNING
+ = "This jar contains entries "
+ + "whose signer certificate is not yet valid.";
+
+ static final String JAR_SIGNED = "jar signed.";
+
+ static final String JAR_VERIFIED = "jar verified.";
+
+ static final String JAR_VERIFIED_WITH_SIGNER_ERRORS
+ = "jar verified, with signer errors.";
+
+ static final int CHAIN_NOT_VALIDATED_EXIT_CODE = 4;
+ static final int HAS_EXPIRED_CERT_EXIT_CODE = 4;
+ static final int BAD_KEY_USAGE_EXIT_CODE = 8;
+ static final int BAD_EXTENDED_KEY_USAGE_EXIT_CODE = 8;
+ static final int BAD_NETSCAPE_CERT_TYPE_EXIT_CODE = 8;
+ static final int HAS_UNSIGNED_ENTRY_EXIT_CODE = 16;
+ static final int ALIAS_NOT_IN_STORE_EXIT_CODE = 32;
+ static final int NOT_SIGNED_BY_ALIAS_EXIT_CODE = 32;
+
+ protected void checkVerifying(OutputAnalyzer analyzer, int expectedExitCode,
+ String... warnings) {
+ analyzer.shouldHaveExitValue(expectedExitCode);
+ for (String warning : warnings) {
+ analyzer.shouldContain(warning);
+ }
+ if (warnings.length > 0) {
+ analyzer.shouldContain(WARNING);
+ }
+ if (expectedExitCode == 0) {
+ analyzer.shouldContain(JAR_VERIFIED);
+ } else {
+ analyzer.shouldContain(JAR_VERIFIED_WITH_SIGNER_ERRORS);
+ }
+ }
+
+ protected void checkSigning(OutputAnalyzer analyzer, String... warnings) {
+ analyzer.shouldHaveExitValue(0);
+ for (String warning : warnings) {
+ analyzer.shouldContain(warning);
+ }
+ if (warnings.length > 0) {
+ analyzer.shouldContain(WARNING);
+ }
+ analyzer.shouldContain(JAR_SIGNED);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/bad_netscape_cert_type.jks.base64 Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,26 @@
+/u3+7QAAAAIAAAABAAAAAQAFYWxpYXMAAAFBpkwW0gAAAr0wggK5MA4GCisGAQQB
+KgIRAQEFAASCAqWkGJ3PPjYmWNKrV23Y1u413RMAkrRZ+1OLWYRcQt4jtxtIyEH5
+Ho5b9dy9XN9FBKlTOD4c2Pc1T43BLKXeuLu3uLLeIxgXFt0z9CLyGwdYZZ751kXr
+DQ99qY6aNQUO6SeE4Wdty0KPAqid6ZJ8bF7T6wsTZSvNhaBRzyFydEfG7bbUYjOl
+mWC44nlsu6VEU3o9RQpcm1gIMwradOaIVT/HoB2bKmAv8gHqI6kreiEZwTdZkSAI
+IRi2vt1RPllXt5hgjDxUfZe8XOYYweR4Vt2/jVuKLJ80DNTu/9SeUD88zQAz53k4
+r3nRhv6TRcPm6tV/Fh92XLHiskL+TAzTfm+bUAudPCCVxN+yRtxvAgA+UhdV/SuM
+Zn5F6nrmP+YJG1hmprgCJIJJaCEXa9RXYC+vIVpO0WVNRuGlGm+/1afnOuQC8Wss
+ShXwjkaqTwAhqBFq7eYmmP8BK3gflYrt2zDLXvhl4ndVvMhMthFJ3ZvLh2LWpqLI
+/n8EMCf8US3lIEFk9DTHBZjffiHkqK2e7+FXEpG3xrgE6ZYLMdbd5Pb3YjZfhQx+
+ZTtiEFzYSaEGhacek/m7dRq1qmwgFsytng2OdWZe2ln8LJY0odr1dGUfJHfgafvi
+tlfbkg/rgjONtwliChDggbkUwnerrj/D/zrdEufUvfyltSshhHXRNDD3fH6spmEk
+hHKgxEc4yvxqJxzdMGtuib355aSfNegyl+GsnsKzXQCVEK2h3BLTQObzaD+8NZ12
+LQHvbrCiaS34vxJ3rEC+a+SW7itZp0aCdXMWdMJNkRKqyLBD3vG3zN05sN3XrhEM
+8BRT020TWY00tbVFbbBFheYLQRgTjrQtr0Yt6UHWBZc4N20crDLcSH5gqcCOVpla
+1Y2uqFEn8yqrGRwn/kgfNgAAAAEABVguNTA5AAABtTCCAbEwggEaoAMCAQICCQDH
+cEuVvzCuqzANBgkqhkiG9w0BAQUFADAPMQ0wCwYDVQQDDARUZXN0MB4XDTEzMTAx
+MTA2NTUwNloXDTIzMTAwOTA2NTUwNlowDzENMAsGA1UEAwwEVGVzdDCBnzANBgkq
+hkiG9w0BAQEFAAOBjQAwgYkCgYEA8hOfp2Dcnvt//ZZQAja9TRiwKqXVS+TiYE3S
+gngCBjIi+YYdo0DsUeO5MBfE6uvCWOr5lwAR/u1iaJOhIoGJDiGoPasZlt+yIgtR
+LzA7j2q+1q6kcwiVxfikI3aUgHV/QsybTriT4Bf7TQNKtJG23MQa4sD7+PjtCWD7
+p3cHTfkCAwEAAaMVMBMwEQYJYIZIAYb4QgEBBAQDAgeAMA0GCSqGSIb3DQEBBQUA
+A4GBAKoDlTJ8wLRA7G8XdGm4gv733n1cSQzlkcsjfOO6/mA5Jvu8tyFNq9HTf9AT
+VXbrbGcUYJjhzSSY3w5apXK1kXyqTB1LUNEJ45WnmciqSSecVTpJz9TuegyoX0Zf
+HScSgqfDmjqoiiFiNCgn3ZEJ85ykGvoFYGH+php+BVi3S0bj5E/jRpyV3vNnii/S
+wJDSAXF6bYU=
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/warnings/bad_netscape_cert_type.sh Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# 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.
+#
+
+#!/bin/sh
+
+# This script creates JKS keystore with a certificate
+# that contains Netscape Certificate Type extension
+# that does not allow code signing
+# The keystore is used by BadNetscapeCertTypeTest.java test
+
+rm -rf keystore.jks
+echo "nsCertType = client" > ext.cfg
+
+openssl req -new -out cert.req -keyout key.pem -days 3650 \
+ -passin pass:password -passout pass:password -subj "/CN=Test"
+openssl x509 -in cert.req -out cert.pem -req -signkey key.pem -days 3650 \
+ -passin pass:password -extfile ext.cfg
+openssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12 \
+ -passin pass:password -passout pass:password -name alias
+
+${JAVA_HOME}/bin/keytool -importkeystore \
+ -srckeystore keystore.p12 -srcstoretype pkcs12 \
+ -srcstorepass password -alias alias \
+ -destkeystore bad_netscape_cert_type.jks -deststoretype jks \
+ -deststorepass password -destalias alias \
+
+openssl base64 < bad_netscape_cert_type.jks > bad_netscape_cert_type.jks.base64
+rm -rf cert.req key.pem cert.pem keystore.p12 ext.cfg bad_netscape_cert_type.jks
--- a/jdk/test/sun/security/tools/policytool/i18n.sh Wed Jan 28 17:48:59 2015 +0100
+++ b/jdk/test/sun/security/tools/policytool/i18n.sh Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 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
@@ -83,8 +83,9 @@
exit 1
fi
+# The keystore type is set to JKS, to match the type expected by i18n.html
${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -genkeypair -alias hello -dname CN=Hello \
- -storepass changeit -keypass changeit -keystore ks
+ -storepass changeit -keypass changeit -keystore ks -storetype jks
echo changeit > good
echo badpass > bad
${TESTJAVA}${FS}bin${FS}policytool ${TESTTOOLVMOPTS}
--- a/langtools/.hgtags Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/.hgtags Thu Jan 29 03:54:45 2015 +0000
@@ -288,3 +288,5 @@
6a06008aec10d32898ca665685f531c681b28f5f jdk9-b43
de2ce70d907c9f227b802cea29285bece5194cd5 jdk9-b44
73bbdcf236b297a0c1b8875f2eeba65eaf7ade60 jdk9-b45
+e272d9be5f90edb6bb6b40f7816ec85eec0f5dc2 jdk9-b46
+230c139552501e612dd0d4423ac30f94c1201c0d jdk9-b47
--- a/langtools/make/Tools.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/make/Tools.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -40,6 +40,7 @@
ADD_JAVAC_FLAGS := -Xprefer:source, \
SRC := $(LANGTOOLS_TOPDIR)/make/tools, \
INCLUDES := compileproperties propertiesparser, \
+ COPY := .properties, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes))
all: $(BUILD_TOOLS_LANGTOOLS)
--- a/langtools/make/gensrc/Gensrc-jdk.compiler.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/make/gensrc/Gensrc-jdk.compiler.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -25,19 +25,19 @@
include GensrcCommon.gmk
-$(eval $(call SetupVersionProperties,JAVAC_VERSION,\
+$(eval $(call SetupVersionProperties,JAVAC_VERSION, \
com/sun/tools/javac/resources/version.properties))
-$(eval $(call SetupVersionProperties,JAVAH_VERSION,\
+$(eval $(call SetupVersionProperties,JAVAH_VERSION, \
com/sun/tools/javah/resources/version.properties))
-$(eval $(call SetupVersionProperties,JAVAP_VERSION,\
+$(eval $(call SetupVersionProperties,JAVAP_VERSION, \
com/sun/tools/javap/resources/version.properties))
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES,\
+$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
$(JAVAC_VERSION) $(JAVAH_VERSION) $(JAVAP_VERSION)))
-$(eval $(call SetupParseProperties,PARSE_PROPERTIES,\
+$(eval $(call SetupParseProperties,PARSE_PROPERTIES, \
com/sun/tools/javac/resources/compiler.properties))
all: $(COMPILE_PROPERTIES) $(PARSE_PROPERTIES)
--- a/langtools/make/gensrc/GensrcCommon.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/make/gensrc/GensrcCommon.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -63,7 +63,8 @@
# Param 2 - Extra properties files to process
define SetupCompileProperties
# Lookup the properties that need to be compiled into resource bundles.
- PROPSOURCES := $2 $$(shell $(FIND) $(LANGTOOLS_TOPDIR)/src/$(MODULE)/share/classes -name "*.properties")
+ PROPSOURCES := $2 \
+ $$(shell $(FIND) $(LANGTOOLS_TOPDIR)/src/$(MODULE)/share/classes -name "*.properties")
# Convert .../src/<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties
# to .../langtools/gensrc/<module>/com/sun/tools/javac/resources/javac_zh_CN.java
@@ -74,7 +75,7 @@
$$(patsubst %.properties, %.java, \
$$(subst /share/classes,, $$(PROPSOURCES))))
- # Generate the package dirs for the tobe generated java files. Sort to remove
+ # Generate the package dirs for the to be generated java files. Sort to remove
# duplicates.
PROPDIRS := $$(sort $$(dir $$(PROPJAVAS)))
@@ -88,8 +89,8 @@
# Now setup the rule for the generation of the resource bundles.
$(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/_the_props: $$(PROPSOURCES)
- $(FIND) $$(@D) -name "*.java" $(FIND_DELETE)
$(MKDIR) -p $$(@D) $$(PROPDIRS)
+ $(FIND) $$(@D) -name "*.java" -a ! -name "*Properties.java" $(FIND_DELETE)
$(ECHO) Compiling $$(words $$(PROPSOURCES)) properties into resource bundles for $(MODULE)
$(TOOL_COMPILEPROPS_CMD) $$(PROPCMDLINE)
$(TOUCH) $$@
@@ -102,11 +103,11 @@
# Param 1 - Variable to add targets to
# Param 2 - Extra properties files to process
define SetupParseProperties
- #property file to generate
- PARSEPROPSOURCES := $$(foreach var,$2,$$(addsuffix $$(var),$(LANGTOOLS_TOPDIR)/src/$(MODULE)/share/classes/))
+ # property files to process
+ PARSEPROPSOURCES := $$(addprefix $(LANGTOOLS_TOPDIR)/src/$(MODULE)/share/classes/, $2)
- PARSEPROPALLDIRS := $$(patsubst $(LANGTOOLS_TOPDIR)/src/%, \
- $(SUPPORT_OUTPUTDIR)/gensrc/%, \
+ PARSEPROPALLDIRS := $$(patsubst $(LANGTOOLS_TOPDIR)/src/$(MODULE)/share/classes/%, \
+ $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/%, \
$$(dir $$(PARSEPROPSOURCES)))
PARSEPROPDIRS := $$(sort $$(PARSEPROPALLDIRS))
@@ -114,11 +115,11 @@
PARSEPROPCMDLINE := $$(subst _SPACE_, $$(SPACE), \
$$(join $$(foreach var,$$(PARSEPROPSOURCES),$$(addprefix -compile_SPACE_,$$(var))), \
$$(addprefix _SPACE_, $$(PARSEPROPALLDIRS))))
-
+
# Now setup the rule for the generation of the resource bundles.
$(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/_the_parsed_props: $(PARSEPROPSOURCES)
- $(CP) -r $(LANGTOOLS_TOPDIR)/make/tools/propertiesparser/resources $(BUILDTOOLS_OUTPUTDIR)/langtools_tools_classes/propertiesparser/resources
$(MKDIR) -p $$(@D) $$(PARSEPROPDIRS)
+ $(FIND) $$(@D) -name "*Properties.java" $(FIND_DELETE)
$(ECHO) Parsing $$(words $$(PARSEPROPSOURCES)) properties into enum-like class for $(MODULE)
$(TOOL_PARSEPROPS_CMD) $$(PARSEPROPCMDLINE)
$(TOUCH) $$@
--- a/langtools/make/tools/propertiesparser/gen/ClassGenerator.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/make/tools/propertiesparser/gen/ClassGenerator.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,3 +1,26 @@
+/*
+ * 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 propertiesparser.gen;
import propertiesparser.parser.Message;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/resources/doclint.properties Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
# questions.
#
-dc.anchor.already.defined = anchor already defined: {0}
+dc.anchor.already.defined = anchor already defined: "{0}"
dc.anchor.value.missing = no value given for anchor
dc.attr.lacks.value = attribute lacks value
dc.attr.not.number = attribute value is not a number
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -98,6 +98,7 @@
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log;
@@ -924,12 +925,7 @@
try {
switch (kind) {
case ERROR:
- boolean prev = log.multipleErrors;
- try {
- log.error(pos, "proc.messager", msg.toString());
- } finally {
- log.multipleErrors = prev;
- }
+ log.error(DiagnosticFlag.MULTIPLE, pos, "proc.messager", msg.toString());
break;
case WARNING:
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java Thu Jan 29 03:54:45 2015 +0000
@@ -74,8 +74,7 @@
WRONG_MTHS(Category.OVERLOAD, KindName.METHOD),
WRONG_MTH(Category.OVERLOAD, KindName.METHOD),
ABSENT_MTH(Category.OVERLOAD, KindName.METHOD),
- ABSENT_TYP(Category.OVERLOAD, KindName.CLASS),
- WRONG_STATICNESS(Category.OVERLOAD, KindName.METHOD);
+ ABSENT_TYP(Category.OVERLOAD, KindName.CLASS);
// There are essentially two "levels" to the Kind datatype.
// The first is a totally-ordered set of categories of
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Thu Jan 29 03:54:45 2015 +0000
@@ -1175,6 +1175,16 @@
return v.visitClassSymbol(this, p);
}
+ public void markAbstractIfNeeded(Types types) {
+ if (types.enter.getEnv(this) != null &&
+ (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym &&
+ (flags() & (FINAL | ABSTRACT)) == 0) {
+ if (types.firstUnimplementedAbstract(this) != null)
+ // add the ABSTRACT flag to an enum
+ flags_field |= ABSTRACT;
+ }
+ }
+
/**Resets the Symbol into the state good for next round of annotation processing.*/
public void reset() {
kind = TYP;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Jan 29 03:54:45 2015 +0000
@@ -48,6 +48,7 @@
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.Scope.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.Symbol.*;
import static com.sun.tools.javac.code.Type.*;
import static com.sun.tools.javac.code.TypeTag.*;
@@ -82,6 +83,7 @@
final JavacMessages messages;
final Names names;
final boolean allowObjectToPrimitiveCast;
+ final boolean allowDefaultMethods;
final Check chk;
final Enter enter;
JCDiagnostic.Factory diags;
@@ -105,6 +107,7 @@
names = Names.instance(context);
Source source = Source.instance(context);
allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
+ allowDefaultMethods = source.allowDefaultMethods();
chk = Check.instance(context);
enter = Enter.instance(context);
capturedName = names.fromString("<captured wildcard>");
@@ -805,13 +808,13 @@
return true;
}
- // Generally, if 's' is a type variable, recur on lower bound; but
+ // Generally, if 's' is a lower-bounded type variable, recur on lower bound; but
// for inference variables and intersections, we need to keep 's'
// (see JLS 4.10.2 for intersections and 18.2.3 for inference vars)
if (!t.hasTag(UNDETVAR) && !t.isCompound()) {
// TODO: JDK-8039198, bounds checking sometimes passes in a wildcard as s
Type lower = cvarLowerBound(wildLowerBound(s));
- if (s != lower)
+ if (s != lower && !lower.hasTag(BOT))
return isSubtype(capture ? capture(t) : t, lower, false);
}
@@ -2775,6 +2778,58 @@
// </editor-fold>
+ /** Return first abstract member of class `sym'.
+ */
+ public MethodSymbol firstUnimplementedAbstract(ClassSymbol sym) {
+ try {
+ return firstUnimplementedAbstractImpl(sym, sym);
+ } catch (CompletionFailure ex) {
+ chk.completionError(enter.getEnv(sym).tree.pos(), ex);
+ return null;
+ }
+ }
+ //where:
+ private MethodSymbol firstUnimplementedAbstractImpl(ClassSymbol impl, ClassSymbol c) {
+ MethodSymbol undef = null;
+ // Do not bother to search in classes that are not abstract,
+ // since they cannot have abstract members.
+ if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
+ Scope s = c.members();
+ for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
+ if (sym.kind == MTH &&
+ (sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
+ MethodSymbol absmeth = (MethodSymbol)sym;
+ MethodSymbol implmeth = absmeth.implementation(impl, this, true);
+ if (implmeth == null || implmeth == absmeth) {
+ //look for default implementations
+ if (allowDefaultMethods) {
+ MethodSymbol prov = interfaceCandidates(impl.type, absmeth).head;
+ if (prov != null && prov.overrides(absmeth, impl, this, true)) {
+ implmeth = prov;
+ }
+ }
+ }
+ if (implmeth == null || implmeth == absmeth) {
+ undef = absmeth;
+ break;
+ }
+ }
+ }
+ if (undef == null) {
+ Type st = supertype(c.type);
+ if (st.hasTag(CLASS))
+ undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)st.tsym);
+ }
+ for (List<Type> l = interfaces(c.type);
+ undef == null && l.nonEmpty();
+ l = l.tail) {
+ undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)l.head.tsym);
+ }
+ }
+ return undef;
+ }
+
+
//where
public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) {
Filter<Symbol> filter = new MethodFilter(ms, site);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jan 29 03:54:45 2015 +0000
@@ -2640,8 +2640,7 @@
try {
refResult = rs.resolveMemberReference(localEnv, that, that.expr.type,
that.name, argtypes, typeargtypes, referenceCheck,
- resultInfo.checkContext.inferenceContext(),
- resultInfo.checkContext.deferredAttrContext().mode);
+ resultInfo.checkContext.inferenceContext(), rs.basicReferenceChooser);
} finally {
resultInfo.checkContext.inferenceContext().rollback(saved_undet);
}
@@ -2659,9 +2658,8 @@
case WRONG_MTHS:
case AMBIGUOUS:
case HIDDEN:
+ case MISSING_ENCL:
case STATICERR:
- case MISSING_ENCL:
- case WRONG_STATICNESS:
targetError = true;
break;
default:
@@ -2722,15 +2720,6 @@
return;
}
- if (that.sym.isStatic() && !TreeInfo.isStaticSelector(that.expr, names) &&
- !that.kind.isUnbound()) {
- //no static bound mrefs
- log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
- diags.fragment("static.bound.mref"));
- result = that.type = types.createErrorType(currentTarget);
- return;
- }
-
if (!refSym.isStatic() && that.kind == JCMemberReference.ReferenceKind.SUPER) {
// Check that super-qualified symbols are not abstract (JLS)
rs.checkNonAbstract(that.pos(), that.sym);
@@ -2794,7 +2783,8 @@
@SuppressWarnings("fallthrough")
void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) {
- Type returnType = checkContext.inferenceContext().asUndetVar(descriptor.getReturnType());
+ InferenceContext inferenceContext = checkContext.inferenceContext();
+ Type returnType = inferenceContext.asUndetVar(descriptor.getReturnType());
Type resType;
switch (tree.getMode()) {
@@ -2823,10 +2813,20 @@
if (incompatibleReturnType != null) {
checkContext.report(tree, diags.fragment("incompatible.ret.type.in.mref",
diags.fragment("inconvertible.types", resType, descriptor.getReturnType())));
+ } else {
+ if (inferenceContext.free(refType)) {
+ // we need to wait for inference to finish and then replace inference vars in the referent type
+ inferenceContext.addFreeTypeListener(List.of(refType),
+ instantiatedContext -> {
+ tree.referentType = instantiatedContext.asInstType(refType);
+ });
+ } else {
+ tree.referentType = refType;
+ }
}
if (!speculativeAttr) {
- List<Type> thrownTypes = checkContext.inferenceContext().asUndetVars(descriptor.getThrownTypes());
+ List<Type> thrownTypes = inferenceContext.asUndetVars(descriptor.getThrownTypes());
if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) {
log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes());
}
@@ -4199,6 +4199,8 @@
chk.validate(tree.implementing, env);
}
+ c.markAbstractIfNeeded(types);
+
// If this is a non-abstract class, check that it has no abstract
// methods or unimplemented methods of an implemented interface.
if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -898,7 +898,7 @@
Type argtype = owntype.getParameterTypes().last();
if (!types.isReifiable(argtype) &&
(!allowSimplifiedVarargs ||
- sym.attribute(syms.trustMeType.tsym) == null ||
+ sym.baseSymbol().attribute(syms.trustMeType.tsym) == null ||
!isTrustMeAllowedOnMethod(sym))) {
warnUnchecked(env.tree.pos(),
"unchecked.generic.array.creation",
@@ -2019,69 +2019,15 @@
* @param c The class.
*/
void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
- try {
- MethodSymbol undef = firstUndef(c, c);
- if (undef != null) {
- if ((c.flags() & ENUM) != 0 &&
- types.supertype(c.type).tsym == syms.enumSym &&
- (c.flags() & FINAL) == 0) {
- // add the ABSTRACT flag to an enum
- c.flags_field |= ABSTRACT;
- } else {
- MethodSymbol undef1 =
- new MethodSymbol(undef.flags(), undef.name,
- types.memberType(c.type, undef), undef.owner);
- log.error(pos, "does.not.override.abstract",
- c, undef1, undef1.location());
- }
- }
- } catch (CompletionFailure ex) {
- completionError(pos, ex);
+ MethodSymbol undef = types.firstUnimplementedAbstract(c);
+ if (undef != null) {
+ MethodSymbol undef1 =
+ new MethodSymbol(undef.flags(), undef.name,
+ types.memberType(c.type, undef), undef.owner);
+ log.error(pos, "does.not.override.abstract",
+ c, undef1, undef1.location());
}
}
-//where
- /** Return first abstract member of class `c' that is not defined
- * in `impl', null if there is none.
- */
- private MethodSymbol firstUndef(ClassSymbol impl, ClassSymbol c) {
- MethodSymbol undef = null;
- // Do not bother to search in classes that are not abstract,
- // since they cannot have abstract members.
- if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
- Scope s = c.members();
- for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
- if (sym.kind == MTH &&
- (sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
- MethodSymbol absmeth = (MethodSymbol)sym;
- MethodSymbol implmeth = absmeth.implementation(impl, types, true);
- if (implmeth == null || implmeth == absmeth) {
- //look for default implementations
- if (allowDefaultMethods) {
- MethodSymbol prov = types.interfaceCandidates(impl.type, absmeth).head;
- if (prov != null && prov.overrides(absmeth, impl, types, true)) {
- implmeth = prov;
- }
- }
- }
- if (implmeth == null || implmeth == absmeth) {
- undef = absmeth;
- break;
- }
- }
- }
- if (undef == null) {
- Type st = types.supertype(c.type);
- if (st.hasTag(CLASS))
- undef = firstUndef(impl, (ClassSymbol)st.tsym);
- }
- for (List<Type> l = types.interfaces(c.type);
- undef == null && l.nonEmpty();
- l = l.tail) {
- undef = firstUndef(impl, (ClassSymbol)l.head.tsym);
- }
- }
- return undef;
- }
void checkNonCyclicDecl(JCClassDecl tree) {
CycleChecker cc = new CycleChecker();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Jan 29 03:54:45 2015 +0000
@@ -27,6 +27,9 @@
import com.sun.source.tree.LambdaExpressionTree.BodyKind;
import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.comp.Resolve.ResolveError;
+import com.sun.tools.javac.resources.CompilerProperties;
+import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.DefinedBy.Api;
@@ -37,6 +40,7 @@
import com.sun.tools.javac.comp.Infer.InferenceContext;
import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase;
import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler;
import java.util.ArrayList;
@@ -786,16 +790,22 @@
JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
mref2.expr = exprTree;
Symbol lookupSym =
- rs.resolveMemberReferenceByArity(localEnv, mref2, exprTree.type,
- tree.name, argtypes.toList(), inferenceContext);
+ rs.resolveMemberReference(localEnv, mref2, exprTree.type,
+ tree.name, argtypes.toList(), List.nil(), rs.arityMethodCheck,
+ inferenceContext, rs.structuralReferenceChooser).fst;
switch (lookupSym.kind) {
- //note: as argtypes are erroneous types, type-errors must
- //have been caused by arity mismatch
- case ABSENT_MTH:
case WRONG_MTH:
case WRONG_MTHS:
- case WRONG_STATICNESS:
- checkContext.report(tree, diags.fragment("incompatible.arg.types.in.mref"));
+ //note: as argtypes are erroneous types, type-errors must
+ //have been caused by arity mismatch
+ checkContext.report(tree, diags.fragment(Fragments.IncompatibleArgTypesInMref));
+ break;
+ case ABSENT_MTH:
+ case STATICERR:
+ //if no method found, or method found with wrong staticness, report better message
+ checkContext.report(tree, ((ResolveError)lookupSym).getDiagnostic(DiagnosticType.FRAGMENT,
+ tree, exprTree.type.tsym, exprTree.type, tree.name, argtypes.toList(), List.nil()));
+ break;
}
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java Thu Jan 29 03:54:45 2015 +0000
@@ -385,7 +385,7 @@
typeEnvs.put(c, localEnv);
// Fill out class fields.
- c.completer = typeEnter;
+ c.completer = null; // do not allow the initial completer linger on.
c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
c.sourcefile = env.toplevel.sourcefile;
c.members_field = WriteableScope.create(c);
@@ -409,6 +409,9 @@
// Enter type parameters.
ct.typarams_field = classEnter(tree.typarams, localEnv);
+ // install further completer for this type.
+ c.completer = typeEnter;
+
// Add non-local class to uncompleted, to make sure it will be
// completed later.
if (!c.isLocal() && uncompleted != null) uncompleted.append(c);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Jan 29 03:54:45 2015 +0000
@@ -263,7 +263,7 @@
@Override
public void visitLambda(JCLambda tree) {
LambdaTranslationContext localContext = (LambdaTranslationContext)context;
- MethodSymbol sym = (MethodSymbol)localContext.translatedSym;
+ MethodSymbol sym = localContext.translatedSym;
MethodType lambdaType = (MethodType) sym.type;
{
@@ -875,11 +875,9 @@
*/
private JCExpression expressionInvoke(VarSymbol rcvr) {
JCExpression qualifier =
- tree.sym.isStatic() ?
- make.Type(tree.sym.owner.type) :
- (rcvr != null) ?
- makeReceiver(rcvr) :
- tree.getQualifierExpression();
+ (rcvr != null) ?
+ makeReceiver(rcvr) :
+ tree.getQualifierExpression();
//create the qualifier expression
JCFieldAccess select = make.Select(qualifier, tree.sym.name);
@@ -891,7 +889,9 @@
convertArgs(tree.sym, args.toList(), tree.varargsElement)).
setType(tree.sym.erasure(types).getReturnType());
- apply = transTypes.coerce(apply, localContext.generatedRefSig().getReturnType());
+ apply = transTypes.coerce(attrEnv, apply,
+ types.erasure(localContext.tree.referentType.getReturnType()));
+
setVarargsIfNeeded(apply, tree.varargsElement);
return apply;
}
@@ -1755,7 +1755,7 @@
Map<LambdaSymbolKind, Map<Symbol, Symbol>> translatedSymbols;
/** the synthetic symbol for the method hoisting the translated lambda */
- Symbol translatedSym;
+ MethodSymbol translatedSym;
List<JCVariableDecl> syntheticParams;
@@ -1997,6 +1997,7 @@
//compute synthetic params
ListBuffer<JCVariableDecl> params = new ListBuffer<>();
+ ListBuffer<VarSymbol> parameterSymbols = new ListBuffer<>();
// The signature of the method is augmented with the following
// synthetic parameters:
@@ -2005,19 +2006,16 @@
// 2) enclosing locals captured by the lambda expression
for (Symbol thisSym : getSymbolMap(CAPTURED_VAR).values()) {
params.append(make.VarDef((VarSymbol) thisSym, null));
- }
- if (methodReferenceReceiver != null) {
- params.append(make.VarDef(
- make.Modifiers(PARAMETER|FINAL),
- names.fromString("$rcvr$"),
- make.Type(methodReferenceReceiver.type),
- null));
+ parameterSymbols.append((VarSymbol) thisSym);
}
for (Symbol thisSym : getSymbolMap(PARAM).values()) {
params.append(make.VarDef((VarSymbol) thisSym, null));
+ parameterSymbols.append((VarSymbol) thisSym);
}
syntheticParams = params.toList();
+ translatedSym.params = parameterSymbols.toList();
+
// Compute and set the lambda name
translatedSym.name = isSerializable()
? serializedLambdaName()
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Jan 29 03:54:45 2015 +0000
@@ -227,7 +227,7 @@
annotate.annotateTypeLater(tree, localEnv, m, tree.pos());
if (tree.defaultValue != null)
- annotateDefaultValueLater(tree.defaultValue, localEnv, m);
+ annotateDefaultValueLater(tree.defaultValue, localEnv, m, tree.pos());
}
/** Create a fresh environment for method bodies.
@@ -438,7 +438,8 @@
/** Queue processing of an attribute default value. */
void annotateDefaultValueLater(final JCExpression defaultValue,
final Env<AttrContext> localEnv,
- final MethodSymbol m) {
+ final MethodSymbol m,
+ final DiagnosticPosition deferPos) {
annotate.normal(new Annotate.Worker() {
@Override
public String toString() {
@@ -449,9 +450,11 @@
@Override
public void run() {
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
+ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(deferPos);
try {
enterDefaultValue(defaultValue, localEnv, m);
} finally {
+ deferredLintHandler.setPos(prevLintPos);
log.useSource(prev);
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Jan 29 03:54:45 2015 +0000
@@ -25,7 +25,6 @@
package com.sun.tools.javac.comp;
-import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import com.sun.tools.javac.api.Formattable.LocalizedString;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
@@ -40,6 +39,7 @@
import com.sun.tools.javac.comp.Infer.FreeTypeListener;
import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
+import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.tree.*;
@@ -65,6 +65,7 @@
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Flags.BLOCK;
+import static com.sun.tools.javac.code.Flags.STATIC;
import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.TypeTag.*;
@@ -105,15 +106,10 @@
context.put(resolveKey, this);
syms = Symtab.instance(context);
- varNotFound = new
- SymbolNotFoundError(ABSENT_VAR);
- methodNotFound = new
- SymbolNotFoundError(ABSENT_MTH);
- methodWithCorrectStaticnessNotFound = new
- SymbolNotFoundError(WRONG_STATICNESS,
- "method found has incorrect staticness");
- typeNotFound = new
- SymbolNotFoundError(ABSENT_TYP);
+ varNotFound = new SymbolNotFoundError(ABSENT_VAR);
+ methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
+ typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
+ referenceNotFound = new ReferenceLookupResult(methodNotFound, null);
names = Names.instance(context);
log = Log.instance(context);
@@ -145,9 +141,11 @@
*/
private final SymbolNotFoundError varNotFound;
private final SymbolNotFoundError methodNotFound;
- private final SymbolNotFoundError methodWithCorrectStaticnessNotFound;
private final SymbolNotFoundError typeNotFound;
+ /** empty reference lookup result */
+ private final ReferenceLookupResult referenceNotFound;
+
public static Resolve instance(Context context) {
Resolve instance = context.get(resolveKey);
if (instance == null)
@@ -2680,69 +2678,16 @@
List<Type> argtypes,
List<Type> typeargtypes,
MethodResolutionPhase maxPhase) {
- ReferenceLookupHelper result;
if (!name.equals(names.init)) {
//method reference
- result =
- new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+ return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+ } else if (site.hasTag(ARRAY)) {
+ //array constructor reference
+ return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
} else {
- if (site.hasTag(ARRAY)) {
- //array constructor reference
- result =
- new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
- } else {
- //class constructor reference
- result =
- new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
- }
+ //class constructor reference
+ return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
}
- return result;
- }
-
- Symbol resolveMemberReferenceByArity(Env<AttrContext> env,
- JCMemberReference referenceTree,
- Type site,
- Name name,
- List<Type> argtypes,
- InferenceContext inferenceContext) {
-
- boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
- site = types.capture(site);
-
- ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
- referenceTree, site, name, argtypes, null, VARARITY);
- //step 1 - bound lookup
- Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
- Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym,
- arityMethodCheck, boundLookupHelper);
- if (isStaticSelector &&
- !name.equals(names.init) &&
- !boundSym.isStatic() &&
- !boundSym.kind.isOverloadError()) {
- boundSym = methodNotFound;
- }
-
- //step 2 - unbound lookup
- Symbol unboundSym = methodNotFound;
- ReferenceLookupHelper unboundLookupHelper = null;
- Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
- if (isStaticSelector) {
- unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
- unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym,
- arityMethodCheck, unboundLookupHelper);
- if (unboundSym.isStatic() &&
- !unboundSym.kind.isOverloadError()) {
- unboundSym = methodNotFound;
- }
- }
-
- //merge results
- Symbol bestSym = choose(boundSym, unboundSym);
- env.info.pendingResolutionPhase = bestSym == unboundSym ?
- unboundEnv.info.pendingResolutionPhase :
- boundEnv.info.pendingResolutionPhase;
-
- return bestSym;
}
/**
@@ -2763,8 +2708,8 @@
* the receiver argument type is used to infer an instantiation for the raw
* qualifier type.
*
- * When a multi-step resolution process is exploited, it is an error
- * if two candidates are found (ambiguity).
+ * When a multi-step resolution process is exploited, the process of picking
+ * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}.
*
* This routine returns a pair (T,S), where S is the member reference symbol,
* and T is the type of the class in which S is defined. This is necessary as
@@ -2779,7 +2724,7 @@
List<Type> typeargtypes,
MethodCheck methodCheck,
InferenceContext inferenceContext,
- AttrMode mode) {
+ ReferenceChooser referenceChooser) {
site = types.capture(site);
ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
@@ -2787,102 +2732,29 @@
//step 1 - bound lookup
Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
- Symbol origBoundSym;
- boolean staticErrorForBound = false;
MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
boundSearchResolveContext.methodCheck = methodCheck;
- Symbol boundSym = origBoundSym = lookupMethod(boundEnv, env.tree.pos(),
+ Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(),
site.tsym, boundSearchResolveContext, boundLookupHelper);
- SearchResultKind boundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH;
- boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
- boolean shouldCheckForStaticness = isStaticSelector &&
- referenceTree.getMode() == ReferenceMode.INVOKE;
- if (boundSym.kind != WRONG_MTHS && boundSym.kind != WRONG_MTH) {
- if (shouldCheckForStaticness) {
- if (!boundSym.isStatic()) {
- staticErrorForBound = true;
- if (hasAnotherApplicableMethod(
- boundSearchResolveContext, boundSym, true)) {
- boundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC;
- } else {
- boundSearchResultKind = SearchResultKind.BAD_MATCH;
- if (!boundSym.kind.isOverloadError()) {
- boundSym = methodWithCorrectStaticnessNotFound;
- }
- }
- } else if (!boundSym.kind.isOverloadError()) {
- boundSearchResultKind = SearchResultKind.GOOD_MATCH;
- }
- }
- }
+ ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext);
//step 2 - unbound lookup
- Symbol origUnboundSym = null;
Symbol unboundSym = methodNotFound;
- ReferenceLookupHelper unboundLookupHelper = null;
Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
- SearchResultKind unboundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH;
- boolean staticErrorForUnbound = false;
- if (isStaticSelector) {
- unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
+ ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
+ ReferenceLookupResult unboundRes = referenceNotFound;
+ if (unboundLookupHelper != null) {
MethodResolutionContext unboundSearchResolveContext =
new MethodResolutionContext();
unboundSearchResolveContext.methodCheck = methodCheck;
- unboundSym = origUnboundSym = lookupMethod(unboundEnv, env.tree.pos(),
+ unboundSym = lookupMethod(unboundEnv, env.tree.pos(),
site.tsym, unboundSearchResolveContext, unboundLookupHelper);
-
- if (unboundSym.kind != WRONG_MTH && unboundSym.kind != WRONG_MTHS) {
- if (shouldCheckForStaticness) {
- if (unboundSym.isStatic()) {
- staticErrorForUnbound = true;
- if (hasAnotherApplicableMethod(
- unboundSearchResolveContext, unboundSym, false)) {
- unboundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC;
- } else {
- unboundSearchResultKind = SearchResultKind.BAD_MATCH;
- if (!unboundSym.kind.isOverloadError()) {
- unboundSym = methodWithCorrectStaticnessNotFound;
- }
- }
- } else if (!unboundSym.kind.isOverloadError()) {
- unboundSearchResultKind = SearchResultKind.GOOD_MATCH;
- }
- }
- }
+ unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext);
}
//merge results
Pair<Symbol, ReferenceLookupHelper> res;
- Symbol bestSym = choose(boundSym, unboundSym);
- if (!bestSym.kind.isOverloadError() &&
- (staticErrorForBound || staticErrorForUnbound)) {
- if (staticErrorForBound) {
- boundSym = methodWithCorrectStaticnessNotFound;
- }
- if (staticErrorForUnbound) {
- unboundSym = methodWithCorrectStaticnessNotFound;
- }
- bestSym = choose(boundSym, unboundSym);
- }
- if (bestSym == methodWithCorrectStaticnessNotFound && mode == AttrMode.CHECK) {
- Symbol symToPrint = origBoundSym;
- String errorFragmentToPrint = "non-static.cant.be.ref";
- if (staticErrorForBound && staticErrorForUnbound) {
- if (unboundSearchResultKind == SearchResultKind.BAD_MATCH_MORE_SPECIFIC) {
- symToPrint = origUnboundSym;
- errorFragmentToPrint = "static.method.in.unbound.lookup";
- }
- } else {
- if (!staticErrorForBound) {
- symToPrint = origUnboundSym;
- errorFragmentToPrint = "static.method.in.unbound.lookup";
- }
- }
- log.error(referenceTree.expr.pos(), "invalid.mref",
- Kinds.kindName(referenceTree.getMode()),
- diags.fragment(errorFragmentToPrint,
- Kinds.kindName(symToPrint), symToPrint));
- }
+ Symbol bestSym = referenceChooser.result(boundRes, unboundRes);
res = new Pair<>(bestSym,
bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper);
env.info.pendingResolutionPhase = bestSym == unboundSym ?
@@ -2892,67 +2764,213 @@
return res;
}
- enum SearchResultKind {
- GOOD_MATCH, //type I
- BAD_MATCH_MORE_SPECIFIC, //type II
- BAD_MATCH, //type III
- NOT_APPLICABLE_MATCH //type IV
- }
-
- boolean hasAnotherApplicableMethod(MethodResolutionContext resolutionContext,
- Symbol bestSoFar, boolean staticMth) {
- for (Candidate c : resolutionContext.candidates) {
- if (resolutionContext.step != c.step ||
- !c.isApplicable() ||
- c.sym == bestSoFar) {
- continue;
- } else {
- if (c.sym.isStatic() == staticMth) {
- return true;
+ /**
+ * This class is used to represent a method reference lookup result. It keeps track of two
+ * things: (i) the symbol found during a method reference lookup and (ii) the static kind
+ * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}).
+ */
+ static class ReferenceLookupResult {
+
+ /**
+ * Static kind associated with a method reference lookup. Erroneous lookups end up with
+ * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC,
+ * depending on whether all applicable candidates are static or non-static methods,
+ * respectively. If a successful lookup has both static and non-static applicable methods,
+ * its kind is set to BOTH.
+ */
+ enum StaticKind {
+ STATIC,
+ NON_STATIC,
+ BOTH,
+ UNDEFINED;
+
+ /**
+ * Retrieve the static kind associated with a given (method) symbol.
+ */
+ static StaticKind from(Symbol s) {
+ return s.isStatic() ?
+ STATIC : NON_STATIC;
+ }
+
+ /**
+ * Merge two static kinds together.
+ */
+ static StaticKind reduce(StaticKind sk1, StaticKind sk2) {
+ if (sk1 == UNDEFINED) {
+ return sk2;
+ } else if (sk2 == UNDEFINED) {
+ return sk1;
+ } else {
+ return sk1 == sk2 ? sk1 : BOTH;
}
}
}
- return false;
- }
-
- //where
- private Symbol choose(Symbol boundSym, Symbol unboundSym) {
- if (lookupSuccess(boundSym) && lookupSuccess(unboundSym)) {
- return ambiguityError(boundSym, unboundSym);
- } else if (lookupSuccess(boundSym) ||
- (canIgnore(unboundSym) && !canIgnore(boundSym))) {
- return boundSym;
- } else if (lookupSuccess(unboundSym) ||
- (canIgnore(boundSym) && !canIgnore(unboundSym))) {
- return unboundSym;
- } else {
- return boundSym;
+
+ /** The static kind. */
+ StaticKind staticKind;
+
+ /** The lookup result. */
+ Symbol sym;
+
+ ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext) {
+ this.staticKind = staticKind(sym, resolutionContext);
+ this.sym = sym;
+ }
+
+ private StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) {
+ switch (sym.kind) {
+ case MTH:
+ case AMBIGUOUS:
+ return resolutionContext.candidates.stream()
+ .filter(c -> c.isApplicable() && c.step == resolutionContext.step)
+ .map(c -> StaticKind.from(c.sym))
+ .reduce(StaticKind::reduce)
+ .orElse(StaticKind.UNDEFINED);
+ case HIDDEN:
+ return StaticKind.from(((AccessError)sym).sym);
+ default:
+ return StaticKind.UNDEFINED;
}
}
- private boolean lookupSuccess(Symbol s) {
- return s.kind == MTH || s.kind == AMBIGUOUS;
+ /**
+ * Does this result corresponds to a successful lookup (i.e. one where a method has been found?)
+ */
+ boolean isSuccess() {
+ return staticKind != StaticKind.UNDEFINED;
}
- private boolean canIgnore(Symbol s) {
- switch (s.kind) {
+ /**
+ * Does this result have given static kind?
+ */
+ boolean hasKind(StaticKind sk) {
+ return this.staticKind == sk;
+ }
+
+ /**
+ * Error recovery helper: can this lookup result be ignored (for the purpose of returning
+ * some 'better' result) ?
+ */
+ boolean canIgnore() {
+ switch (sym.kind) {
case ABSENT_MTH:
return true;
case WRONG_MTH:
InapplicableSymbolError errSym =
- (InapplicableSymbolError)s.baseSymbol();
+ (InapplicableSymbolError)sym.baseSymbol();
return new Template(MethodCheckDiag.ARITY_MISMATCH.regex())
.matches(errSym.errCandidate().snd);
case WRONG_MTHS:
InapplicableSymbolsError errSyms =
- (InapplicableSymbolsError)s.baseSymbol();
+ (InapplicableSymbolsError)sym.baseSymbol();
return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty();
- case WRONG_STATICNESS:
- return false;
default:
return false;
}
}
+ }
+
+ /**
+ * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup)
+ * {@code ReferenceLookupResult} objects into a (@code Symbol), which is then regarded as the
+ * result of method reference resolution.
+ */
+ abstract class ReferenceChooser {
+ /**
+ * Generate a result from a pair of lookup result objects. This method delegates to the
+ * appropriate result generation routine.
+ */
+ Symbol result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
+ return unboundRes != referenceNotFound ?
+ unboundResult(boundRes, unboundRes) :
+ boundResult(boundRes);
+ }
+
+ /**
+ * Generate a symbol from a given bound lookup result.
+ */
+ abstract Symbol boundResult(ReferenceLookupResult boundRes);
+
+ /**
+ * Generate a symbol from a pair of bound/unbound lookup results.
+ */
+ abstract Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
+ }
+
+ /**
+ * This chooser implements the selection strategy used during a full lookup; this logic
+ * is described in JLS SE 8 (15.3.2).
+ */
+ ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
+
+ @Override
+ Symbol boundResult(ReferenceLookupResult boundRes) {
+ return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
+ boundRes.sym : //the search produces a non-static method
+ new BadMethodReferenceError(boundRes.sym, false);
+ }
+
+ @Override
+ Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
+ if (boundRes.hasKind(StaticKind.STATIC) &&
+ (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
+ //the first search produces a static method and no non-static method is applicable
+ //during the second search
+ return boundRes.sym;
+ } else if (unboundRes.hasKind(StaticKind.NON_STATIC) &&
+ (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
+ //the second search produces a non-static method and no static method is applicable
+ //during the first search
+ return unboundRes.sym;
+ } else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
+ //both searches produce some result; ambiguity (error recovery)
+ return ambiguityError(boundRes.sym, unboundRes.sym);
+ } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
+ //Both searches failed to produce a result with correct staticness (i.e. first search
+ //produces an non-static method). Alternatively, a given search produced a result
+ //with the right staticness, but the other search has applicable methods with wrong
+ //staticness (error recovery)
+ return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
+ } else {
+ //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
+ return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
+ unboundRes.sym : boundRes.sym;
+ }
+ }
+ };
+
+ /**
+ * This chooser implements the selection strategy used during an arity-based lookup; this logic
+ * is described in JLS SE 8 (15.12.2.1).
+ */
+ ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
+
+ @Override
+ Symbol boundResult(ReferenceLookupResult boundRes) {
+ return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
+ boundRes.sym : //the search has at least one applicable non-static method
+ new BadMethodReferenceError(boundRes.sym, false);
+ }
+
+ @Override
+ Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
+ if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
+ //the first serach has at least one applicable static method
+ return boundRes.sym;
+ } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
+ //the second search has at least one applicable non-static method
+ return unboundRes.sym;
+ } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
+ //either the first search produces a non-static method, or second search produces
+ //a non-static method (error recovery)
+ return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
+ } else {
+ //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
+ return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
+ unboundRes.sym : boundRes.sym;
+ }
+ }
+ };
/**
* Helper for defining custom method-like lookup logic; a lookup helper
@@ -3070,22 +3088,7 @@
* method returns an dummy lookup helper.
*/
ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
- //dummy loopkup helper that always return 'methodNotFound'
- return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
- @Override
- ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
- return this;
- }
- @Override
- Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
- return methodNotFound;
- }
- @Override
- ReferenceKind referenceKind(Symbol sym) {
- Assert.error();
- return null;
- }
- };
+ return null;
}
/**
@@ -3124,12 +3127,31 @@
@Override
ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
- if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
- argtypes.nonEmpty() &&
- (argtypes.head.hasTag(NONE) ||
- types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) {
- return new UnboundMethodReferenceLookupHelper(referenceTree, name,
- site, argtypes, typeargtypes, maxPhase);
+ if (TreeInfo.isStaticSelector(referenceTree.expr, names)) {
+ if (argtypes.nonEmpty() &&
+ (argtypes.head.hasTag(NONE) ||
+ types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), site))) {
+ return new UnboundMethodReferenceLookupHelper(referenceTree, name,
+ site, argtypes, typeargtypes, maxPhase);
+ } else {
+ return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
+ @Override
+ ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
+ return this;
+ }
+
+ @Override
+ Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ return methodNotFound;
+ }
+
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ Assert.error();
+ return null;
+ }
+ };
+ }
} else {
return super.unboundLookup(inferenceContext);
}
@@ -3231,16 +3253,10 @@
findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
findMethod(env, site, name, argtypes, typeargtypes,
phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
- return sym.kind != MTH ||
- site.getEnclosingType().hasTag(NONE) ||
- hasEnclosingInstance(env, site) ?
- sym : new InvalidSymbolError(MISSING_ENCL, sym, null) {
- @Override
- JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
- return diags.create(dkind, log.currentSource(), pos,
- "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
- }
- };
+ return (sym.kind != MTH ||
+ site.getEnclosingType().hasTag(NONE) ||
+ hasEnclosingInstance(env, site)) ?
+ sym : new BadConstructorReferenceError(sym);
}
@Override
@@ -3613,8 +3629,7 @@
hasLocation = !location.name.equals(names._this) &&
!location.name.equals(names._super);
}
- boolean isConstructor = (kind == ABSENT_MTH || kind == WRONG_STATICNESS) &&
- name == names.init;
+ boolean isConstructor = name == names.init;
KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind();
Name idname = isConstructor ? site.tsym.name : name;
String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
@@ -4019,13 +4034,13 @@
Name sname = s1.name;
if (sname == names.init) sname = s1.owner.name;
return diags.create(dkind, log.currentSource(),
- pos, "ref.ambiguous", sname,
- kindName(s1),
- s1,
- s1.location(site, types),
- kindName(s2),
- s2,
- s2.location(site, types));
+ pos, "ref.ambiguous", sname,
+ kindName(s1),
+ s1,
+ s1.location(site, types),
+ kindName(s2),
+ s2,
+ s2.location(site, types));
}
/**
@@ -4108,6 +4123,52 @@
}
/**
+ * BadMethodReferenceError error class indicating that a method reference symbol has been found,
+ * but with the wrong staticness.
+ */
+ class BadMethodReferenceError extends StaticError {
+
+ boolean unboundLookup;
+
+ public BadMethodReferenceError(Symbol sym, boolean unboundLookup) {
+ super(sym);
+ this.unboundLookup = unboundLookup;
+ }
+
+ @Override
+ JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
+ final String key;
+ if (!unboundLookup) {
+ key = "bad.static.method.in.bound.lookup";
+ } else if (sym.isStatic()) {
+ key = "bad.static.method.in.unbound.lookup";
+ } else {
+ key = "bad.instance.method.in.unbound.lookup";
+ }
+ return sym.kind.isOverloadError() ?
+ ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) :
+ diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym);
+ }
+ }
+
+ /**
+ * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found,
+ * but pointing to a class for which an enclosing instance is not available.
+ */
+ class BadConstructorReferenceError extends InvalidSymbolError {
+
+ public BadConstructorReferenceError(Symbol sym) {
+ super(MISSING_ENCL, sym, "BadConstructorReferenceError");
+ }
+
+ @Override
+ JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
+ return diags.create(dkind, log.currentSource(), pos,
+ "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
+ }
+ }
+
+ /**
* Helper class for method resolution diagnostic simplification.
* Certain resolution diagnostic are rewritten as simpler diagnostic
* where the enclosing resolution diagnostic (i.e. 'inapplicable method')
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Jan 29 03:54:45 2015 +0000
@@ -1000,6 +1000,7 @@
l.nonEmpty();
l = l.tail) {
ClassSymbol inner = l.head;
+ inner.markAbstractIfNeeded(types);
char flags = (char) adjustFlags(inner.flags_field);
if ((flags & INTERFACE) != 0) flags |= ABSTRACT; // Interfaces are always ABSTRACT
if (inner.name.isEmpty()) flags &= ~FINAL; // Anonymous class: unset FINAL flag
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Jan 29 03:54:45 2015 +0000
@@ -85,7 +85,7 @@
private Names names;
/** End position mappings container */
- private final AbstractEndPosTable endPosTable;
+ protected final AbstractEndPosTable endPosTable;
// Because of javac's limited lookahead, some contexts are ambiguous in
// the presence of type annotations even though they are not ambiguous
@@ -1209,15 +1209,7 @@
if (annos.nonEmpty()) {
t = toP(F.at(pos).AnnotatedType(annos, t));
}
- // .class is only allowed if there were no annotations
- JCExpression nt = bracketsSuffix(t);
- if (nt != t && (annos.nonEmpty() || TreeInfo.containsTypeAnnotation(t))) {
- // t and nt are different if bracketsSuffix parsed a .class.
- // The check for nonEmpty covers the case when the whole array is annotated.
- // Helper method isAnnotated looks for annos deeply within t.
- syntaxError("no.annotations.on.dot.class");
- }
- t = nt;
+ t = bracketsSuffix(t);
} else {
if ((mode & EXPR) != 0) {
mode = EXPR;
@@ -1956,6 +1948,12 @@
}
t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
} else {
+ Tag tag = t.getTag();
+ // Type annotations are illegal on class literals. Annotated non array class literals
+ // are complained about directly in term3(), Here check for type annotations on dimensions
+ // taking care to handle some interior dimension(s) being annotated.
+ if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
+ syntaxError("no.annotations.on.dot.class");
t = toP(F.at(pos).Select(t, names._class));
}
} else if ((mode & TYPE) != 0) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacMessager.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacMessager.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import javax.lang.model.element.*;
@@ -113,13 +114,7 @@
switch (kind) {
case ERROR:
errorCount++;
- boolean prev = log.multipleErrors;
- log.multipleErrors = true;
- try {
- log.error(pos, "proc.messager", msg.toString());
- } finally {
- log.multipleErrors = prev;
- }
+ log.error(DiagnosticFlag.MULTIPLE, pos, "proc.messager", msg.toString());
break;
case WARNING:
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Jan 29 03:54:45 2015 +0000
@@ -262,9 +262,6 @@
compiler.misc.static.mref.with.targs=\
parameterized qualifier on static method reference
-compiler.misc.static.bound.mref=\
- static bound method reference
-
# 0: symbol
compiler.err.cant.assign.val.to.final.var=\
cannot assign a value to final variable {0}
@@ -2050,12 +2047,16 @@
non-static {0} {1} cannot be referenced from a static context
# 0: symbol kind, 1: symbol
-compiler.misc.non-static.cant.be.ref=\
- non-static {0} {1} cannot be referenced from a static context
+compiler.misc.bad.static.method.in.unbound.lookup=\
+ unexpected static {0} {1} found in unbound lookup
# 0: symbol kind, 1: symbol
-compiler.misc.static.method.in.unbound.lookup=\
- static {0} {1} found in unbound lookup
+compiler.misc.bad.instance.method.in.unbound.lookup=\
+ unexpected instance {0} {1} found in unbound lookup
+
+# 0: symbol kind, 1: symbol
+compiler.misc.bad.static.method.in.bound.lookup=\
+ unexpected static {0} {1} found in bound lookup
## Both arguments ({0}, {1}) are "kindname"s. {0} is a comma-separated list
## of kindnames (the list should be identical to that provided in source.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Jan 29 03:54:45 2015 +0000
@@ -2101,6 +2101,7 @@
public PolyKind refPolyKind;
public boolean ownerAccessible;
public OverloadKind overloadKind;
+ public Type referentType;
public enum OverloadKind {
OVERLOADED,
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JCDiagnostic.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -112,7 +112,7 @@
*/
public JCDiagnostic error(
DiagnosticFlag flag, DiagnosticSource source, DiagnosticPosition pos, Error errorKey) {
- JCDiagnostic diag = create(null, defaultErrorFlags, source, pos, errorKey);
+ JCDiagnostic diag = create(null, EnumSet.copyOf(defaultErrorFlags), source, pos, errorKey);
if (flag != null) {
diag.setFlag(flag);
}
@@ -432,7 +432,10 @@
SYNTAX,
RECOVERABLE,
NON_DEFERRABLE,
- COMPRESSED
+ COMPRESSED,
+ /** Print multiple errors for same source locations.
+ */
+ MULTIPLE;
}
private final DiagnosticSource source;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java Thu Jan 29 03:54:45 2015 +0000
@@ -33,6 +33,7 @@
import java.util.AbstractCollection;
import java.util.ListIterator;
import java.util.NoSuchElementException;
+import java.util.stream.Collector;
/** A class for generic linked lists. Links are supposed to be
* immutable, the only exception being the incremental construction of
@@ -537,4 +538,14 @@
return Collections.unmodifiableList(a);
}
+
+ /**
+ * Collect elements into a new list (using a @code{ListBuffer})
+ */
+ public static <Z> Collector<Z, ListBuffer<Z>, List<Z>> collector() {
+ return Collector.of(ListBuffer::new,
+ (buf, el)->buf.add(el),
+ (buf1, buf2)-> { buf1.addAll(buf2); return buf1; },
+ buf->buf.toList());
+ }
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,7 @@
import com.sun.tools.javac.main.Main;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.tree.EndPosTable;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
@@ -191,10 +192,6 @@
*/
public boolean dumpOnError;
- /** Print multiple errors for same source locations.
- */
- public boolean multipleErrors;
-
/**
* Diagnostic listener, if provided through programmatic
* interface to javac (JSR 199).
@@ -417,7 +414,7 @@
* source name and pos.
*/
protected boolean shouldReport(JavaFileObject file, int pos) {
- if (multipleErrors || file == null)
+ if (file == null)
return true;
Pair<JavaFileObject,Integer> coords = new Pair<>(file, pos);
@@ -580,8 +577,9 @@
break;
case ERROR:
- if (nerrors < MaxErrors
- && shouldReport(diagnostic.getSource(), diagnostic.getIntPosition())) {
+ if (nerrors < MaxErrors &&
+ (diagnostic.isFlagSet(DiagnosticFlag.MULTIPLE) ||
+ shouldReport(diagnostic.getSource(), diagnostic.getIntPosition()))) {
writeDiagnostic(diagnostic);
nerrors++;
}
--- a/langtools/test/tools/doclint/AnchorTest.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/doclint/AnchorTest.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,4 +1,4 @@
-AnchorTest.java:19: error: anchor already defined: foo
+AnchorTest.java:19: error: anchor already defined: "foo"
* <a name=foo></a>
^
AnchorTest.java:24: error: invalid name for anchor: ""
@@ -10,28 +10,40 @@
AnchorTest.java:34: error: no value given for anchor
* <a name ></a>
^
-AnchorTest.java:46: error: anchor already defined: foo
+AnchorTest.java:46: error: anchor already defined: "foo"
* <a id=foo></a>
^
AnchorTest.java:51: error: invalid name for anchor: ""
* <a id=></a>
^
+AnchorTest.java:51: error: anchor already defined: ""
+ * <a id=></a>
+ ^
AnchorTest.java:56: error: invalid name for anchor: "123"
* <a id=123 ></a>
^
+AnchorTest.java:56: error: anchor already defined: "123"
+ * <a id=123 ></a>
+ ^
AnchorTest.java:61: error: no value given for anchor
* <a id ></a>
^
-AnchorTest.java:73: error: anchor already defined: foo
+AnchorTest.java:73: error: anchor already defined: "foo"
* <p id=foo>text</p>
^
AnchorTest.java:78: error: invalid name for anchor: ""
* <p id=>text</p>
^
+AnchorTest.java:78: error: anchor already defined: ""
+ * <p id=>text</p>
+ ^
AnchorTest.java:83: error: invalid name for anchor: "123"
* <p id=123 >text</p>
^
+AnchorTest.java:83: error: anchor already defined: "123"
+ * <p id=123 >text</p>
+ ^
AnchorTest.java:88: error: no value given for anchor
* <p id >text</p>
^
-12 errors
+16 errors
--- a/langtools/test/tools/doclint/AnchorTest2.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/doclint/AnchorTest2.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,4 +1,4 @@
-AnchorTest2.java:15: error: anchor already defined: AnchorTest2
+AnchorTest2.java:15: error: anchor already defined: "AnchorTest2"
/** <a name="AnchorTest2"> </a> */
^
1 error
--- a/langtools/test/tools/doclint/HtmlTagsTest.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/doclint/HtmlTagsTest.out Thu Jan 29 03:54:45 2015 +0000
@@ -13,6 +13,9 @@
HtmlTagsTest.java:28: error: element not allowed in documentation comments: <html>
* <html>
^
+HtmlTagsTest.java:28: error: element not closed: html
+ * <html>
+ ^
HtmlTagsTest.java:33: error: block element not allowed within inline element <span>: p
* <span> <p> </span>
^
@@ -40,5 +43,5 @@
HtmlTagsTest.java:64: error: tag not allowed here: <b>
* <ul> <b>text</b> <li> ... </li> </ul>
^
-13 errors
-1 warning
+14 errors
+1 warning
\ No newline at end of file
--- a/langtools/test/tools/doclint/anchorTests/p/Test.javac.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/doclint/anchorTests/p/Test.javac.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,7 +1,7 @@
-Test.java:14:7: compiler.err.proc.messager: anchor already defined: dupTest
-Test.java:24:12: compiler.err.proc.messager: anchor already defined: dupTestField
-Test.java:27:12: compiler.err.proc.messager: anchor already defined: dupTestMethod
-Test.java:32:11: compiler.err.proc.messager: anchor already defined: dupNested
-Test.java:40:15: compiler.err.proc.messager: anchor already defined: dupNestedField
-Test.java:47:15: compiler.err.proc.messager: anchor already defined: dupNestedMethod
+Test.java:14:7: compiler.err.proc.messager: anchor already defined: "dupTest"
+Test.java:24:12: compiler.err.proc.messager: anchor already defined: "dupTestField"
+Test.java:27:12: compiler.err.proc.messager: anchor already defined: "dupTestMethod"
+Test.java:32:11: compiler.err.proc.messager: anchor already defined: "dupNested"
+Test.java:40:15: compiler.err.proc.messager: anchor already defined: "dupNestedField"
+Test.java:47:15: compiler.err.proc.messager: anchor already defined: "dupNestedMethod"
6 errors
--- a/langtools/test/tools/doclint/anchorTests/p/Test.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/doclint/anchorTests/p/Test.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,19 +1,19 @@
-Test.java:14: error: anchor already defined: dupTest
+Test.java:14: error: anchor already defined: "dupTest"
* <a name="dupTest">dupTest again</a>
^
-Test.java:24: error: anchor already defined: dupTestField
+Test.java:24: error: anchor already defined: "dupTestField"
/** <a name="dupTestField">dupTestField again</a> */
^
-Test.java:27: error: anchor already defined: dupTestMethod
+Test.java:27: error: anchor already defined: "dupTestMethod"
/** <a name="dupTestMethod">dupTestMethod again</a> */
^
-Test.java:32: error: anchor already defined: dupNested
+Test.java:32: error: anchor already defined: "dupNested"
* <a name="dupNested">dupNested again</a>
^
-Test.java:40: error: anchor already defined: dupNestedField
+Test.java:40: error: anchor already defined: "dupNestedField"
* <a name="dupNestedField">dupNestedField</a>
^
-Test.java:47: error: anchor already defined: dupNestedMethod
+Test.java:47: error: anchor already defined: "dupNestedMethod"
* <a name="dupNestedMethod">dupNestedMethod</a>
^
6 errors
--- a/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/doclint/anchorTests/p/package-info.javac.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,2 +1,2 @@
-package-info.java:12:7: compiler.err.proc.messager: anchor already defined: here
+package-info.java:12:7: compiler.err.proc.messager: anchor already defined: "here"
1 error
--- a/langtools/test/tools/doclint/anchorTests/p/package-info.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/doclint/anchorTests/p/package-info.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,4 +1,4 @@
-package-info.java:12: error: anchor already defined: here
+package-info.java:12: error: anchor already defined: "here"
* <a name=here>here again</a>
^
1 error
--- a/langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/doclint/tidy/AnchorAlreadyDefined.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,7 +1,7 @@
-AnchorAlreadyDefined.java:14: error: anchor already defined: here
+AnchorAlreadyDefined.java:14: error: anchor already defined: "here"
* <a name="here">duplicate</a>
^
-AnchorAlreadyDefined.java:15: error: anchor already defined: here
+AnchorAlreadyDefined.java:15: error: anchor already defined: "here"
* <h1 id="here">duplicate</h1>
^
2 errors
--- a/langtools/test/tools/javac/6304921/TestLog.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/6304921/TestLog.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,11 @@
* @bug 6304912
* @summary unit test for Log
*/
+import java.lang.reflect.Field;
import java.io.InputStream;
-import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
+import java.util.Set;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import com.sun.tools.javac.file.JavacFileManager;
@@ -41,23 +42,34 @@
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
+import com.sun.tools.javac.util.JCDiagnostic.Factory;
import com.sun.tools.javac.util.Options;
public class TestLog
{
- public static void main(String... args) throws IOException {
+ public static void main(String... args) throws Exception {
test(false);
test(true);
}
- static void test(boolean genEndPos) throws IOException {
+ static void test(boolean genEndPos) throws Exception {
Context context = new Context();
Options options = Options.instance(context);
options.put("diags", "%b:%s/%o/%e:%_%t%m|%p%m");
Log log = Log.instance(context);
- log.multipleErrors = true;
+ Factory diagnosticFactory = JCDiagnostic.Factory.instance(context);
+ Field defaultErrorFlagsField =
+ JCDiagnostic.Factory.class.getDeclaredField("defaultErrorFlags");
+
+ defaultErrorFlagsField.setAccessible(true);
+
+ Set<DiagnosticFlag> defaultErrorFlags =
+ (Set<DiagnosticFlag>) defaultErrorFlagsField.get(diagnosticFactory);
+
+ defaultErrorFlags.add(DiagnosticFlag.MULTIPLE);
JavacFileManager.preRegister(context);
ParserFactory pfac = ParserFactory.instance(context);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8052070/DuplicateTypeParameter.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8052070
+ * @summary javac crashes when there are duplicated type parameters
+ * @compile/fail/ref=DuplicateTypeParameter.out -XDrawDiagnostics DuplicateTypeParameter.java
+ */
+
+public class DuplicateTypeParameter<T, T, A> {
+ class Inner <P, P, Q> {}
+ public void foo() {
+ class Local <M, M, N> {};
+ }
+}
+
+class Secondary<D, D, E> {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8052070/DuplicateTypeParameter.out Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,5 @@
+DuplicateTypeParameter.java:8:40: compiler.err.already.defined: kindname.type.variable, T, kindname.class, DuplicateTypeParameter
+DuplicateTypeParameter.java:9:21: compiler.err.already.defined: kindname.type.variable, P, kindname.class, DuplicateTypeParameter.Inner
+DuplicateTypeParameter.java:15:20: compiler.err.already.defined: kindname.type.variable, D, kindname.class, Secondary
+DuplicateTypeParameter.java:11:25: compiler.err.already.defined: kindname.type.variable, M, kindname.class, Local
+4 errors
--- a/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/MethodParameters/ClassFileVisitor.java Thu Jan 29 03:54:45 2015 +0000
@@ -147,6 +147,7 @@
public int mAttrs;
public int mNumParams;
public boolean mSynthetic;
+ public boolean mIsLambda;
public boolean mIsConstructor;
public boolean mIsClinit;
public boolean mIsBridge;
@@ -165,6 +166,7 @@
mIsClinit = mName.equals("<clinit>");
prefix = cname + "." + mName + "() - ";
mIsBridge = method.access_flags.is(AccessFlags.ACC_BRIDGE);
+ mIsLambda = mSynthetic && mName.startsWith("lambda$");
if (mIsClinit) {
sb = new StringBuilder(); // Discard output
@@ -225,7 +227,7 @@
// IMPL: Whether MethodParameters attributes will be generated
// for some synthetics is unresolved. For now, assume no.
- if (mSynthetic) {
+ if (mSynthetic && !mIsLambda) {
warn(prefix + "synthetic has MethodParameter attribute");
}
@@ -349,10 +351,12 @@
} else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) {
expect = "name";
allowMandated = true;
- } else if (mIsBridge) {
+ } else if (mIsBridge || mIsLambda) {
allowSynthetic = true;
/* you can't expect an special name for bridges' parameters.
- * The name of the original parameters are now copied.
+ * The name of the original parameters are now copied. Likewise
+ * for a method encoding the lambda expression, names are derived
+ * from source lambda's parameters and captured enclosing locals.
*/
expect = null;
}
--- a/langtools/test/tools/javac/MethodParameters/LambdaTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/MethodParameters/LambdaTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8006582
+ * @bug 8006582 8037546
* @summary javac should generate method parameters correctly.
* @build Tester
* @compile -parameters LambdaTest.java
@@ -31,8 +31,8 @@
*/
/**
- * Parameter names are not recorded for lambdas. This test verifies
- * that there are no MethodParameters attribute for lambdas.
+ * Post https://bugs.openjdk.java.net/browse/JDK-8037546, this test verifies
+ * that MethodParameters attribute for lambdas are emitted properly.
*/
class LambdaTest {
--- a/langtools/test/tools/javac/MethodParameters/LambdaTest.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/MethodParameters/LambdaTest.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,7 +1,7 @@
class LambdaTest --
LambdaTest.<init>()
LambdaTest.foo(i)
-LambdaTest.lambda$static$1(arg0)/*synthetic*/
-LambdaTest.lambda$null$0(arg0, arg1)/*synthetic*/
+LambdaTest.lambda$static$1(x1/*synthetic*/)/*synthetic*/
+LambdaTest.lambda$null$0(final cap$0/*synthetic*/, x2/*synthetic*/)/*synthetic*/
static interface LambdaTest$I -- inner
LambdaTest$I.m(x)
--- a/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/MethodParameters/ReflectionVisitor.java Thu Jan 29 03:54:45 2015 +0000
@@ -277,7 +277,7 @@
param = "final " + param;
}
sb.append(sep).append(param);
- if (!m.isBridge() && !expect.equals(param)) {
+ if (!m.isBridge() && !m.getName().startsWith("lambda$") && !expect.equals(param)) {
error(prefix + "param[" + i + "]='"
+ param + "' expected '" + expect + "'");
break;
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.java Thu Jan 29 03:54:45 2015 +0000
@@ -1,6 +1,6 @@
/*
* @test /nodynamiccopyright/
- * @bug 8027262
+ * @bug 8027262 8027888
* @summary A class expression cannot be annotated.
* @compile/fail/ref=AnnotatedClassExpr.out -XDrawDiagnostics AnnotatedClassExpr.java
*/
@@ -10,6 +10,12 @@
class AnnotatedClassExpr {
static void main() {
Object o1 = @A int.class;
+ o1 = @A int [] . class;
+ o1 = int @A [] . class;
+ o1 = int [] @A [] . class;
+ o1 = AnnotatedClassExpr @A [] .class;
+ o1 = @A AnnotatedClassExpr @A [] .class;
+ o1 = @A AnnotatedClassExpr.class;
}
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,2 +1,8 @@
AnnotatedClassExpr.java:12:29: compiler.err.no.annotations.on.dot.class
-1 error
+AnnotatedClassExpr.java:13:27: compiler.err.no.annotations.on.dot.class
+AnnotatedClassExpr.java:14:27: compiler.err.no.annotations.on.dot.class
+AnnotatedClassExpr.java:15:30: compiler.err.no.annotations.on.dot.class
+AnnotatedClassExpr.java:16:41: compiler.err.no.annotations.on.dot.class
+AnnotatedClassExpr.java:17:44: compiler.err.no.annotations.on.dot.class
+AnnotatedClassExpr.java:18:37: compiler.err.no.annotations.on.dot.class
+7 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/InnerClasses/T8068517.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/** @test
+ * @bug 8034854
+ * @summary Verify that nested enums have correct abstract flag in the InnerClasses attribute.
+ * @library /tools/lib
+ * @build ToolBox T8068517
+ * @run main T8068517
+ */
+
+import com.sun.tools.javac.util.Assert;
+import java.util.Arrays;
+import javax.tools.JavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+public class T8068517 {
+
+ public static void main(String[] args) throws Exception {
+ new T8068517().run();
+ }
+
+ void run() throws Exception {
+ runTest("class A {\n" +
+ " enum AInner implements Runnable {\n" +
+ " A {\n" +
+ " public void run() {}\n" +
+ " };\n" +
+ " }\n" +
+ "}\n",
+ "class B {\n" +
+ " A.AInner a;\n" +
+ "}");
+ runTest("class A {\n" +
+ " enum AInner implements Runnable {\n" +
+ " A {\n" +
+ " public void run() {}\n" +
+ " };\n" +
+ " }\n" +
+ " AInner aInner;\n" +
+ "}\n",
+ "class B {\n" +
+ " void test(A a) {;\n" +
+ " switch (a.aInner) {\n" +
+ " case A: break;\n" +
+ " }\n" +
+ " };\n" +
+ "}");
+ runTest("class A {\n" +
+ " enum AInner implements Runnable {\n" +
+ " A {\n" +
+ " public void run() {}\n" +
+ " };\n" +
+ " }\n" +
+ " AInner aInner;\n" +
+ "}\n",
+ "class B {\n" +
+ " void test(A a) {;\n" +
+ " System.err.println(a.aInner.toString());\n" +
+ " };\n" +
+ "}");
+ runTest("class A {\n" +
+ " enum AInner implements Runnable {\n" +
+ " A {\n" +
+ " public void run() {}\n" +
+ " };\n" +
+ " }\n" +
+ " AInner aInner() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n",
+ "class B {\n" +
+ " void test(A a) {;\n" +
+ " System.err.println(a.aInner().toString());\n" +
+ " };\n" +
+ "}");
+ }
+
+ void runTest(String aJava, String bJava) throws Exception {
+ try (JavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)) {
+ ToolBox tb = new ToolBox();
+ ToolBox.MemoryFileManager memoryFM1 = new ToolBox.MemoryFileManager(fm);
+ tb.new JavacTask().fileManager(memoryFM1)
+ .sources(aJava, bJava)
+ .run();
+ ToolBox.MemoryFileManager memoryFM2 = new ToolBox.MemoryFileManager(fm);
+ tb.new JavacTask().fileManager(memoryFM2)
+ .sources(bJava, aJava)
+ .run();
+
+ Assert.check(Arrays.equals(memoryFM1.getFileBytes(StandardLocation.CLASS_OUTPUT, "B"),
+ memoryFM2.getFileBytes(StandardLocation.CLASS_OUTPUT, "B")));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadInstanceMethodInUnboundLookup.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.misc.bad.instance.method.in.unbound.lookup
+// key: compiler.misc.invalid.mref
+// key: compiler.err.prob.found.req
+
+class BadInstanceMethodInUnboundLookup {
+
+ interface SAM {
+ void m(Integer u);
+ }
+
+ void f(Integer i) { }
+
+ static void test() {
+ SAM s = BadInstanceMethodInUnboundLookup::f;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadStaticMethodInBoundLookup.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.misc.invalid.mref
+// key: compiler.misc.bad.static.method.in.bound.lookup
+// key: compiler.err.prob.found.req
+
+class BadStaticMethodInBoundLookup {
+
+ Runnable r = new BadStaticMethodInBoundLookup()::m;
+
+ static void m() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadStaticMethodInUnboundLookup.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.misc.invalid.mref
+// key: compiler.misc.bad.static.method.in.unbound.lookup
+// key: compiler.err.prob.found.req
+
+class BadStaticMethodInUnboundLookup {
+
+ interface SAM {
+ void m(BadStaticMethodInUnboundLookup m);
+ }
+
+ SAM s = BadStaticMethodInUnboundLookup::m;
+
+ static void m() { }
+}
--- a/langtools/test/tools/javac/diags/examples/NonStaticCantBeRefFragment.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.misc.non-static.cant.be.ref
-// key: compiler.err.invalid.mref
-
-class NonStaticCantBeRefFragment {
-
- interface SAM {
- void m(Integer u);
- }
-
- void f(Integer i) { }
-
- static void test() {
- SAM s = NonStaticCantBeRefFragment::f;
- }
-}
--- a/langtools/test/tools/javac/diags/examples/StaticBoundMref.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.mref
-// key: compiler.misc.static.bound.mref
-
-class StaticBoundMref {
-
- Runnable r = new StaticBoundMref()::m;
-
- static void m() { }
-}
--- a/langtools/test/tools/javac/diags/examples/StaticMethodInUnboundLookup.java Wed Jan 28 17:48:59 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-// key: compiler.err.invalid.mref
-// key: compiler.misc.static.method.in.unbound.lookup
-
-class StaticBoundMref {
-
- interface SAM {
- void m(StaticBoundMref m);
- }
-
- SAM s = StaticBoundMref::m;
-
- static void m() { }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/LowerBoundBottomTypeTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8062358
+ * @summary ClassCastException in TransTypes.visitApply
+ * @compile LowerBoundBottomTypeTest.java
+*/
+
+public class LowerBoundBottomTypeTest {
+ void g() {
+ f().getInIntf3().getInIntf2().getInIntf1().getA();
+ }
+ interface IntfA {
+ int getA();
+ }
+
+ interface Intf1<A extends IntfA> {
+ A getInIntf1();
+ }
+
+ interface Intf2<B> {
+ Intf1<? extends B> getInIntf2();
+ }
+
+ interface Intf3<C> {
+ Intf2<? extends C> getInIntf3();
+ }
+
+ Intf3<?> f() {
+ return null;
+ }
+}
--- a/langtools/test/tools/javac/lambda/LambdaLambdaSerialized.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/lambda/LambdaLambdaSerialized.java Thu Jan 29 03:54:45 2015 +0000
@@ -67,13 +67,13 @@
out.writeObject(lamb);
}
- static void readAssert(ObjectInputStream in, String expected) throws IOException, ClassNotFoundException {
- LSI<LSI<Map>> ls = (LSI<LSI<Map>>) in.readObject();
+ static void readAssert(ObjectInputStream in, String expected) throws IOException, ClassNotFoundException {
+ LSI<LSI<Map>> ls = (LSI<LSI<Map>>)in.readObject();
Map result = ls.get().get();
System.out.printf("Result: %s\n", result);
}
+
+ interface LSI<T> extends Serializable {
+ T get();
+ }
}
-
-interface LSI<T> extends Serializable {
- T get();
-}
--- a/langtools/test/tools/javac/lambda/MethodReference22.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference22.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,9 +1,9 @@
-MethodReference22.java:40:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String))
-MethodReference22.java:41:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @999, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref))
-MethodReference22.java:46:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
-MethodReference22.java:47:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @1270, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref))
-MethodReference22.java:55:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m3(MethodReference22,java.lang.String))
-MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1574, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref))
+MethodReference22.java:40:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m1(java.lang.String)))
+MethodReference22.java:41:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @999, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m1(java.lang.String)))
+MethodReference22.java:46:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m4(java.lang.String)))
+MethodReference22.java:47:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @1270, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m4(java.lang.String)))
+MethodReference22.java:55:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22))
+MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1574, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m3(MethodReference22,java.lang.String)))
MethodReference22.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))
MethodReference22.java:58:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1667, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)))
MethodReference22.java:63:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
--- a/langtools/test/tools/javac/lambda/MethodReference28.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference28.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,7 +1,7 @@
MethodReference28.java:31:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m2, java.lang.Integer,java.lang.Integer, int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch)))
MethodReference28.java:32:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m3, java.lang.String, int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
MethodReference28.java:33:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m4, java.lang.String[], int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: int, java.lang.String))))
-MethodReference28.java:37:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.Integer))
+MethodReference28.java:37:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m1(java.lang.Integer)))
MethodReference28.java:38:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m2, java.lang.Integer,java.lang.Integer, int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch)))
MethodReference28.java:39:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m3, java.lang.String, int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
MethodReference28.java:40:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m4, java.lang.String[], int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: int, java.lang.String))))
--- a/langtools/test/tools/javac/lambda/MethodReference51.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference51.out Thu Jan 29 03:54:45 2015 +0000
@@ -2,6 +2,6 @@
MethodReference51.java:40:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, f, java.lang.String, int, kindname.class, MethodReference51, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
MethodReference51.java:41:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, g, int,{(compiler.misc.inapplicable.method: kindname.method, MethodReference51, g(java.lang.Integer,java.lang.Number), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, MethodReference51, g(java.lang.Number,java.lang.Integer), (compiler.misc.arg.length.mismatch))}))
MethodReference51.java:42:32: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: g, kindname.method, g(java.lang.Integer,java.lang.Number), MethodReference51, kindname.method, g(java.lang.Number,java.lang.Integer), MethodReference51))
-MethodReference51.java:43:21: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, h(int))
+MethodReference51.java:43:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, h(int)))
MethodReference51.java:44:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.not.def.access.class.intf.cant.access: j(int), MethodReference51.Foo))
6 errors
--- a/langtools/test/tools/javac/lambda/MethodReference55.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference55.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,3 +1,3 @@
-MethodReference55.java:36:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.bound.mref)
-MethodReference55.java:39:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.bound.mref)
+MethodReference55.java:36:11: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.bound.lookup: kindname.method, m(java.lang.Object)))
+MethodReference55.java:39:9: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference55.V, @1384, kindname.class, MethodReference55<X>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.bound.lookup: kindname.method, m(java.lang.Object))))
2 errors
--- a/langtools/test/tools/javac/lambda/MethodReference68.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference68.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,3 +1,2 @@
MethodReference68.java:21:10: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference68.F<Z>,Z[], @493,int, kindname.class, MethodReference68, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, MethodReference68.Foo,java.lang.Object)
-MethodReference68.java:21:12: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, getName())
-2 errors
+1 error
--- a/langtools/test/tools/javac/lambda/MethodReference73.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/lambda/MethodReference73.out Thu Jan 29 03:54:45 2015 +0000
@@ -2,12 +2,12 @@
MethodReference73.java:90:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference73,java.lang.String), MethodReference73, kindname.method, m2(java.lang.String), MethodReference73))
MethodReference73.java:91:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference73,java.lang.String), MethodReference73, kindname.method, m3(java.lang.String), MethodReference73))
MethodReference73.java:92:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference73,java.lang.String), MethodReference73, kindname.method, m4(java.lang.String), MethodReference73))
-MethodReference73.java:100:18: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m9(MethodReference73,java.lang.String))
-MethodReference73.java:101:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m10(MethodReference73,java.lang.String))
-MethodReference73.java:102:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m11(java.lang.String))
-MethodReference73.java:103:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m12(java.lang.String))
-MethodReference73.java:104:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m13(MethodReference73,java.lang.String))
-MethodReference73.java:105:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m14(java.lang.String))
-MethodReference73.java:106:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m15(MethodReference73,java.lang.String))
+MethodReference73.java:100:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m9, kindname.method, m9(MethodReference73,java.lang.String), MethodReference73, kindname.method, m9(java.lang.String), MethodReference73))
+MethodReference73.java:101:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m10(MethodReference73,java.lang.String)))
+MethodReference73.java:102:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m11, kindname.method, m11(MethodReference73,java.lang.String), MethodReference73, kindname.method, m11(java.lang.String), MethodReference73))
+MethodReference73.java:103:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.unbound.lookup: kindname.method, m12(java.lang.String)))
+MethodReference73.java:104:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, m13(MethodReference73,java.lang.String)))
+MethodReference73.java:105:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.static.method.in.unbound.lookup: kindname.method, m14(java.lang.String)))
+MethodReference73.java:106:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m15, kindname.method, m15(MethodReference73,java.lang.String), MethodReference73, kindname.method, m15(java.lang.String), MethodReference73))
MethodReference73.java:108:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, m16, MethodReference73,java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, MethodReference73, m16(MethodReference73,java.lang.String,int), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, MethodReference73, m16(java.lang.String,int), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: MethodReference73, java.lang.String)))}))
12 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReferenceGenericTarget.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,107 @@
+/*
+ * 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 8046977 8065303
+ * @summary ClassCastException: typing information needed for method reference bridging not preserved
+ * @author Srikanth
+ * @run main MethodReferenceGenericTarget
+ */
+
+public class MethodReferenceGenericTarget {
+ static String result = "";
+
+ interface ISi { int m(Short a); }
+
+ public static void main(String[] args) {
+ (new MethodReferenceGenericTarget()).testUnboxObjectToNumberWiden();
+ if (!result.equals("7775"))
+ throw new AssertionError("Incorrect result");
+ MethodReferenceTestPrivateTypeConversion.main(null);
+ new InferenceHookTest().test();
+ }
+
+ void foo(ISi q) {
+ result += q.m((short)75);
+ }
+
+ public void testUnboxObjectToNumberWiden() {
+ ISi q = (new E<Short>())::xI;
+ result += q.m((short)77);
+ // Verify poly invocation context to confirm we handle
+ // deferred/speculative attribution paths adequately.
+ foo((new E<Short>())::xI);
+ }
+
+ class E<T> {
+ private T xI(T t) { return t; }
+ }
+}
+
+// snippet from https://bugs.openjdk.java.net/browse/JDK-8065303
+class MethodReferenceTestPrivateTypeConversion {
+
+ class MethodReferenceTestTypeConversion_E<T> {
+ private T xI(T t) { return t; }
+ }
+
+ interface ISi { int m(Short a); }
+
+ interface ICc { char m(Character a); }
+
+ public void testUnboxObjectToNumberWiden() {
+ ISi q = (new MethodReferenceTestTypeConversion_E<Short>())::xI;
+ if ((q.m((short)77) != (short)77))
+ throw new AssertionError("Incorrect result");
+ }
+
+ public void testUnboxObjectToChar() {
+ ICc q = (new MethodReferenceTestTypeConversion_E<Character>())::xI;
+ if (q.m('@') != '@')
+ throw new AssertionError("Incorrect result");
+ }
+
+ public static void main(String[] args) {
+ new MethodReferenceTestPrivateTypeConversion().testUnboxObjectToNumberWiden();
+ new MethodReferenceTestPrivateTypeConversion().testUnboxObjectToChar();
+ }
+}
+
+class InferenceHookTestBase {
+ <X> X m(Integer i) { return null; }
+}
+
+class InferenceHookTest extends InferenceHookTestBase {
+ interface SAM1<R> {
+ R m(Integer i);
+ }
+
+ <Z> Z g(SAM1<Z> o) { return null; }
+
+ void test() {
+ String s = g(super::m);
+ if (s != null)
+ throw new AssertionError("Incorrect result");
+ }
+}
--- a/langtools/test/tools/javac/lambda/SerializedLambdaInInit.java Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/lambda/SerializedLambdaInInit.java Thu Jan 29 03:54:45 2015 +0000
@@ -111,8 +111,8 @@
}
}
}
+
+ interface LSI extends Serializable {
+ String convert(String x);
+ }
}
-
-interface LSI extends Serializable {
- String convert(String x);
-}
--- a/langtools/test/tools/javac/lambda/TargetType60.out Wed Jan 28 17:48:59 2015 +0100
+++ b/langtools/test/tools/javac/lambda/TargetType60.out Thu Jan 29 03:54:45 2015 +0000
@@ -1,6 +1,6 @@
TargetType60.java:54:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam0), TargetType60, kindname.method, <U>g(TargetType60.Sam1<U>), TargetType60
TargetType60.java:55:21: compiler.err.ref.ambiguous: g, kindname.method, <U>g(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>g(TargetType60.Sam2<U,java.lang.String>), TargetType60
-TargetType60.java:61:27: compiler.err.cant.apply.symbols: kindname.method, u, @1639,{(compiler.misc.inapplicable.method: kindname.method, TargetType60, <U>u(TargetType60.Sam1<U>), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, n2, TargetType60,java.lang.String, U, kindname.class, TargetType60, (compiler.misc.arg.length.mismatch))))),(compiler.misc.inapplicable.method: kindname.method, TargetType60, <U>u(TargetType60.Sam2<U,java.lang.String>), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, n2, , U,java.lang.String, (compiler.misc.location: kindname.class, TargetType60, null)))))}
+TargetType60.java:61:27: compiler.err.cant.apply.symbols: kindname.method, u, @1639,{(compiler.misc.inapplicable.method: kindname.method, TargetType60, <U>u(TargetType60.Sam1<U>), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, n2, TargetType60,java.lang.String, U, kindname.class, TargetType60, (compiler.misc.arg.length.mismatch))))),(compiler.misc.inapplicable.method: kindname.method, TargetType60, <U>u(TargetType60.Sam2<U,java.lang.String>), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.bad.instance.method.in.unbound.lookup: kindname.method, n2(TargetType60,java.lang.String)))))}
TargetType60.java:62:27: compiler.err.ref.ambiguous: u, kindname.method, <U>u(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>u(TargetType60.Sam2<U,java.lang.String>), TargetType60
TargetType60.java:63:27: compiler.err.ref.ambiguous: u, kindname.method, <U>u(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>u(TargetType60.Sam2<U,java.lang.String>), TargetType60
5 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferencePackagePrivateQualifier.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8068254
+ * @summary Method reference uses wrong qualifying type
+ * @author srikanth
+ * @run main MethodReferencePackagePrivateQualifier
+ */
+import pkg.B;
+public class MethodReferencePackagePrivateQualifier {
+ public static void main(String... args) {
+ pkg.B.m();
+ Runnable r = pkg.B::m;
+ r.run();
+ r = B::m;
+ r.run();
+ if (!pkg.B.result.equals("A.m()A.m()A.m()"))
+ throw new AssertionError("Incorrect result");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/pkg/B.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package pkg;
+class A {
+ public static void m() {
+ B.result += "A.m()";
+ }
+}
+
+public class B extends A {
+ public static String result = "";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/parser/extend/JavacExtensionTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.SourcePositions;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTaskImpl;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.util.Context;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.ToolProvider;
+import javax.tools.StandardJavaFileManager;
+import com.sun.source.tree.ImportTree;
+import java.util.Collections;
+import java.io.PrintWriter;
+import com.sun.source.tree.VariableTree;
+import static javax.tools.StandardLocation.CLASS_OUTPUT;
+
+/*
+ * @test
+ * @bug 8067384 8068488
+ * @summary Verify that JavacParser can be extended
+ */
+public class JavacExtensionTest {
+
+ public static void main(String[] args) throws Exception {
+ PrintWriter pw = new PrintWriter("trialSource.java", "UTF-8");
+ pw.println("int x = 9;");
+ pw.close();
+ List<? extends Tree> defs = parse("trialSource.java");
+ if (defs.size() != 1) {
+ throw new AssertionError("Expected only one def, got: " + defs.size());
+ }
+ Tree tree = defs.get(0);
+ if (tree instanceof VariableTree) {
+ System.out.println("Passes! --- " + tree);
+ } else {
+ throw new AssertionError("Expected VariableTree, got: " + tree);
+ }
+ }
+
+ static List<? extends Tree> parse(String srcfile) throws Exception {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
+ Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects(srcfile);
+ String classPath = System.getProperty("java.class.path");
+ List<String> options = Arrays.asList("-classpath", classPath);
+ DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
+ Context context = new Context();
+ JavacTaskImpl task = (JavacTaskImpl) ((JavacTool) compiler).getTask(null, null,
+ diagnostics, options, null, fileObjects, context);
+ TrialParserFactory.instance(context);
+ Iterable<? extends CompilationUnitTree> asts = task.parse();
+ Iterator<? extends CompilationUnitTree> it = asts.iterator();
+ if (it.hasNext()) {
+ CompilationUnitTree cut = it.next();
+ return cut.getTypeDecls();
+ } else {
+ throw new AssertionError("Expected compilation unit");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/parser/extend/TrialParser.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,253 @@
+/*
+ * 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.
+ */
+
+import com.sun.tools.javac.code.TypeTag;
+import com.sun.tools.javac.parser.JavacParser;
+import com.sun.tools.javac.parser.ParserFactory;
+import com.sun.tools.javac.parser.Tokens.Comment;
+import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
+import com.sun.tools.javac.parser.Tokens.Token;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.CLASS;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.COLON;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.ENUM;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.EOF;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.INTERFACE;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.LPAREN;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.MONKEYS_AT;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.PACKAGE;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.SEMI;
+import static com.sun.tools.javac.parser.Tokens.TokenKind.VOID;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
+import com.sun.tools.javac.tree.JCTree.JCModifiers;
+import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
+import com.sun.tools.javac.tree.JCTree.JCStatement;
+import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.JCTree.Tag;
+import static com.sun.tools.javac.tree.JCTree.Tag.IDENT;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Position;
+
+/**
+ *
+ * @author Robert Field
+ */
+class TrialParser extends JavacParser {
+
+ public TrialParser(ParserFactory fac,
+ com.sun.tools.javac.parser.Lexer S,
+ boolean keepDocComments,
+ boolean keepLineMap,
+ boolean keepEndPositions) {
+ super(fac, S, keepDocComments, keepLineMap, keepEndPositions);
+ }
+
+ @Override
+ public JCCompilationUnit parseCompilationUnit() {
+ Token firstToken = token;
+ JCModifiers mods = null;
+ boolean seenImport = false;
+ boolean seenPackage = false;
+ ListBuffer<JCTree> defs = new ListBuffer<>();
+ if (token.kind == MONKEYS_AT) {
+ mods = modifiersOpt();
+ }
+
+ if (token.kind == PACKAGE) {
+ int packagePos = token.pos;
+ List<JCAnnotation> annotations = List.nil();
+ seenPackage = true;
+ if (mods != null) {
+ checkNoMods(mods.flags);
+ annotations = mods.annotations;
+ mods = null;
+ }
+ nextToken();
+ JCExpression pid = qualident(false);
+ accept(SEMI);
+ JCPackageDecl pd = F.at(packagePos).PackageDecl(annotations, pid);
+ attach(pd, firstToken.comment(CommentStyle.JAVADOC));
+ storeEnd(pd, token.pos);
+ defs.append(pd);
+ }
+
+ boolean firstTypeDecl = true;
+ while (token.kind != EOF) {
+ if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
+ // error recovery
+ skip(true, false, false, false);
+ if (token.kind == EOF) {
+ break;
+ }
+ }
+ if (mods == null && token.kind == IMPORT) {
+ seenImport = true;
+ defs.append(importDeclaration());
+ break;
+ } else {
+ Comment docComment = token.comment(CommentStyle.JAVADOC);
+ if (firstTypeDecl && !seenImport && !seenPackage) {
+ docComment = firstToken.comment(CommentStyle.JAVADOC);
+ }
+ List<? extends JCTree> udefs = aUnit(mods, docComment);
+ for (JCTree def : udefs) {
+ defs.append(def);
+ }
+ mods = null;
+ firstTypeDecl = false;
+ break;
+ }
+ }
+ List<JCTree> rdefs = defs.toList();
+ class TrialUnit extends JCCompilationUnit {
+
+ public TrialUnit(List<JCTree> defs) {
+ super(defs);
+ }
+ }
+ JCCompilationUnit toplevel = new TrialUnit(rdefs);
+ if (rdefs.isEmpty()) {
+ storeEnd(toplevel, S.prevToken().endPos);
+ }
+ toplevel.lineMap = S.getLineMap();
+ this.endPosTable.setParser(null); // remove reference to parser
+ toplevel.endPositions = this.endPosTable;
+ return toplevel;
+ }
+
+ List<? extends JCTree> aUnit(JCModifiers pmods, Comment dc) {
+ switch (token.kind) {
+ case EOF:
+ return List.nil();
+ case RBRACE:
+ case CASE:
+ case DEFAULT:
+ // These are illegal, fall through to handle as illegal statement
+ case LBRACE:
+ case IF:
+ case FOR:
+ case WHILE:
+ case DO:
+ case TRY:
+ case SWITCH:
+ case SYNCHRONIZED:
+ case RETURN:
+ case THROW:
+ case BREAK:
+ case CONTINUE:
+ case SEMI:
+ case ELSE:
+ case FINALLY:
+ case CATCH:
+ case ASSERT:
+ return List.<JCTree>of(parseStatement());
+ default:
+ JCModifiers mods = modifiersOpt(pmods);
+ if (token.kind == CLASS
+ || token.kind == INTERFACE
+ || token.kind == ENUM) {
+ return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
+ } else {
+ int pos = token.pos;
+ List<JCTypeParameter> typarams = typeParametersOpt();
+ // if there are type parameters but no modifiers, save the start
+ // position of the method in the modifiers.
+ if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
+ mods.pos = pos;
+ storeEnd(mods, pos);
+ }
+ List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
+
+ if (annosAfterParams.nonEmpty()) {
+ checkAnnotationsAfterTypeParams(annosAfterParams.head.pos);
+ mods.annotations = mods.annotations.appendList(annosAfterParams);
+ if (mods.pos == Position.NOPOS) {
+ mods.pos = mods.annotations.head.pos;
+ }
+ }
+
+ Token prevToken = token;
+ pos = token.pos;
+ JCExpression t;
+ boolean isVoid = token.kind == VOID;
+ if (isVoid) {
+ t = to(F.at(pos).TypeIdent(TypeTag.VOID));
+ nextToken();
+ } else {
+ // return type of method, declared type of variable, or an expression
+ t = term(EXPR | TYPE);
+ }
+ if (token.kind == COLON && t.hasTag(IDENT)) {
+ // labelled statement
+ nextToken();
+ JCStatement stat = parseStatement();
+ return List.<JCTree>of(F.at(pos).Labelled(prevToken.name(), stat));
+ } else if ((isVoid || (lastmode & TYPE) != 0) && LAX_IDENTIFIER.accepts(token.kind)) {
+ // we have "Type Ident", so we can assume it is variable or method declaration
+ pos = token.pos;
+ Name name = ident();
+ if (token.kind == LPAREN) {
+ // method declaration
+ //mods.flags |= Flags.STATIC;
+ return List.of(methodDeclaratorRest(
+ pos, mods, t, name, typarams,
+ false, isVoid, dc));
+ } else if (!isVoid && typarams.isEmpty()) {
+ // variable declaration
+ //mods.flags |= Flags.STATIC;
+ List<JCTree> defs
+ = variableDeclaratorsRest(pos, mods, t, name, false, dc,
+ new ListBuffer<JCTree>()).toList();
+ accept(SEMI);
+ storeEnd(defs.last(), S.prevToken().endPos);
+ return defs;
+ } else {
+ // malformed declaration, return error
+ pos = token.pos;
+ List<JCTree> err = isVoid
+ ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, t, typarams,
+ List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
+ : null;
+ return List.<JCTree>of(syntaxError(token.pos, err, "expected", LPAREN));
+ }
+ } else if (!typarams.isEmpty()) {
+ // type parameters on non-variable non-method -- error
+ return List.<JCTree>of(syntaxError(token.pos, "illegal.start.of.type"));
+ } else {
+ // expression-statement or expression to evaluate
+ accept(SEMI);
+ JCExpressionStatement expr = toP(F.at(pos).Exec(t));
+ return List.<JCTree>of(expr);
+ }
+
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/parser/extend/TrialParserFactory.java Thu Jan 29 03:54:45 2015 +0000
@@ -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.
+ */
+
+import com.sun.tools.javac.parser.JavacParser;
+import com.sun.tools.javac.parser.ParserFactory;
+import com.sun.tools.javac.parser.ScannerFactory;
+import com.sun.tools.javac.util.Context;
+
+/**
+ *
+ * @author Robert Field
+ */
+class TrialParserFactory extends ParserFactory {
+
+ public static ParserFactory instance(Context context) {
+ ParserFactory instance = context.get(parserFactoryKey);
+ if (instance == null) {
+ instance = new TrialParserFactory(context);
+ }
+ return instance;
+ }
+
+ private final ScannerFactory scannerFactory;
+
+ protected TrialParserFactory(Context context) {
+ super(context);
+ this.scannerFactory = ScannerFactory.instance(context);
+ }
+
+ @Override
+ public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
+ com.sun.tools.javac.parser.Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
+ return new TrialParser(this, lexer, keepDocComments, keepLineMap, keepEndPos);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/TestMultipleErrors.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @bug 8066843
+ * @summary Annotation processors should be able to print multiple errors at the same location.
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor TestMultipleErrors
+ * @compile/fail/ref=TestMultipleErrors.out -XDrawDiagnostics -processor TestMultipleErrors TestMultipleErrors.java
+ */
+
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.element.*;
+import javax.tools.Diagnostic.Kind;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.Trees;
+
+public class TestMultipleErrors extends JavacTestingAbstractProcessor {
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ for (Element root : roundEnv.getRootElements()) {
+ processingEnv.getMessager().printMessage(Kind.ERROR, "error1", root);
+ processingEnv.getMessager().printMessage(Kind.ERROR, "error2", root);
+
+ Trees trees = Trees.instance(processingEnv);
+ TreePath path = trees.getPath(root);
+
+ trees.printMessage(Kind.ERROR, "error3", path.getLeaf(), path.getCompilationUnit());
+ trees.printMessage(Kind.ERROR, "error4", path.getLeaf(), path.getCompilationUnit());
+ }
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/TestMultipleErrors.out Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,5 @@
+TestMultipleErrors.java:41:8: compiler.err.proc.messager: error1
+TestMultipleErrors.java:41:8: compiler.err.proc.messager: error2
+TestMultipleErrors.java:41:8: compiler.err.proc.messager: error3
+TestMultipleErrors.java:41:8: compiler.err.proc.messager: error4
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/varargs/warning/Warn6.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,43 @@
+/*
+ * 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 8069254
+ * @summary Ensure the generic array creation warning is not incorrectly produced for diamonds
+ * @compile -Xlint:unchecked -Werror Warn6.java
+ */
+
+public class Warn6<T> {
+ @SafeVarargs
+ public Warn6(T... args) {
+ }
+
+ public static void main(String[] args) {
+ Iterable<String> i = null;
+
+ Warn6<Iterable<String>> foo2 = new Warn6<>(i, i);
+ Warn6<Iterable<String>> foo3 = new Warn6<Iterable<String>>(i, i);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T8069094.java Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,17 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 8069094
+ * @summary Verify that \\@SuppressWarnings("unchecked") works correctly for annotation default values
+ * @build VerifySuppressWarnings
+ * @compile/ref=T8069094.out -XDrawDiagnostics -Xlint:unchecked,deprecation,cast T8069094.java
+ * @run main VerifySuppressWarnings T8069094.java
+ */
+
+@interface T8069094 {
+ T8069094A foo() default T8069094A.Bar;
+}
+
+@Deprecated
+enum T8069094A {
+ Bar
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/suppress/T8069094.out Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,3 @@
+T8069094.java:11:5: compiler.warn.has.been.deprecated: T8069094A, compiler.misc.unnamed.package
+T8069094.java:11:29: compiler.warn.has.been.deprecated: T8069094A, compiler.misc.unnamed.package
+2 warnings
--- a/make/Images.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/make/Images.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -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)))
--- a/make/MakeHelpers.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/make/MakeHelpers.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/make/ModuleWrapper.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/make/ModuleWrapper.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -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.
--- a/make/common/JavaCompilation.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/make/common/JavaCompilation.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -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.
--- a/make/common/NativeCompilation.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/make/common/NativeCompilation.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- a/make/common/SetupJavaCompilers.gmk Wed Jan 28 17:48:59 2015 +0100
+++ b/make/common/SetupJavaCompilers.gmk Thu Jan 29 03:54:45 2015 +0000
@@ -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.
--- a/make/jprt.properties Wed Jan 28 17:48:59 2015 +0100
+++ b/make/jprt.properties Thu Jan 29 03:54:45 2015 +0000
@@ -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}, \
--- a/modules.xml Wed Jan 28 17:48:59 2015 +0100
+++ b/modules.xml Thu Jan 29 03:54:45 2015 +0000
@@ -737,7 +737,7 @@
</export>
<export>
<name>sun.awt</name>
- <to>oracle.accessbridge</to>
+ <to>jdk.accessbridge</to>
</export>
</module>
<module>
--- a/nashorn/.hgtags Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/.hgtags Thu Jan 29 03:54:45 2015 +0000
@@ -279,3 +279,5 @@
8ae8dff2a28f3b8831cce97ae0c7a957c5dc650a jdk9-b43
50ee576062726e536d1bb9a5eadd8fd4470128fc jdk9-b44
3c2bbeda038aef7061455fec604db7d8a342fac5 jdk9-b45
+2ecf0a617f0f9af1ffd278a0c70e76f1946ce773 jdk9-b46
+29046d42a95e5b9f105ab086a628bbd7f81c915d jdk9-b47
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java Thu Jan 29 03:54:45 2015 +0000
@@ -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(
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java Thu Jan 29 03:54:45 2015 +0000
@@ -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()) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/TypeUtilities.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/TypeUtilities.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptObjectMirror.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptObjectMirror.java Thu Jan 29 03:54:45 2015 +0000
@@ -340,9 +340,10 @@
@Override
public boolean containsKey(final Object key) {
+ checkKey(key);
return inGlobal(new Callable<Boolean>() {
@Override public Boolean call() {
- return sobj.containsKey(unwrap(key, global));
+ return sobj.containsKey(key);
}
});
}
@@ -376,6 +377,7 @@
@Override
public Object get(final Object key) {
+ checkKey(key);
return inGlobal(new Callable<Object>() {
@Override public Object call() {
return translateUndefined(wrap(sobj.get(key), global));
@@ -410,6 +412,7 @@
@Override
public Object put(final String key, final Object value) {
+ checkKey(key);
final ScriptObject oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
return inGlobal(new Callable<Object>() {
@@ -422,6 +425,9 @@
@Override
public void putAll(final Map<? extends String, ? extends Object> map) {
+ if (map == null) {
+ throw new NullPointerException("map is null");
+ }
final ScriptObject oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
inGlobal(new Callable<Object>() {
@@ -429,7 +435,9 @@
for (final Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
final Object value = entry.getValue();
final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
- sobj.set(entry.getKey(), unwrap(modValue, global), getCallSiteFlags());
+ final String key = entry.getKey();
+ checkKey(key);
+ sobj.set(key, unwrap(modValue, global), getCallSiteFlags());
}
return null;
}
@@ -438,9 +446,10 @@
@Override
public Object remove(final Object key) {
+ checkKey(key);
return inGlobal(new Callable<Object>() {
@Override public Object call() {
- return wrap(sobj.remove(unwrap(key, global), strict), global);
+ return wrap(sobj.remove(key, strict), global);
}
});
}
@@ -629,7 +638,7 @@
}
/**
- * Utilitity to convert this script object to the given type.
+ * Utility to convert this script object to the given type.
*
* @param <T> destination type to convert to
* @param type destination type to convert to
@@ -786,6 +795,24 @@
}
}
+ /**
+ * Ensures the key is not null, empty string, or a non-String object. The contract of the {@link Bindings}
+ * interface requires that these are not accepted as keys.
+ * @param key the key to check
+ * @throws NullPointerException if key is null
+ * @throws ClassCastException if key is not a String
+ * @throws IllegalArgumentException if key is empty string
+ */
+ private static void checkKey(final Object key) {
+ if (key == null) {
+ throw new NullPointerException("key can not be null");
+ } else if (!(key instanceof String)) {
+ throw new ClassCastException("key should be a String. It is " + key.getClass().getName() + " instead.");
+ } else if (((String)key).length() == 0) {
+ throw new IllegalArgumentException("key can not be empty");
+ }
+ }
+
@Override
public double toNumber() {
return inGlobal(new Callable<Double>() {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java Thu Jan 29 03:54:45 2015 +0000
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.runtime.arrays;
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Array;
@@ -761,39 +762,6 @@
}
/**
- * Push an array of items to the end of the array
- *
- * @param strict are we in strict mode
- * @param item the item
- * @return new array data (or same)
- */
- public ArrayData push(final boolean strict, final double item) {
- return push(strict, item);
- }
-
- /**
- * Push an array of items to the end of the array
- *
- * @param strict are we in strict mode
- * @param item the item
- * @return new array data (or same)
- */
- public ArrayData push(final boolean strict, final long item) {
- return push(strict, item);
- }
-
- /**
- * Push an array of items to the end of the array
- *
- * @param strict are we in strict mode
- * @param item the item
- * @return new array data (or same)
- */
- public ArrayData push(final boolean strict, final int item) {
- return push(strict, item);
- }
-
- /**
* Pop an element from the end of the array
*
* @return the popped element
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Thu Jan 29 03:54:45 2015 +0000
@@ -26,6 +26,7 @@
package jdk.nashorn.internal.runtime.arrays;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
@@ -343,17 +344,6 @@
}
@Override
- public final ArrayData push(final boolean strict, final int item) {
- final long len = length();
- final ArrayData newData = ensure(len);
- if (newData == this) {
- array[(int)len] = item;
- return this;
- }
- return newData.set((int)len, item, strict);
- }
-
- @Override
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
final long oldLength = length();
final long newLength = oldLength - removed + added;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Thu Jan 29 03:54:45 2015 +0000
@@ -27,6 +27,7 @@
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
import static jdk.nashorn.internal.lookup.Lookup.MH;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
@@ -303,17 +304,6 @@
}
@Override
- public final ArrayData push(final boolean strict, final long item) {
- final long len = length();
- final ArrayData newData = ensure(len);
- if (newData == this) {
- array[(int)len] = item;
- return this;
- }
- return newData.set((int)len, item, strict);
- }
-
- @Override
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
final long oldLength = length();
final long newLength = oldLength - removed + added;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Thu Jan 29 03:54:45 2015 +0000
@@ -28,6 +28,7 @@
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
@@ -277,17 +278,6 @@
}
@Override
- public final ArrayData push(final boolean strict, final double item) {
- final long len = length();
- final ArrayData newData = ensure(len);
- if (newData == this) {
- array[(int)len] = item;
- return this;
- }
- return newData.set((int)len, item, strict);
- }
-
- @Override
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
final long oldLength = length();
final long newLength = oldLength - removed + added;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Thu Jan 29 03:54:45 2015 +0000
@@ -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;
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Method> FUNCTIONAL_IFACE_METHOD = new ClassValue<Method>() {
+ @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;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Thu Jan 29 03:54:45 2015 +0000
@@ -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<Method> FUNCTIONAL_IFACE_METHOD = new ClassValue<Method>() {
- @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);
- }
}
--- a/nashorn/test/script/basic/JDK-8020324.js.EXPECTED Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/test/script/basic/JDK-8020324.js.EXPECTED Thu Jan 29 03:54:45 2015 +0000
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8068573.js Thu Jan 29 03:54:45 2015 +0000
@@ -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]);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8068985.js Thu Jan 29 03:54:45 2015 +0000
@@ -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);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8068985.js.EXPECTED Thu Jan 29 03:54:45 2015 +0000
@@ -0,0 +1,10 @@
+[object global]
+[object global]
+34.23
+hello
+false
+[object global]
+[object Object]
+foo
+[]
+{foo=bar}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8069002.js Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+}
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Jan 28 17:48:59 2015 +0100
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Thu Jan 29 03:54:45 2015 +0000
@@ -30,12 +30,18 @@
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.Collections;
import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.Invocable;
@@ -680,6 +686,163 @@
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<String, String>() {
+ @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<Object>() {
+ @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());
+ }
+
+ // @bug JDK-8068603: NashornScriptEngine.put/get() impls don't conform to NPE, IAE spec assertions
+ @Test
+ public void illegalBindingsValuesTest() throws Exception {
+ final ScriptEngineManager manager = new ScriptEngineManager();
+ final ScriptEngine e = manager.getEngineByName("nashorn");
+
+ try {
+ e.put(null, "null-value");
+ fail();
+ } catch (NullPointerException x) {
+ // expected
+ }
+
+ try {
+ e.put("", "empty-value");
+ fail();
+ } catch (IllegalArgumentException x) {
+ // expected
+ }
+
+ final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
+ assertTrue(b instanceof ScriptObjectMirror);
+
+ try {
+ b.put(null, "null-value");
+ fail();
+ } catch (NullPointerException x) {
+ // expected
+ }
+
+ try {
+ b.put("", "empty-value");
+ fail();
+ } catch (IllegalArgumentException x) {
+ // expected
+ }
+
+ try {
+ b.get(null);
+ fail();
+ } catch (NullPointerException x) {
+ // expected
+ }
+
+ try {
+ b.get("");
+ fail();
+ } catch (IllegalArgumentException x) {
+ // expected
+ }
+
+ try {
+ b.get(1);
+ fail();
+ } catch (ClassCastException x) {
+ // expected
+ }
+
+ try {
+ b.remove(null);
+ fail();
+ } catch (NullPointerException x) {
+ // expected
+ }
+
+ try {
+ b.remove("");
+ fail();
+ } catch (IllegalArgumentException x) {
+ // expected
+ }
+
+ try {
+ b.remove(1);
+ fail();
+ } catch (ClassCastException x) {
+ // expected
+ }
+
+ try {
+ b.containsKey(null);
+ fail();
+ } catch (NullPointerException x) {
+ // expected
+ }
+
+ try {
+ b.containsKey("");
+ fail();
+ } catch (IllegalArgumentException x) {
+ // expected
+ }
+
+ try {
+ b.containsKey(1);
+ fail();
+ } catch (ClassCastException x) {
+ // expected
+ }
+
+ try {
+ b.putAll(null);
+ fail();
+ } catch (NullPointerException x) {
+ // expected
+ }
+
+ try {
+ b.putAll(Collections.singletonMap((String)null, "null-value"));
+ fail();
+ } catch (NullPointerException x) {
+ // expected
+ }
+
+ try {
+ b.putAll(Collections.singletonMap("", "empty-value"));
+ fail();
+ } catch (IllegalArgumentException x) {
+ // expected
+ }
+ }
+
private static void checkProperty(final ScriptEngine e, final String name)
throws ScriptException {
final String value = System.getProperty(name);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/test/models/OverloadedSetter.java Thu Jan 29 03:54:45 2015 +0000
@@ -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";
+ }
+}
--- a/test/lib/sun/hotspot/WhiteBox.java Wed Jan 28 17:48:59 2015 +0100
+++ b/test/lib/sun/hotspot/WhiteBox.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
--- a/test/lib/sun/hotspot/code/BlobType.java Wed Jan 28 17:48:59 2015 +0100
+++ b/test/lib/sun/hotspot/code/BlobType.java Thu Jan 29 03:54:45 2015 +0000
@@ -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);
+ }
}