8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
Reviewed-by: hannesw
--- 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!");
+ }
}