changeset 54:333748665588

8007091: Provide private API to pass application class loader for nashorn script engine Reviewed-by: jlaskey, lagergren
author sundar
date Tue, 29 Jan 2013 19:57:25 +0530
parents b6c69beebde6
children 755404d7d189
files src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
diffstat 2 files changed, 118 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java	Mon Jan 28 16:22:03 2013 -0400
+++ b/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/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java	Mon Jan 28 16:22:03 2013 -0400
+++ b/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!");
+    }
 }