8007715: Make sure that not all tests run with AllPermission

Reviewed-by: lagergren, attila
diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
index 8ef6b50..04766c1 100644
--- a/nashorn/make/build.xml
+++ b/nashorn/make/build.xml
@@ -198,25 +198,40 @@
            debug="${javac.debug}"
            encoding="${javac.encoding}"
            includeantruntime="false"/>
+
+    <!-- tests that check nashorn internals and internal API -->
+    <jar jarfile="${nashorn.internal.tests.jar}">
+      <fileset dir="${build.test.classes.dir}" excludes="**/api/scripting/*"/>
+    </jar>
+
+    <!-- tests that check nashorn script engine (jsr-223) API -->
+    <jar jarfile="${nashorn.api.tests.jar}">
+      <fileset dir="${build.test.classes.dir}" includes="**/api/scripting/*"/>
+    </jar>
+
   </target>
 
   <target name="generate-policy-file">
     <!-- Generating nashorn.policy file -->
-    <echo message="grant codeBase &quot;file:/${basedir}/dist/nashorn.jar&quot; {" file="${build.dir}/nashorn.policy"/>
+
+    <!-- nashorn internal tests jar requires AllPermission -->
+    <echo message="grant codeBase &quot;file:/${basedir}/${nashorn.internal.tests.jar}&quot; {" file="${build.dir}/nashorn.policy"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
+    <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-
-    <echo message="grant codeBase &quot;file:/${basedir}/build/test/classes&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
+    
+    <!-- TestNG framework jar needs AllPermission -->
+    <echo message="grant codeBase &quot;file:/${basedir}/${file.reference.testng.jar}&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
 
-    <echo message="grant codeBase &quot;file:/${basedir}/${file.reference.testng.jar}&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
+    <!-- AllPermission to test/script/trusted tests -->
+    <echo message="grant codeBase &quot;file:/${basedir}/test/script/trusted/*&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
@@ -225,14 +240,11 @@
 
     <echo message="grant codeBase &quot;file:/${basedir}/test/script/basic/*&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
+    <!-- test/script/basic .js scripts load other script tests -->
+    <echo message="    permission java.io.FilePermission &quot;${basedir}/test/script/-&quot;, &quot;read&quot;;" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-
-    <echo message="grant codeBase &quot;file:/${basedir}/test/perf/*&quot; {" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
-    <echo message="    permission java.security.AllPermission;" file="${build.dir}/nashorn.policy" append="true"/>
+    <!-- test/script/basic .js scripts can read nashorn.test.* properties -->
+    <echo message="    permission java.util.PropertyPermission &quot;nashorn.test.*&quot;, &quot;read&quot;;" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="};" file="${build.dir}/nashorn.policy" append="true"/>
     <echo message="" file="${build.dir}/nashorn.policy" append="true"/>
diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties
index 682cdb6..70107f4 100644
--- a/nashorn/make/project.properties
+++ b/nashorn/make/project.properties
@@ -53,6 +53,10 @@
 
 # test classes directory
 build.test.classes.dir=${build.dir}/test/classes
+# nashorn test jar - internal tests jar and api tests jar
+nashorn.internal.tests.jar=${build.dir}/nashorn-internal-tests.jar
+nashorn.api.tests.jar=${build.dir}/nashorn-api-tests.jar
+
 # test results directory
 build.test.results.dir=${build.dir}/test/reports
 
@@ -116,12 +120,13 @@
 test.basic.dir=test/script/basic
 test.error.dir=test/script/error
 test.sandbox.dir=test/script/sandbox
+test.trusted.dir=test/script/trusted
 test.external.dir=test/script/external
 test262.dir=${test.external.dir}/test262
 test262.suite.dir=${test262.dir}/test/suite
 
 test-sys-prop.test.dir=${test.dir}
-test-sys-prop.test.js.roots=${test.basic.dir} ${test.error.dir} ${test.sandbox.dir}
+test-sys-prop.test.js.roots=${test.basic.dir} ${test.error.dir} ${test.sandbox.dir} ${test.trusted.dir}
 test-sys-prop.test262.suite.dir=${test262.suite.dir}
 test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases
 test-sys-prop.test.basic.dir=${test.basic.dir}
@@ -205,7 +210,9 @@
 
 run.test.classpath=\
     ${file.reference.testng.jar}:\
-    ${build.test.classes.dir}
+    ${nashorn.internal.tests.jar}:\
+    ${nashorn.api.tests.jar}
+
 src.dir=src
 test.src.dir=test/src
 
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
index c7137fd..6e04247 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
@@ -607,24 +607,38 @@
         if (src instanceof String) {
             srcName = (String)src;
             final File file = new File((String)src);
-            if (file.isFile()) {
-                url = file.toURI().toURL();
-            } else if (srcName.indexOf(':') != -1) {
+            if (srcName.indexOf(':') != -1) {
                 try {
                     url = new URL((String)src);
                 } catch (final MalformedURLException e) {
                     // fallback URL - nashorn:foo.js - check under jdk/nashorn/internal/runtime/resources
-                    String str = (String)src;
+                    final String str = (String)src;
                     if (str.startsWith("nashorn:")) {
-                        str = "resources/" + str.substring("nashorn:".length());
-                        url = Context.class.getResource(str);
-                        if (url == null) {
+                        final String resource = "resources/" + str.substring("nashorn:".length());
+                        // NOTE: even sandbox scripts should be able to load scripts in nashorn: scheme
+                        // These scripts are always available and are loaded from nashorn.jar's resources.
+                        final Source code = AccessController.doPrivileged(
+                                new PrivilegedAction<Source>() {
+                                    @Override
+                                    public Source run() {
+                                        try {
+                                            final URL resURL = Context.class.getResource(resource);
+                                            return (resURL != null)? new Source(str, resURL) : null;
+                                        } catch (final IOException exp) {
+                                            return null;
+                                        }
+                                    }
+                                });
+                        if (code == null) {
                             throw e;
                         }
+                        return evaluateSource(code, scope, scope);
                     } else {
                         throw e;
                     }
                 }
+            } else if (file.isFile()) {
+                url = file.toURI().toURL();
             }
             src = url;
         }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
index f4b4ad2..685f141 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
@@ -456,6 +456,8 @@
     private static ClassLoader createClassLoader(final ClassLoader parentLoader, final String className,
             final byte[] classBytes, final String privilegedActionClassName) {
         return new AdapterLoader(parentLoader) {
+            private final ProtectionDomain myProtectionDomain = getClass().getProtectionDomain();
+
             @Override
             protected Class<?> findClass(final String name) throws ClassNotFoundException {
                 if(name.equals(className)) {
@@ -463,7 +465,7 @@
                     return defineClass(name, bytes, 0, bytes.length, GENERATED_PROTECTION_DOMAIN);
                 } else if(name.equals(privilegedActionClassName)) {
                     final byte[] bytes = generatePrivilegedActionClassBytes(privilegedActionClassName.replace('.', '/'));
-                    return defineClass(name, bytes, 0, bytes.length, getClass().getProtectionDomain());
+                    return defineClass(name, bytes, 0, bytes.length, myProtectionDomain);
                 } else {
                     throw new ClassNotFoundException(name);
                 }
diff --git a/nashorn/test/script/README b/nashorn/test/script/README
new file mode 100644
index 0000000..3cca31e
--- /dev/null
+++ b/nashorn/test/script/README
@@ -0,0 +1,26 @@
+basic:
+
+"basic" language and library tests. These need run only with File read 
+permission to read files under "test/script" or subdirs and property read
+permission to read properties named "nashorn.test.*"
+
+error:
+
+scripts that should result in compile-time error. The expected files check
+for the error message format etc.
+
+currently-failing: 
+
+Tests that fail currently - but should pass eventually.
+These are excluded for now.
+
+sandbox:
+
+Tests to check that sandbox scripts cannot access security sensitive resources.
+Scripts under this directory run with no special permissions other than
+what is given to all "sandbox" scripts.
+
+trusted:
+
+These tests run under AllPermission. Put only those scripts that really need
+AllPermission - say for eg. creating class loader, full reflective access.
diff --git a/nashorn/test/script/basic/NASHORN-758.js b/nashorn/test/script/basic/NASHORN-758.js
index 7a92a4c..f57eaf1 100644
--- a/nashorn/test/script/basic/NASHORN-758.js
+++ b/nashorn/test/script/basic/NASHORN-758.js
@@ -25,16 +25,16 @@
  * NASHORN-758 : nashorn shell command line options improvements
  *
  * @test
- * @option -Dfoo=bar
- * @option -Dhello=world
+ * @option -Dnashorn.test.foo=bar
+ * @option -Dnashorn.test.hello=world
  * @run
  */
 
 
-if (java.lang.System.getProperty("foo") != "bar") {
-    fail("System property 'foo' != 'bar'");
+if (java.lang.System.getProperty("nashorn.test.foo") != "bar") {
+    fail("System property 'nashorn.test.foo' != 'bar'");
 }
 
-if (java.lang.System.getProperty("hello") != "world") {
-    fail("System property 'hello' != 'world'");
+if (java.lang.System.getProperty("nashorn.test.hello") != "world") {
+    fail("System property 'nashorn.test.hello' != 'world'");
 }
diff --git a/nashorn/test/script/basic/javaexceptions.js b/nashorn/test/script/basic/javaexceptions.js
index 3db97e6..3f81f69 100644
--- a/nashorn/test/script/basic/javaexceptions.js
+++ b/nashorn/test/script/basic/javaexceptions.js
@@ -31,7 +31,7 @@
 try {
     new java.io.FileInputStream("non_existent_file");
 } catch (e) {
-    print(e instanceof java.io.FileNotFoundException);
+    print(e instanceof java.io.FileNotFoundException || e instanceof java.lang.SecurityException);
 }
 
 try {
diff --git a/nashorn/test/script/basic/newexpr.js b/nashorn/test/script/basic/newexpr.js
index 78711a1..d8d1b48 100644
--- a/nashorn/test/script/basic/newexpr.js
+++ b/nashorn/test/script/basic/newexpr.js
@@ -29,7 +29,7 @@
  */
 
 var File = java.io.File;
-print(new File(".").isDirectory());
+print(! new File(".").toString().isEmpty());
 
 var obj = {
    foo : function (x) {
diff --git a/nashorn/test/script/sandbox/interfaceimpl.js b/nashorn/test/script/sandbox/interfaceimpl.js
new file mode 100644
index 0000000..b2ee86b
--- /dev/null
+++ b/nashorn/test/script/sandbox/interfaceimpl.js
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Check that user defined interface can be implemented.
+ *
+ * @test
+ * @run
+ * @security
+ */
+
+var Window = Java.type("jdk.nashorn.api.scripting.Window");
+var WindowEventHandler = Java.type("jdk.nashorn.api.scripting.WindowEventHandler");
+
+var w = new Window();
+
+var loadedFuncReached = false;
+// try function to SAM converter
+w.onload = function() {
+    loadedFuncReached = true;
+    return true;
+}
+
+w.onload.loaded();
+if (! loadedFuncReached) {
+    fail("Interface method impl. not called");
+}
+
+// reset
+loadedFuncReached = false;
+
+// try direct interface implementation
+w.onload = new WindowEventHandler() {
+    loaded: function() {
+        loadedFuncReached = true;
+        return true;
+    }
+};
+
+w.onload.loaded();
+if (! loadedFuncReached) {
+    fail("Interface method impl. not called");
+}
diff --git a/nashorn/test/script/sandbox/loadcompat.js b/nashorn/test/script/sandbox/loadcompat.js
new file mode 100644
index 0000000..e99f67f
--- /dev/null
+++ b/nashorn/test/script/sandbox/loadcompat.js
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Check that nashorn mozilla compatibility script can be loaded in sandbox.
+ *
+ * @test
+ * @run
+ * @security
+ */
+
+load("nashorn:mozilla_compat.js");
+
+var obj = {};
+if (obj.__proto__ !== Object.prototype) {
+    fail("__proto__ does not work as expected");
+}
+
+var array = [];
+if (array.__proto__ !== Array.prototype) {
+    fail("__proto__ does not work as expected");
+}
+
+if (typeof JavaAdapter != 'function') {
+    fail("JavaAdapter constructor is missing in compatibility script");
+}
+
+if (typeof importPackage != 'function') {
+    fail("importPackage function is missing in compatibility script");
+}
diff --git a/nashorn/test/script/basic/JDK-8006424.js b/nashorn/test/script/trusted/JDK-8006424.js
similarity index 100%
rename from nashorn/test/script/basic/JDK-8006424.js
rename to nashorn/test/script/trusted/JDK-8006424.js
diff --git a/nashorn/test/script/basic/JDK-8006529.js b/nashorn/test/script/trusted/JDK-8006529.js
similarity index 100%
rename from nashorn/test/script/basic/JDK-8006529.js
rename to nashorn/test/script/trusted/JDK-8006529.js
diff --git a/nashorn/test/script/basic/NASHORN-638.js b/nashorn/test/script/trusted/NASHORN-638.js
similarity index 100%
rename from nashorn/test/script/basic/NASHORN-638.js
rename to nashorn/test/script/trusted/NASHORN-638.js
diff --git a/nashorn/test/script/basic/NASHORN-638.js.EXPECTED b/nashorn/test/script/trusted/NASHORN-638.js.EXPECTED
similarity index 100%
rename from nashorn/test/script/basic/NASHORN-638.js.EXPECTED
rename to nashorn/test/script/trusted/NASHORN-638.js.EXPECTED
diff --git a/nashorn/test/script/basic/NASHORN-653.js b/nashorn/test/script/trusted/NASHORN-653.js
similarity index 100%
rename from nashorn/test/script/basic/NASHORN-653.js
rename to nashorn/test/script/trusted/NASHORN-653.js
diff --git a/nashorn/test/script/trusted/README b/nashorn/test/script/trusted/README
new file mode 100644
index 0000000..60260ed
--- /dev/null
+++ b/nashorn/test/script/trusted/README
@@ -0,0 +1,4 @@
+This directory contains tests that need AllPermission to run.
+
+Scripts that need to create classloaders, need to reflectively access
+declared members of other classes etc. should go here.
diff --git a/nashorn/test/script/basic/getenv.js b/nashorn/test/script/trusted/getenv.js
similarity index 100%
rename from nashorn/test/script/basic/getenv.js
rename to nashorn/test/script/trusted/getenv.js
diff --git a/nashorn/test/script/basic/getenv.js.EXPECTED b/nashorn/test/script/trusted/getenv.js.EXPECTED
similarity index 100%
rename from nashorn/test/script/basic/getenv.js.EXPECTED
rename to nashorn/test/script/trusted/getenv.js.EXPECTED
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
index 6b043f6..169ebf9 100644
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
@@ -972,46 +972,6 @@
         }
     }
 
-    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();
@@ -1033,38 +993,4 @@
 
         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!");
-    }
 }
diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java
index f7e6857..3968476 100644
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java
@@ -27,8 +27,15 @@
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 import java.util.Map;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+import jdk.nashorn.api.scripting.ScriptEngineTest;
 import jdk.nashorn.internal.runtime.options.Options;
 import org.testng.annotations.Test;
 
@@ -107,4 +114,83 @@
         final ScriptFunction func = cx.compileScript(source, global, cx._strict);
         return func != null ? ScriptRuntime.apply(func, global) : null;
     }
+
+    // Tests for trusted client usage of nashorn script engine factory extension API
+
+    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];
+        }
+    };
+
+    // These are for "private" extension API of NashornScriptEngineFactory that
+    // accepts a ClassLoader and/or command line options.
+
+    @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 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!");
+    }
 }