6356642: extcheck.exe -verbose throws ArrayIndexOutOfBoundsException exception
authorbristor
Mon, 08 Sep 2008 14:11:13 -0700
changeset 1159 ef22d0ad63bf
parent 1158 34d64e750f8e
child 1160 fe006e99708a
child 1220 e79d3fdb2e73
6356642: extcheck.exe -verbose throws ArrayIndexOutOfBoundsException exception Summary: Fix causes printing of user-level error messages instead of throwing exceptions Reviewed-by: sherman
jdk/src/share/classes/com/sun/tools/extcheck/ExtCheck.java
jdk/src/share/classes/com/sun/tools/extcheck/Main.java
jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.java
jdk/test/com/sun/tools/extcheck/TestExtcheckArgs.sh
--- 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