6356642: extcheck.exe -verbose throws ArrayIndexOutOfBoundsException exception
Summary: Fix causes printing of user-level error messages instead of throwing exceptions
Reviewed-by: sherman
--- a/jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java Mon Sep 08 13:44:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java Mon Sep 08 14:11:13 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -256,13 +256,13 @@
private boolean isNotOlderThan(String already,String target)
throws NumberFormatException
{
- if (already == null || already.length() < 1) {
+ if (already == null || already.length() < 1) {
throw new NumberFormatException("Empty version string");
}
- // Until it matches scan and compare numbers
- StringTokenizer dtok = new StringTokenizer(target, ".", true);
- StringTokenizer stok = new StringTokenizer(already, ".", true);
+ // Until it matches scan and compare numbers
+ StringTokenizer dtok = new StringTokenizer(target, ".", true);
+ StringTokenizer stok = new StringTokenizer(already, ".", true);
while (dtok.hasMoreTokens() || stok.hasMoreTokens()) {
int dver;
int sver;
@@ -276,19 +276,19 @@
} else
sver = 0;
- if (sver < dver)
- return false; // Known to be incompatible
- if (sver > dver)
- return true; // Known to be compatible
+ if (sver < dver)
+ return false; // Known to be incompatible
+ if (sver > dver)
+ return true; // Known to be compatible
- // Check for and absorb separators
- if (dtok.hasMoreTokens())
- dtok.nextToken();
- if (stok.hasMoreTokens())
- stok.nextToken();
- // Compare next component
- }
- // All components numerically equal
+ // Check for and absorb separators
+ if (dtok.hasMoreTokens())
+ dtok.nextToken();
+ if (stok.hasMoreTokens())
+ stok.nextToken();
+ // Compare next component
+ }
+ // All components numerically equal
return true;
}
@@ -307,11 +307,10 @@
}
/**
- * Print out the error message and exit from the program
+ * Throws a RuntimeException with a message describing the error.
*/
- static void error(String message){
- System.err.println(message);
- System.exit(-1);
+ static void error(String message) throws RuntimeException {
+ throw new RuntimeException(message);
}
@@ -356,19 +355,19 @@
}
private JarFile findJarFile(URL url) throws IOException {
- // Optimize case where url refers to a local jar file
- if ("file".equals(url.getProtocol())) {
- String path = url.getFile().replace('/', File.separatorChar);
- File file = new File(path);
- if (!file.exists()) {
- throw new FileNotFoundException(path);
- }
- return new JarFile(path);
- }
- URLConnection uc = getBaseURL().openConnection();
- //uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
- return ((JarURLConnection)uc).getJarFile();
- }
+ // Optimize case where url refers to a local jar file
+ if ("file".equals(url.getProtocol())) {
+ String path = url.getFile().replace('/', File.separatorChar);
+ File file = new File(path);
+ if (!file.exists()) {
+ throw new FileNotFoundException(path);
+ }
+ return new JarFile(path);
+ }
+ URLConnection uc = getBaseURL().openConnection();
+ //uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
+ return ((JarURLConnection)uc).getJarFile();
+ }
/*
--- a/jdk/src/share/classes/com/sun/tools/extcheck/Main.java Mon Sep 08 13:44:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/extcheck/Main.java Mon Sep 08 14:11:13 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
* 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,10 @@
*/
public final class Main {
-
+ public static final String INSUFFICIENT = "Insufficient number of arguments";
+ public static final String MISSING = "Missing <jar file> argument";
+ public static final String DOES_NOT_EXIST = "Jarfile does not exist: ";
+ public static final String EXTRA = "Extra command line argument: ";
/**
* Terminates with one of the following codes
@@ -40,26 +43,36 @@
* 0 No newer jar file was found
* -1 An internal error occurred
*/
- public static void main(String args[]){
+ public static void main(String args[]) {
+ try {
+ realMain(args);
+ } catch (Exception ex) {
+ System.err.println(ex.getMessage());
+ System.exit(-1);
+ }
+ }
- if (args.length < 1){
- System.err.println("Usage: extcheck [-verbose] <jar file>");
- System.exit(-1);
+ public static void realMain(String[] args) throws Exception {
+ if (args.length < 1) {
+ usage(INSUFFICIENT);
}
int argIndex = 0;
boolean verboseFlag = false;
- if (args[argIndex].equals("-verbose")){
+ if (args[argIndex].equals("-verbose")) {
verboseFlag = true;
argIndex++;
+ if (argIndex >= args.length) {
+ usage(MISSING);
+ }
}
String jarName = args[argIndex];
argIndex++;
File jarFile = new File(jarName);
if (!jarFile.exists()){
- ExtCheck.error("Jarfile " + jarName + " does not exist");
+ usage(DOES_NOT_EXIST + jarName);
}
if (argIndex < args.length) {
- ExtCheck.error("Extra command line argument :"+args[argIndex]);
+ usage(EXTRA + args[argIndex]);
}
ExtCheck jt = ExtCheck.create(jarFile,verboseFlag);
boolean result = jt.checkInstalledAgainstTarget();
@@ -68,7 +81,10 @@
} else {
System.exit(1);
}
-
}
+ private static void usage(String msg) throws Exception {
+ throw new Exception(msg + "\nUsage: extcheck [-verbose] <jar file>");
+ }
}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.java Mon Sep 08 14:11:13 2008 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6356642
+ * @summary Verify that extcheck exits appropriately when invalid args are given.
+ * @run shell TestExtcheckArgs.sh
+ * @author Dave Bristor
+ */
+
+import java.io.File;
+import com.sun.tools.extcheck.Main;
+
+/*
+ * Test extcheck by using Runtime.exec instead of invoking
+ * com.sun.tools.extcheck.Main.main, since the latter does its own
+ * System.exit under the conditions checked here.
+ */
+public class TestExtcheckArgs {
+ public static void realMain(String[] args) throws Throwable {
+ String testJar = System.getenv("TESTJAVA") + File.separator
+ + "lib" + File.separator + "jconsole.jar";
+
+ verify(new String[] {
+ }, Main.INSUFFICIENT);
+ verify(new String[] {
+ "-verbose"
+ }, Main.MISSING);
+ verify(new String[] {
+ "-verbose",
+ "foo"
+ }, Main.DOES_NOT_EXIST);
+ verify(new String[] {
+ testJar,
+ "bar"
+ }, Main.EXTRA);
+ verify(new String[] {
+ "-verbose",
+ testJar,
+ "bar"
+ }, Main.EXTRA);
+ }
+
+ static void verify(String[] args, String expected) throws Throwable {
+ try {
+ Main.realMain(args);
+ fail();
+ } catch (Exception ex) {
+ if (ex.getMessage().startsWith(expected)) {
+ pass();
+ } else {
+ fail("Unexpected message: " + ex.getMessage());
+ }
+ }
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static boolean pass() {passed++; return true;}
+ static boolean fail() {failed++; Thread.dumpStack(); return false;}
+ static boolean fail(String msg) {System.out.println(msg); return fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
+ static boolean equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) return pass();
+ else return fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.println("\nPassed = " + passed + " failed = " + failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.sh Mon Sep 08 14:11:13 2008 -0700
@@ -0,0 +1,47 @@
+#! /bin/sh
+
+#
+# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+if [ "x$TESTJAVA" = x ]; then
+ TESTJAVA=$1; shift
+ TESTCLASSES=.
+ TESTSRC=.
+fi
+export TESTJAVA
+
+case "`uname`" in Windows*|CYGWIN* ) PS=';';; *) PS=':';; esac
+
+${TESTJAVA}/bin/javac -d ${TESTCLASSES} -classpath ${TESTJAVA}/lib/tools.jar${PS}${TESTCLASSES} ${TESTSRC}/TestExtcheckArgs.java
+rc=$?
+if [ $rc != 0 ]; then
+ echo Compilation failure with exit status $rc
+ exit $rc
+fi
+
+${TESTJAVA}/bin/java -classpath ${TESTJAVA}/lib/tools.jar${PS}${TESTCLASSES} TestExtcheckArgs
+rc=$?
+if [ $rc != 0 ]; then
+ echo Execution failure with exit status $rc
+ exit $rc
+fi