1 # @test MultipleJRE.sh 2 # @bug 4811102 4953711 4955505 4956301 4991229 4998210 5018605 6387069 6733959 3 # @build PrintVersion 4 # @build UglyPrintVersion 5 # @build ZipMeUp 6 # @run shell MultipleJRE.sh 7 # @summary Verify Multiple JRE version support 8 # @author Joseph E. Kowalski 9 10 # 11 # Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. 12 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13 # 14 # This code is free software; you can redistribute it and/or modify it 15 # under the terms of the GNU General Public License version 2 only, as 16 # published by the Free Software Foundation. 17 # 18 # This code is distributed in the hope that it will be useful, but WITHOUT 19 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21 # version 2 for more details (a copy is included in the LICENSE file that 22 # accompanied this code). 23 # 24 # You should have received a copy of the GNU General Public License version 25 # 2 along with this work; if not, write to the Free Software Foundation, 26 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 27 # 28 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 29 # or visit www.oracle.com if you need additional information or have any 30 # questions. 31 # 32 33 # Verify directory context variables are set 34 if [ "${TESTJAVA}" = "" ] 35 then 36 echo "TESTJAVA not set. Test cannot execute. Failed." 37 exit 1 38 fi 39 40 if [ "${COMPILEJAVA}" = "" ]; then 41 COMPILEJAVA="${TESTJAVA}" 42 fi 43 44 if [ "${TESTSRC}" = "" ] 45 then 46 echo "TESTSRC not set. Test cannot execute. Failed." 47 exit 1 48 fi 49 50 if [ "${TESTCLASSES}" = "" ] 51 then 52 echo "TESTCLASSES not set. Test cannot execute. Failed." 53 exit 1 54 fi 55 56 JAVAEXE="$TESTJAVA/bin/java ${TESTVMOPTS}" 57 JAVA="$TESTJAVA/bin/java ${TESTVMOPTS} -classpath $TESTCLASSES" 58 JAR="$COMPILEJAVA/bin/jar ${TESTTOOLVMOPTS}" 59 OS=`uname -s`; 60 61 # 62 # Tests whether we are on windows (true) or not. 63 # 64 IsWindows() { 65 case "$OS" in 66 Windows* | CYGWIN* ) 67 printf "true" 68 ;; 69 * ) 70 printf "false" 71 ;; 72 esac 73 } 74 75 # 76 # Shell routine to test for the proper rejection of syntactically incorrect 77 # version specifications. 78 # 79 TestSyntax() { 80 mess="`$JAVA -version:\"$1\" -version 2>&1`" 81 if [ $? -eq 0 ]; then 82 echo "Invalid version syntax $1 accepted" 83 exit 1 84 fi 85 prefix="`echo "$mess" | cut -d ' ' -f 1-3`" 86 if [ "$prefix" != "Error: Syntax error" ]; then 87 echo "Unexpected error message for invalid syntax $1" 88 exit 1 89 fi 90 } 91 92 # 93 # Just as the name says. We sprinkle these in the appropriate location 94 # in the test file system and they just say who they are pretending to be. 95 # 96 CreateMockVM() { 97 mkdir -p jdk/j2re$1/bin 98 echo "#!/bin/sh" > jdk/j2re$1/bin/java 99 echo "echo \"$1\"" >> jdk/j2re$1/bin/java 100 chmod +x jdk/j2re$1/bin/java 101 } 102 103 # 104 # Constructs the jar file needed by these tests. 105 # 106 CreateJar() { 107 mkdir -p META-INF 108 echo "Manifest-Version: 1.0" > META-INF/MANIFEST.MF 109 echo "Main-Class: PrintVersion" >> META-INF/MANIFEST.MF 110 if [ "$1" != "" ]; then 111 echo "JRE-Version: $1" >> META-INF/MANIFEST.MF 112 fi 113 cp $TESTCLASSES/PrintVersion.class . 114 $JAR $2cmf META-INF/MANIFEST.MF PrintVersion PrintVersion.class 115 } 116 117 # 118 # Constructs a jar file using zip. 119 # 120 CreateZippyJar() { 121 mkdir -p META-INF 122 echo "Manifest-Version: 1.0" > META-INF/MANIFEST.MF 123 echo "Main-Class: PrintVersion" >> META-INF/MANIFEST.MF 124 if [ "$1" != "" ]; then 125 echo "JRE-Version: $1" >> META-INF/MANIFEST.MF 126 fi 127 cp $TESTCLASSES/PrintVersion.class . 128 /usr/bin/zip $2 PrintVersion META-INF/MANIFEST.MF PrintVersion.class 129 } 130 131 # 132 # Constructs a jar file with a Main-Class attribute of greater than 133 # 80 characters to validate the continuation line processing. 134 # 135 # Make this just long enough to require two continuation lines. Longer 136 # paths take too much away from the restricted Windows maximum path length. 137 # Note: see the variable UGLYCLASS and its check for path length. 138 # 139 # Make sure that 5018605 remains fixed by including additional sections 140 # in the Manifest which contain the same names as those allowed in the 141 # main section. 142 # 143 PACKAGE=reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongpackagename 144 UGLYCLASS=$TESTCLASSES/$PACKAGE/UglyPrintVersion.class 145 CreateUglyJar() { 146 mkdir -p META-INF 147 echo "Manifest-Version: 1.0" > META-INF/MANIFEST.MF 148 echo "Main-Class: $PACKAGE.UglyPrintVersion" >> META-INF/MANIFEST.MF 149 if [ "$1" != "" ]; then 150 echo "JRE-Version: $1" >> META-INF/MANIFEST.MF 151 fi 152 echo "" >> META-INF/MANIFEST.MF 153 echo "Name: NotToBeFound.class" >> META-INF/MANIFEST.MF 154 echo "Main-Class: NotToBeFound" >> META-INF/MANIFEST.MF 155 mkdir -p $PACKAGE 156 cp $UGLYCLASS $PACKAGE 157 $JAR $2cmf META-INF/MANIFEST.MF PrintVersion \ 158 $PACKAGE/UglyPrintVersion.class 159 } 160 161 # 162 # Constructs a jar file with a fair number of "zip directory" entries and 163 # the MANIFEST.MF entry at or near the end of that directory to validate 164 # the ability to transverse that directory. 165 # 166 CreateFullJar() { 167 mkdir -p META-INF 168 echo "Manifest-Version: 1.0" > META-INF/MANIFEST.MF 169 echo "Main-Class: PrintVersion" >> META-INF/MANIFEST.MF 170 if [ "$1" != "" ]; then 171 echo "JRE-Version: $1" >> META-INF/MANIFEST.MF 172 fi 173 cp $TESTCLASSES/PrintVersion.class . 174 for i in 0 1 2 3 4 5 6 7 8 9 ; do 175 for j in 0 1 2 3 4 5 6 7 8 9 ; do 176 touch AfairlyLongNameEatsUpDirectorySpaceBetter$i$j 177 done 178 done 179 $JAR $2cMf PrintVersion PrintVersion.class AfairlyLong* 180 $JAR $2umf META-INF/MANIFEST.MF PrintVersion 181 rm -f AfairlyLong* 182 } 183 184 # 185 # Creates a jar file with the attributes which caused the failure 186 # described in 4991229. 187 # 188 # Generate a bunch of CENTAB entries, each of which is 64 bytes long 189 # which practically guarentees we will hit the appropriate power of 190 # two buffer (initially 1K). Note that due to the perversity of 191 # zip/jar files, the first entry gets extra stuff so it needs a 192 # shorter name to compensate. 193 # 194 CreateAlignedJar() { 195 mkdir -p META-INF 196 echo "Manifest-Version: 1.0" > META-INF/MANIFEST.MF 197 echo "Main-Class: PrintVersion" >> META-INF/MANIFEST.MF 198 if [ "$1" != "" ]; then 199 echo "JRE-Version: $1" >> META-INF/MANIFEST.MF 200 fi 201 cp $TESTCLASSES/PrintVersion.class . 202 touch 57BytesSpecial 203 for i in 0 1 2 3 4 5 6 7 8 9 ; do 204 for j in 0 1 2 3 4 5 6 7 8 9 ; do 205 touch 64BytesPerEntry-$i$j 206 done 207 done 208 $JAR $2cMf PrintVersion 57* 64* PrintVersion.class 209 $JAR $2umf META-INF/MANIFEST.MF PrintVersion 210 rm -f 57* 64* 211 } 212 213 # 214 # Adds comments to a jar/zip file. This serves two purposes: 215 # 216 # 1) Make sure zip file comments (both per file and per archive) are 217 # properly processed and ignored. 218 # 219 # 2) A long file comment creates a mondo "Central Directory" entry in 220 # the zip file. Such a "mondo" entry could also be due to a very 221 # long file name (path) or a long "Ext" entry, but adding the long 222 # comment is the easiest way. 223 # 224 CommentZipFile() { 225 file= 226 tail="is designed to take up space - lots and lots of space." 227 mv PrintVersion PrintVersion.zip 228 /usr/bin/zipnote PrintVersion.zip > zipout 229 while read ampersand line; do 230 if [ "$ampersand" = "@" ]; then 231 if [ "$line" = "(comment above this line)" ]; then 232 echo "File Comment Line." >> zipin 233 if [ "$file" = "$1" ]; then 234 for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do 235 for j in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do 236 echo "Mondo comment line $i$j $tail" >> zipin 237 done 238 done 239 fi 240 else 241 file=$line 242 fi 243 fi 244 echo "$ampersand $line" >> zipin 245 if [ "$ampersand" = "@" ]; then 246 if [ "$line" = "(zip file comment below this line)" ]; then 247 echo "Zip File Comment Line number 1" >> zipin 248 echo "Zip File Comment Line number 2" >> zipin 249 fi 250 fi 251 done < zipout 252 /usr/bin/zipnote -w PrintVersion.zip < zipin 253 mv PrintVersion.zip PrintVersion 254 rm zipout zipin 255 } 256 257 # 258 # Attempt to launch a vm using a version specifier and make sure the 259 # resultant launch (probably a "mock vm") is appropriate. 260 # 261 LaunchVM() { 262 if [ "$1" != "" ]; then 263 mess="`$JAVA -version:\"$1\" -jar PrintVersion 2>&1`" 264 else 265 mess="`$JAVA -jar PrintVersion 2>&1`" 266 fi 267 if [ $? -ne 0 ]; then 268 prefix=`echo "$mess" | cut -d ' ' -f 1-3` 269 if [ "$prefix" != "Unable to locate" ]; then 270 echo "$mess" 271 exit 1 272 fi 273 echo "Unexpected error in attempting to locate $1" 274 exit 1 275 fi 276 echo $mess | grep "$2" > /dev/null 2>&1 277 if [ $? != 0 ]; then 278 echo "Launched $mess, expected $2" 279 exit 1 280 fi 281 } 282 283 # Tests very long Main-Class attribute in the jar 284 TestLongMainClass() { 285 JVER=$1 286 if [ "$JVER" = "mklink" ]; then 287 JVER=XX 288 JDKXX=jdk/j2re$JVER 289 rm -rf jdk 290 mkdir jdk 291 ln -s $TESTJAVA $JDKXX 292 JAVA_VERSION_PATH="`pwd`/jdk" 293 export JAVA_VERSION_PATH 294 fi 295 $JAVAEXE -cp $TESTCLASSES ZipMeUp UglyBetty.jar 4097 296 message="`$JAVAEXE -version:$JVER -jar UglyBetty.jar 2>&1`" 297 echo $message | grep "Error: main-class: attribute exceeds system limits" > /dev/null 2>&1 298 if [ $? -ne 0 ]; then 299 printf "Long manifest test did not get expected error" 300 exit 1 301 fi 302 unset JAVA_VERSION_PATH 303 rm -rf jdk 304 } 305 306 # 307 # Main test sequence starts here 308 # 309 RELEASE=`$JAVA -version 2>&1 | head -n 1 | cut -d ' ' -f 3 | \ 310 sed -e "s/\"//g"` 311 BASE_RELEASE=`echo $RELEASE | sed -e "s/-.*//g"` 312 313 # 314 # Make sure that the generic jar/manifest reading code works. Test both 315 # compressed and "stored" jar files. 316 # 317 # The "Ugly" jar (long manifest line) tests are only run if the combination 318 # of the file name length restrictions and the length of the cwd allow it. 319 # 320 CreateJar "" "" 321 LaunchVM "" "${RELEASE}" 322 CreateJar "" "0" 323 LaunchVM "" "${RELEASE}" 324 if [ `IsWindows` = "true" ]; then 325 MAXIMUM_PATH=255; 326 else 327 MAXIMUM_PATH=1024; 328 fi 329 330 PATH_LENGTH=`printf "%s" "$UGLYCLASS" | wc -c` 331 if [ ${PATH_LENGTH} -lt ${MAXIMUM_PATH} ]; then 332 CreateUglyJar "" "" 333 LaunchVM "" "${RELEASE}" 334 CreateUglyJar "" "0" 335 LaunchVM "" "${RELEASE}" 336 else 337 printf "Warning: Skipped UglyJar test, path length exceeded, %d" $MAXIMUM_PATH 338 printf " allowed, the current path is %d\n" $PATH_LENGTH 339 fi 340 CreateAlignedJar "" "" 341 LaunchVM "" "${RELEASE}" 342 CreateFullJar "" "" 343 LaunchVM "" "${RELEASE}" 344 345 # 346 # 4998210 shows that some very strange behaviors are semi-supported. 347 # In this case, it's the ability to prepend any kind of stuff to the 348 # jar file and require that the jar file still work. Note that this 349 # "interface" isn't publically supported and we may choose to break 350 # it in the future, but this test guarantees that we won't break it 351 # without informed consent. We take advantage the fact that the 352 # "FullJar" we just tested is probably the best jar to begin with 353 # for this test. 354 # 355 echo "This is just meaningless bytes to prepend to the jar" > meaningless 356 mv PrintVersion meaningfull 357 cat meaningless meaningfull > PrintVersion 358 LaunchVM "" "${RELEASE}" 359 rm meaningless meaningfull 360 361 # 362 # Officially, one must use "the jar command to create a jar file. However, 363 # all the comments about jar commands **imply** that jar files and zip files 364 # are equivalent. (Note: this isn't true due to the "0xcafe" insertion.) 365 # On systems which have a command line zip, test the ability to use zip 366 # to construct a jar and then use it (6387069). 367 # 368 if [ -x /usr/bin/zip ]; then 369 CreateZippyJar "" "-q" 370 LaunchVM "" "${RELEASE}" 371 fi 372 373 # 374 # jar files shouldn't have comments, but it is possible that somebody added 375 # one by using zip -c, zip -z, zipnote or a similar utility. On systems 376 # that have "zipnote", verify this functionality. 377 # 378 # This serves a dual purpose of creating a very large "central directory 379 # entry" which validates to code to read such entries. 380 # 381 if [ -x /usr/bin/zipnote ]; then 382 CreateFullJar "" "" 383 CommentZipFile "AfairlyLongNameEatsUpDirectorySpaceBetter20" 384 LaunchVM "" "${RELEASE}" 385 fi 386 387 # 388 # Throw some syntactically challenged (illegal) version specifiers at 389 # the interface. Failure (of the launcher) is success for the test. 390 # 391 TestSyntax "1.2..3" # Two adjacent separators 392 TestSyntax "_1.2.3" # Begins with a separator 393 TestSyntax "1.2.3-" # Ends with a separator 394 TestSyntax "1.2+.3" # Embedded modifier 395 TestSyntax "1.2.4+&1.2*&1++" # Long and invalid 396 397 # On windows we see if there is another jre installed, usually 398 # there is, then we test using that, otherwise links are created 399 # to get through to SelectVersion. 400 if [ `IsWindows` = "false" ]; then 401 TestLongMainClass "mklink" 402 else 403 $JAVAEXE -version:1.0+ 404 if [ $? -eq 0 ]; then 405 TestLongMainClass "1.0+" 406 else 407 printf "Warning: TestLongMainClass skipped as there is no" 408 printf "viable MJRE installed.\n" 409 fi 410 fi 411 412 # 413 # Because scribbling in the registry can be rather destructive, only a 414 # subset of the tests are run on Windows. 415 # 416 if [ `IsWindows` = "true" ]; then 417 exit 0; 418 fi 419 420 # 421 # Additional version specifiers containing spaces. (Sigh, unable to 422 # figure out the glomming on Windows) 423 # 424 TestSyntax "1.2.3_99 1.3.2+ 1.2.4+&1.2*&1++" # Long and invalid 425 426 # 427 # Create a mock installation of a number of shell scripts named as though 428 # they were installed JREs. Then test to see if the launcher can cause 429 # the right shell scripts to be invoked. 430 # 431 # Note, that as a side effect, this test verifies that JAVA_VERSION_PATH 432 # works. 433 # 434 rm -rf jdk 435 JAVA_VERSION_PATH="`pwd`/jdk" 436 export JAVA_VERSION_PATH 437 438 CreateMockVM 1.10 439 CreateMockVM 1.11.3 440 CreateMockVM 1.11.3_03 441 CreateMockVM 1.11.4 442 CreateMockVM 1.12.3_03 443 CreateMockVM 1.12.3_03-lastweek 444 CreateMockVM 1.13.3_03 445 CreateMockVM 1.13.3_03-lastweek 446 CreateMockVM 1.13.3_03_lastweek 447 CreateMockVM 1.20.0 448 449 # 450 # Test extracting the version information from the jar file: 451 # 452 # Requested Expected 453 CreateJar "1.10+" "" 454 LaunchVM "" "1.20.0" 455 CreateJar "1.11.3_03+&1.11*" "" 456 LaunchVM "" "1.11.4" 457 CreateJar "1.12.3_03+&1.12.3*" "" 458 LaunchVM "" "1.12.3_03" 459 CreateJar "1.13.3_03+&1.13.3*" "" 460 LaunchVM "" "1.13.3_03_lastweek" # Strange but true 461 462 # 463 # Test obtaining the version information from the command line (and that 464 # it overrides the manifest). 465 # 466 CreateJar "${BASERELEASE}*" "" 467 LaunchVM "1.10+" "1.20.0" 468 LaunchVM "1.11.3_03+&1.11*" "1.11.4" 469 LaunchVM "1.12.3_03+&1.12.3*" "1.12.3_03" 470 LaunchVM "1.13.3_03+&1.13.3*" "1.13.3_03_lastweek" # Strange but true 471 472 [ -d jdk ] && rm -rf jdk 473 [ -d META_INF ] && rm -rf META_INF 474 475 exit 0