8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
authorsundar
Wed, 10 Jul 2013 13:25:07 +0530
changeset 18862 8b6a01b38cb8
parent 18861 39748ee0cc9a
child 18863 f582e6cdeae5
8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false Reviewed-by: hannesw
nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java
nashorn/src/jdk/nashorn/internal/runtime/Context.java
nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java
--- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java	Tue Jul 09 15:56:59 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java	Wed Jul 10 13:25:07 2013 +0530
@@ -528,7 +528,7 @@
         return this.env;
     }
 
-    private static String safeSourceName(final Source source) {
+    private String safeSourceName(final Source source) {
         String baseName = new File(source.getName()).getName();
 
         final int index = baseName.lastIndexOf(".js");
@@ -537,6 +537,9 @@
         }
 
         baseName = baseName.replace('.', '_').replace('-', '_');
+        if (! env._loader_per_compile) {
+            baseName = baseName + installer.getUniqueScriptId();
+        }
         final String mangled = NameCodec.encode(baseName);
 
         return mangled != null ? mangled : baseName;
--- a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java	Tue Jul 09 15:56:59 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java	Wed Jul 10 13:25:07 2013 +0530
@@ -62,4 +62,10 @@
      * @param code bytecode to verify
      */
     public void verify(final byte[] code);
+
+    /**
+     * Get next unique script id
+     * @return unique script id
+     */
+    public long getUniqueScriptId();
 }
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java	Tue Jul 09 15:56:59 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java	Wed Jul 10 13:25:07 2013 +0530
@@ -96,6 +96,11 @@
         public void verify(final byte[] code) {
             context.verify(code);
         }
+
+        @Override
+        public long getUniqueScriptId() {
+            return context.getUniqueScriptId();
+        }
     }
 
     /** Is Context global debug mode enabled ? */
@@ -197,6 +202,9 @@
     /** Current error manager. */
     private final ErrorManager errors;
 
+    /** Unique id for script. Used only when --loader-per-compile=false */
+    private long uniqueScriptId;
+
     private static final ClassLoader myLoader = Context.class.getClassLoader();
     private static final StructureLoader sharedLoader;
     private static final AccessControlContext NO_PERMISSIONS_CONTEXT;
@@ -816,4 +824,8 @@
     private ScriptObject newGlobalTrusted() {
         return new Global(this);
     }
+
+    private synchronized long getUniqueScriptId() {
+        return uniqueScriptId++;
+    }
 }
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java	Tue Jul 09 15:56:59 2013 +0200
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java	Wed Jul 10 13:25:07 2013 +0530
@@ -145,4 +145,55 @@
 
         fail("Cannot find nashorn factory!");
     }
+
+    @Test
+    /**
+     * Test repeated evals with --loader-per-compile=false
+     * We used to get "class redefinition error".
+     */
+    public void noLoaderPerCompilerTest() {
+        final ScriptEngineManager sm = new ScriptEngineManager();
+        for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+            if (fac instanceof NashornScriptEngineFactory) {
+                final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+                final String[] options = new String[] { "--loader-per-compile=false" };
+                final ScriptEngine e = nfac.getScriptEngine(options);
+                try {
+                    e.eval("2 + 3");
+                    e.eval("4 + 4");
+                } catch (final ScriptException se) {
+                    se.printStackTrace();
+                    fail(se.getMessage());
+                }
+                return;
+            }
+        }
+        fail("Cannot find nashorn factory!");
+    }
+
+    @Test
+    /**
+     * Test that we can use same script name in repeated evals with --loader-per-compile=false
+     * We used to get "class redefinition error" as name was derived from script name.
+     */
+    public void noLoaderPerCompilerWithSameNameTest() {
+        final ScriptEngineManager sm = new ScriptEngineManager();
+        for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+            if (fac instanceof NashornScriptEngineFactory) {
+                final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+                final String[] options = new String[] { "--loader-per-compile=false" };
+                final ScriptEngine e = nfac.getScriptEngine(options);
+                e.put(ScriptEngine.FILENAME, "test.js");
+                try {
+                    e.eval("2 + 3");
+                    e.eval("4 + 4");
+                } catch (final ScriptException se) {
+                    se.printStackTrace();
+                    fail(se.getMessage());
+                }
+                return;
+            }
+        }
+        fail("Cannot find nashorn factory!");
+    }
 }