8007091: Provide private API to pass application class loader for nashorn script engine
Reviewed-by: jlaskey, lagergren
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Mon Jan 28 16:22:03 2013 -0400
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Tue Jan 29 19:57:25 2013 +0530
@@ -141,6 +141,16 @@
}
/**
+ * Create a new Script engine initialized by given class loader.
+ *
+ * @param appLoader class loader to be used as script "app" class loader.
+ * @return newly created script engine.
+ */
+ public ScriptEngine getScriptEngine(final ClassLoader appLoader) {
+ return new NashornScriptEngine(this, appLoader);
+ }
+
+ /**
* Create a new Script engine initialized by given arguments.
*
* @param args arguments array passed to script engine.
@@ -150,6 +160,17 @@
return new NashornScriptEngine(this, args, getAppClassLoader());
}
+ /**
+ * Create a new Script engine initialized by given arguments.
+ *
+ * @param args arguments array passed to script engine.
+ * @param appLoader class loader to be used as script "app" class loader.
+ * @return newly created script engine.
+ */
+ public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) {
+ return new NashornScriptEngine(this, args, appLoader);
+ }
+
// -- Internals only below this point
private static final List<String> names;
@@ -180,7 +201,7 @@
private static ClassLoader getAppClassLoader() {
if (System.getSecurityManager() == null) {
- return ClassLoader.getSystemClassLoader();
+ return Thread.currentThread().getContextClassLoader();
}
// Try to determine the caller class loader. Use that if it can be
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Mon Jan 28 16:22:03 2013 -0400
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Tue Jan 29 19:57:25 2013 +0530
@@ -971,4 +971,100 @@
fail(se.getMessage());
}
}
+
+ private static class MyClassLoader extends ClassLoader {
+ // to check if script engine uses the specified class loader
+ private final boolean[] reached = new boolean[1];
+
+ @Override
+ protected Class findClass(final String name) throws ClassNotFoundException {
+ // flag that it reached here
+ reached[0] = true;
+ return super.findClass(name);
+ }
+
+ public boolean reached() {
+ return reached[0];
+ }
+ };
+
+ @Test
+ public void factoryClassLoaderTest() {
+ final ScriptEngineManager sm = new ScriptEngineManager();
+ for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+ final MyClassLoader loader = new MyClassLoader();
+ // set the classloader as app class loader
+ final ScriptEngine e = nfac.getScriptEngine(loader);
+ try {
+ e.eval("Packages.foo");
+ // check that the class loader was attempted
+ assertTrue(loader.reached(), "did not reach class loader!");
+ } catch (final ScriptException se) {
+ se.printStackTrace();
+ fail(se.getMessage());
+ }
+ return;
+ }
+ }
+
+ fail("Cannot find nashorn factory!");
+ }
+
+ @Test
+ public void factoryOptionsTest() {
+ final ScriptEngineManager sm = new ScriptEngineManager();
+ for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+ // specify --no-syntax-extensions flag
+ final String[] options = new String[] { "--no-syntax-extensions" };
+ final ScriptEngine e = nfac.getScriptEngine(options);
+ try {
+ // try nashorn specific extension
+ e.eval("var f = funtion(x) 2*x;");
+ fail("should have thrown exception!");
+ } catch (final ScriptException se) {
+ }
+ return;
+ }
+ }
+
+ fail("Cannot find nashorn factory!");
+ }
+
+ @Test
+ public void factoryClassLoaderAndOptionsTest() {
+ final ScriptEngineManager sm = new ScriptEngineManager();
+ for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac;
+ final String[] options = new String[] { "-strict" };
+ final MyClassLoader loader = new MyClassLoader();
+ // set the classloader as app class loader
+ final ScriptEngine e = nfac.getScriptEngine(options, loader);
+ try {
+ e.eval("Packages.foo");
+ // check that the class loader was attempted
+ assertTrue(loader.reached(), "did not reach class loader!");
+ } catch (final ScriptException se) {
+ se.printStackTrace();
+ fail(se.getMessage());
+ }
+
+ try {
+ // strict mode - delete of a var should throw SyntaxError
+ e.eval("var d = 2; delete d;");
+ } catch (final ScriptException se) {
+ // check that the error message contains "SyntaxError"
+ assertTrue(se.getMessage().contains("SyntaxError"));
+ }
+
+ return;
+ }
+ }
+
+ fail("Cannot find nashorn factory!");
+ }
}