8181033: Confusing message: A JNI error has occurred, please check your installation and try again
authormchung
Thu, 25 May 2017 10:40:08 -0700
changeset 45339 f2ab1225d11f
parent 45338 f760c3a27d1c
child 45340 7f22bdef12f2
8181033: Confusing message: A JNI error has occurred, please check your installation and try again Reviewed-by: alanb, dholmes, ksrini
jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java
jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties
jdk/test/tools/launcher/MainClassCantBeLoadedTest.java
--- a/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Thu May 25 11:54:42 2017 +0100
+++ b/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Thu May 25 10:40:08 2017 -0700
@@ -568,7 +568,6 @@
         }
 
         validateMainClass(mainClass);
-
         return mainClass;
     }
 
@@ -619,7 +618,7 @@
             }
         } catch (LinkageError le) {
             abort(null, "java.launcher.module.error3", mainClass, m.getName(),
-                    le.getClass().getName() + ": " + le.getLocalizedMessage());
+                le.getClass().getName() + ": " + le.getLocalizedMessage());
         }
         if (c == null) {
             abort(null, "java.launcher.module.error2", mainClass, mainModule);
@@ -707,14 +706,22 @@
 
     // Check the existence and signature of main and abort if incorrect
     static void validateMainClass(Class<?> mainClass) {
-        Method mainMethod;
+        Method mainMethod = null;
         try {
             mainMethod = mainClass.getMethod("main", String[].class);
         } catch (NoSuchMethodException nsme) {
             // invalid main or not FX application, abort with an error
             abort(null, "java.launcher.cls.error4", mainClass.getName(),
                   JAVAFX_APPLICATION_CLASS_NAME);
-            return; // Avoid compiler issues
+        } catch (Throwable e) {
+            if (mainClass.getModule().isNamed()) {
+                abort(e, "java.launcher.module.error5",
+                      mainClass.getName(), mainClass.getModule(),
+                      e.getClass().getName(), e.getLocalizedMessage());
+            } else {
+                abort(e,"java.launcher.cls.error7", mainClass.getName(),
+                      e.getClass().getName(), e.getLocalizedMessage());
+            }
         }
 
         /*
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Thu May 25 11:54:42 2017 +0100
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Thu May 25 10:40:08 2017 -0700
@@ -208,6 +208,9 @@
 java.launcher.cls.error6=\
     Error: LinkageError occurred while loading main class {0}\n\
     \t{1}
+java.launcher.cls.error7=\
+     Error: Unable to initialize main class {0}\n\
+     Caused by: {1}: {2}
 java.launcher.jar.error1=\
     Error: An unexpected error occurred while trying to open file {0}
 java.launcher.jar.error2=manifest not found in {0}
@@ -222,7 +225,10 @@
 java.launcher.module.error2=\
     Error: Could not find or load main class {0} in module {1}
 java.launcher.module.error3=\
-    Error: Unable to load main class {0} from module {1}\n\
+    Error: Unable to load main class {0} in module {1}\n\
     \t{2}
 java.launcher.module.error4=\
     {0} not found
+java.launcher.module.error5=\
+    Error: Unable to initialize main class {0} in module {1}\n\
+    Caused by: {1}: {2}
--- a/jdk/test/tools/launcher/MainClassCantBeLoadedTest.java	Thu May 25 11:54:42 2017 +0100
+++ b/jdk/test/tools/launcher/MainClassCantBeLoadedTest.java	Thu May 25 10:40:08 2017 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8174694
+ * @bug 8174694 8181033
  * @summary improve error message shown when main class can't be loaded
  * @compile MainClassCantBeLoadedTest.java
  * @run main MainClassCantBeLoadedTest
@@ -85,6 +85,68 @@
             System.err.println(trExecution);
     }
 
+    @Test
+    void testFailToInitializeMainClass() throws Exception {
+        if (!isEnglishLocale()) {
+            return;
+        }
+
+        File cwd = new File(".");
+        File srcDir = new File(cwd, "src");
+        if (srcDir.exists()) {
+            recursiveDelete(srcDir);
+        }
+        srcDir.mkdirs();
+
+        /* we want to generate class C that will resolve additional class
+         */
+        ArrayList<String> scratchpad = new ArrayList<>();
+        scratchpad.add("public class C {");
+        scratchpad.add("    public static void main(String... args) {");
+        scratchpad.add("        try {");
+        scratchpad.add("            System.out.println(\"loading of restricted class\");");
+        scratchpad.add("        } catch (Exception e) {");
+        scratchpad.add("            java.security.Provider p = new com.sun.crypto.provider.SunJCE();");
+        scratchpad.add("            p.toString();");
+        scratchpad.add("        }");
+        scratchpad.add("    }");
+        scratchpad.add("}");
+        createFile(new File(srcDir, "C.java"), scratchpad);
+
+
+        // Compile and execute C should succeed
+        TestResult trCompilation = doExec(javacCmd,
+            "--add-exports", "java.base/com.sun.crypto.provider=ALL-UNNAMED",
+            "-d", "out",
+            new File(srcDir, "C.java").toString());
+        if (!trCompilation.isOK()) {
+            System.err.println(trCompilation);
+            throw new RuntimeException("Error: compiling");
+        }
+
+        TestResult trExecution = doExec(javaCmd,
+            "--add-exports", "java.base/com.sun.crypto.provider=ALL-UNNAMED",
+            "-cp", "out", "C");
+        if (!trExecution.isOK()) {
+            System.err.println(trExecution);
+            throw new RuntimeException("Error: executing");
+        }
+
+        // Execute C with security manager will fail with AccessControlException
+        trExecution = doExec(javaCmd,
+            "-Djava.security.manager",
+            "--add-exports", "java.base/com.sun.crypto.provider=ALL-UNNAMED",
+            "-cp", "out", "C");
+
+        // then this error message should be generated
+        trExecution.contains("Error: Unable to initialize main class C");
+        trExecution.contains("Caused by: java.security.AccessControlException: " +
+            "access denied (\"java.lang.RuntimePermission\"" +
+            " \"accessClassInPackage.com.sun.crypto.provider\")");
+        if (!trExecution.testStatus)
+            System.err.println(trExecution);
+    }
+
     public static void main(String[] args) throws Exception {
         MainClassCantBeLoadedTest a = new MainClassCantBeLoadedTest();
         a.run(args);