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