8007091: Provide private API to pass application class loader for nashorn script engine
authorsundar
Tue, 29 Jan 2013 19:57:25 +0530
changeset 16199 3722d034c582
parent 16198 1cfb1fbab2dc
child 16200 1c54dc374fe4
8007091: Provide private API to pass application class loader for nashorn script engine Reviewed-by: jlaskey, lagergren
nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
--- 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!");
+    }
 }