7125442: jar application located in two bytes character named folder cannot be run with JRE 7 u1/u2
authorksrini
Wed, 11 Jan 2012 08:14:47 -0800
changeset 11520 1c485b79de81
parent 11519 4cc0b4da6c36
child 11521 d7698e6c5f51
7125442: jar application located in two bytes character named folder cannot be run with JRE 7 u1/u2 Reviewed-by: sherman, mchung, darcy
jdk/src/share/bin/java.c
jdk/test/tools/launcher/I18NJarTest.java
jdk/test/tools/launcher/TestHelper.java
--- a/jdk/src/share/bin/java.c	Wed Jan 11 13:07:15 2012 +0000
+++ b/jdk/src/share/bin/java.c	Wed Jan 11 08:14:47 2012 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -1225,14 +1225,7 @@
                 "checkAndLoadMain",
                 "(ZILjava/lang/String;)Ljava/lang/Class;"));
 
-    switch (mode) {
-        case LM_CLASS:
-            str = NewPlatformString(env, name);
-            break;
-        default:
-            str = (*env)->NewStringUTF(env, name);
-            break;
-    }
+    str = NewPlatformString(env, name);
     result = (*env)->CallStaticObjectMethod(env, cls, mid, USE_STDERR, mode, str);
 
     if (JLI_IsTraceLauncher()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/I18NJarTest.java	Wed Jan 11 08:14:47 2012 -0800
@@ -0,0 +1,110 @@
+/*
+ * 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 7125442
+ * @summary ensures a jar path as well as a class located in a path containing
+ *          unicode characters are launched.
+ * @compile -XDignore.symbol.file I18NJarTest.java TestHelper.java
+ * @run main/othervm I18NJarTest
+ */
+import java.io.File;
+import java.util.Locale;
+
+/*
+ * Note 1: the system must have the correct Locale, in order for the test to
+ * work correctly, on those systems that do not comply, the test will succeed.
+ * Here are some guidelines to set the locale correctly.
+ * On Windows: ControlPanel->Regional Settings,
+ *             ensure that "Japanese" is selected and checked, and in
+ *             "Code page conversion tables", the following must be checked,
+ *             932 (ANSI/OEM - Japanese Shift-JIS).
+ * On Unix: use "locale -a" verify one of these exist ja_JP.UTF-8 or
+ *          ja_JP.utf8 or ja_JP.ujis, and export one of them with LC_ALL.
+ *
+ *
+ * Note 2: since we need to set the locale, it is safest to execute this test
+ * in its own VM (othervm mode), such that the ensuing tests can run unperturbed,
+ * regardless of the outcome.
+ */
+public class I18NJarTest {
+    private static final File cwd = new File(".");
+    private static final File dir = new File("\uFF66\uFF67\uFF68\uFF69");
+    private static final String encoding = System.getProperty("sun.jnu.encoding", "");
+
+    public static void main(String... args) throws Exception {
+        boolean localeAvailable = false;
+        for (Locale l : Locale.getAvailableLocales()) {
+            if (l.toLanguageTag().equals(Locale.JAPAN.toLanguageTag())) {
+                localeAvailable = true;
+                break;
+            }
+        }
+        if (!localeAvailable) {
+            System.out.println("Warning: locale: " + Locale.JAPAN
+                    + " not found, test passes vacuosly");
+            return;
+        }
+        if (encoding.equals("MS932") || encoding.equals("UTF-8")) {
+            Locale.setDefault(Locale.JAPAN);
+            System.out.println("using locale " + Locale.JAPAN +
+                    ", encoding " + encoding);
+        } else {
+            System.out.println("Warning: current encoding is " + encoding +
+                    "this test requires MS932 <Ja> or UTF-8," +
+                    " test passes vacuosly");
+            return;
+        }
+        dir.mkdir();
+        File dirfile = new File(dir, "foo.jar");
+        TestHelper.createJar(dirfile,
+                "public static void main(String... args) {",
+                "System.out.println(\"Hello World\");",
+                "System.exit(0);",
+                "}");
+
+        // remove the class files, to ensure that the class is indeed picked up
+        // from the jar file and not from ambient classpath.
+        File[] classFiles = cwd.listFiles(TestHelper.createFilter(TestHelper.CLASS_FILE_EXT));
+        for (File f : classFiles) {
+            f.delete();
+        }
+
+        // test with a jar file
+        TestHelper.TestResult tr = TestHelper.doExec(TestHelper.javaCmd,
+                "-jar", dirfile.getAbsolutePath());
+        System.out.println(tr);
+        if (!tr.isOK()) {
+            throw new RuntimeException("TEST FAILED");
+        }
+
+        // test the same class but by specifying it as a classpath
+        tr = TestHelper.doExec(TestHelper.javaCmd, "-cp",
+                dirfile.getAbsolutePath(), "Foo");
+        System.out.println(tr);
+        if (!tr.isOK()) {
+            throw new RuntimeException("TEST FAILED");
+        }
+    }
+}
--- a/jdk/test/tools/launcher/TestHelper.java	Wed Jan 11 13:07:15 2012 +0000
+++ b/jdk/test/tools/launcher/TestHelper.java	Wed Jan 11 08:14:47 2012 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -21,23 +21,24 @@
  * questions.
  */
 
-import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.FileVisitResult;
-import java.nio.file.SimpleFileVisitor;
-import javax.tools.ToolProvider;
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileFilter;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintStream;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.nio.file.Files;
+import java.nio.file.FileVisitResult;
+import java.nio.file.SimpleFileVisitor;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
 
 import static java.nio.file.StandardCopyOption.*;
 
@@ -68,6 +69,10 @@
     static final boolean isDualMode = isSolaris;
     static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
 
+    static final String JAVA_FILE_EXT  = ".java";
+    static final String CLASS_FILE_EXT = ".class";
+    static final String JAR_FILE_EXT   = ".jar";
+
     static int testExitValue = 0;
 
     static {
@@ -303,6 +308,19 @@
         }
     }
 
+    static FileFilter createFilter(final String extension) {
+        return new FileFilter() {
+            @Override
+            public boolean accept(File pathname) {
+                String name = pathname.getName();
+                if (name.endsWith(extension)) {
+                    return true;
+                }
+                return false;
+            }
+        };
+    }
+
     /*
      * A class to encapsulate the test results and stuff, with some ease
      * of use methods to check the test results.