Merge
authorlana
Thu, 02 Jun 2016 21:14:32 +0000
changeset 38810 f092b4fabfdb
parent 38804 7155279e3b44 (current diff)
parent 38809 98a5507b1c86 (diff)
child 38811 04341c6c4bc7
Merge
--- a/nashorn/LICENSE	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/LICENSE	Thu Jun 02 21:14:32 2016 +0000
@@ -3,7 +3,7 @@
 Version 2, June 1991
 
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 Everyone is permitted to copy and distribute verbatim copies of this license
 document, but changing it is not allowed.
@@ -287,8 +287,8 @@
     more details.
 
     You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc., 59
-    Temple Place, Suite 330, Boston, MA 02111-1307 USA
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 Also add information on how to contact you by electronic and paper mail.
 
--- a/nashorn/make/build.xml	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/make/build.xml	Thu Jun 02 21:14:32 2016 +0000
@@ -258,31 +258,13 @@
     <property name="compile.suppress.jar" value="defined"/>
   </target>
 
-  <!-- generate javadoc for all Nashorn and ASM classes -->
+  <!-- generate javadoc for Nashorn classes -->
   <target name="javadoc" depends="jar">
     <javadoc destdir="${dist.javadoc.dir}" use="yes" overview="${nashorn.module.src.dir}/overview.html"
         windowtitle="${nashorn.product.name} ${nashorn.version}"
         additionalparam="-quiet" failonerror="true" useexternalfile="true">
-      <arg value="${javadoc.option}"/>
-      <classpath>
-        <pathelement location="${build.classes.dir}"/>
-      </classpath>
-      <fileset dir="${nashorn.module.src.dir}" includes="**/*.java"/>
-      <fileset dir="${nashorn.shell.module.src.dir}" includes="**/*.java"/>
-      <fileset dir="${jdk.asm.src.dir}" includes="**/*.java"/>
-      <link href="http://docs.oracle.com/javase/8/docs/api/"/>
-      <!-- The following tags are used only in ASM sources - just ignore these -->
-      <tag name="label" description="label tag in ASM sources" enabled="false"/>
-      <tag name="linked" description="linked tag in ASM sources" enabled="false"/>
-      <tag name="associates" description="associates tag in ASM sources" enabled="false"/>
-    </javadoc>
-  </target>
-
-  <!-- generate javadoc for Nashorn classes -->
-  <target name="javadocnh" depends="jar">
-    <javadoc destdir="${dist.javadoc.dir}" use="yes" overview="${nashorn.module.src.dir}/overview.html"
-        windowtitle="${nashorn.product.name} ${nashorn.version}"
-        additionalparam="-quiet" failonerror="true" useexternalfile="true">
+      <arg value="-modulesourcepath"/>
+      <arg value="${basedir}/src/*/share/classes"/>
       <arg value="${javadoc.option}"/>
       <classpath>
         <pathelement location="${build.classes.dir}"/>
@@ -295,10 +277,13 @@
   </target>
 
   <!-- generate javadoc only for nashorn extension api classes -->
-  <target name="javadocapi" depends="jar">
-    <javadoc destdir="${dist.javadoc.dir}" use="yes" overview="${nashorn.module.src.dir}/overview.html"
+  <target name="nashornapi" depends="jar">
+    <mkdir dir="${dist.nashornapi.javadoc.dir}"/>
+    <javadoc destdir="${dist.nashornapi.javadoc.dir}" use="yes" overview="${nashorn.module.src.dir}/overview.html"
         extdirs="${nashorn.ext.path}" windowtitle="${nashorn.product.name} ${nashorn.version}"
         additionalparam="-quiet" failonerror="true" useexternalfile="true">
+      <arg value="-modulesourcepath"/>
+      <arg value="${basedir}/src/*/share/classes"/>
       <arg value="${javadoc.option}"/>
       <classpath>
         <pathelement location="${build.classes.dir}"/>
@@ -310,9 +295,12 @@
 
   <!-- generate javadoc only for Dynalink API classes -->
   <target name="dynalinkapi" depends="jar">
-    <javadoc destdir="${dist.javadoc.dir}" use="yes"
+    <mkdir dir="${dist.dynalinkapi.javadoc.dir}"/>
+    <javadoc destdir="${dist.dynalinkapi.javadoc.dir}" use="yes"
         windowtitle="Dynalink"
         additionalparam="-quiet" failonerror="true" useexternalfile="true">
+      <arg value="-modulesourcepath"/>
+      <arg value="${basedir}/src/*/share/classes"/>
       <arg value="${javadoc.option}"/>
       <classpath>
         <pathelement location="${build.classes.dir}"/>
@@ -322,6 +310,8 @@
     </javadoc>
   </target>
 
+  <target name="javadocapi" depends="nashornapi, dynalinkapi"/>
+
   <!-- generate shell.html for shell tool documentation -->
   <target name="shelldoc" depends="jar">
     <java classname="${nashorn.shell.tool}" dir="${basedir}" output="${dist.dir}/shell.html" failonerror="true" fork="true">
@@ -502,6 +492,10 @@
     permission java.io.FilePermission "${basedir}/test/script/external/showdown/-", "read";
 };
 
+grant codeBase "file:/${basedir}/test/script/basic/JDK-8158467.js" {
+    permission java.lang.RuntimePermission "nashorn.setConfig";
+};
+
     </echo>
 
     <replace file="${build.dir}/nashorn.policy"><replacetoken>\</replacetoken><replacevalue>/</replacevalue></replace>    <!--hack for Windows - to make URLs with normal path separators -->
@@ -595,7 +589,7 @@
     </testng>
   </target>
 
-  <target name="test" depends="prepare, test-pessimistic, test-optimistic"/>
+  <target name="test" depends="prepare, javadoc, test-pessimistic, test-optimistic"/>
 
   <target name="test-optimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
     <echo message="Running test suite in OPTIMISTIC mode..."/>
--- a/nashorn/make/project.properties	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/make/project.properties	Thu Jun 02 21:14:32 2016 +0000
@@ -24,7 +24,8 @@
 application.title=nashorn
 
 # location of JDK embedded ASM sources
-jdk.asm.src.dir=../jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm
+jdk.java.base.dir=../jdk/src/java.base/share/classes
+jdk.asm.src.dir=${jdk.java.base.dir}/jdk/internal/org/objectweb/asm
 
 # location of JDK embedded jline sources
 jdk.jline.src.dir=../jdk/src/jdk.internal.le/share/classes
@@ -86,6 +87,8 @@
 nashorn.jar=${dist.dir}/nashorn.jar
 jjs.jar=${dist.dir}/jjs.jar
 dist.javadoc.dir=${dist.dir}/javadoc
+dist.nashornapi.javadoc.dir=${dist.javadoc.dir}/nashornapi
+dist.dynalinkapi.javadoc.dir=${dist.javadoc.dir}/dynalinkapi
 
 # configuration for java flight recorder
 run.test.jvmargs.jfr=-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=${build.dir},stackdepth=128
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Module.java	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Module.java	Thu Jun 02 21:14:32 2016 +0000
@@ -44,7 +44,7 @@
     /**
      * A module ExportEntry record.
      *
-     * @link http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records
+     * @see <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records">es6 modules</a>
      */
     public static final class ExportEntry {
         private final String exportName;
@@ -164,7 +164,7 @@
     /**
      * An ImportEntry record.
      *
-     * @link http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records
+     * @see <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records">es6 modules</a>
      */
     public static final class ImportEntry {
         private final String moduleRequest;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Thu Jun 02 21:14:32 2016 +0000
@@ -4626,6 +4626,9 @@
      *   ArrowFunction[?In, ?Yield]
      *   LeftHandSideExpression[?Yield] = AssignmentExpression[?In, ?Yield]
      *   LeftHandSideExpression[?Yield] AssignmentOperator AssignmentExpression[?In, ?Yield]
+     *
+     * @param noIn {@code true} if IN operator should be ignored.
+     * @return the assignment expression
      */
     protected Expression assignmentExpression(final boolean noIn) {
         // This method is protected so that subclass can get details
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Thu Jun 02 21:14:32 2016 +0000
@@ -39,14 +39,21 @@
 import java.io.InputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.io.UncheckedIOException;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import java.lang.invoke.SwitchPoint;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.SoftReference;
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
 import java.lang.reflect.Field;
+import java.lang.reflect.Layer;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.Module;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.security.AccessControlContext;
@@ -60,9 +67,12 @@
 import java.security.ProtectionDomain;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicLong;
@@ -129,6 +139,11 @@
     public static final String NASHORN_JAVA_REFLECTION = "nashorn.JavaReflection";
 
     /**
+     * Permission to create a new Module
+     */
+    public static final String NASHORN_CREATE_MODULE = "nashorn.createModule";
+
+    /**
      * Permission to enable nashorn debug mode.
      */
     public static final String NASHORN_DEBUG_MODE = "nashorn.debugMode";
@@ -337,7 +352,7 @@
             return new NamedContextCodeInstaller(context, codeSource, context.createNewLoader());
         }
 
-        private static final byte[] getAnonymousHostClassBytes() {
+        private static byte[] getAnonymousHostClassBytes() {
             final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
             cw.visit(V1_7, Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, ANONYMOUS_HOST_CLASS_NAME.replace('.', '/'), null, "java/lang/Object", null);
             cw.visitEnd();
@@ -471,6 +486,11 @@
     /** class loader to resolve classes from script. */
     private final ClassLoader appLoader;
 
+    /*package-private*/
+    ClassLoader getAppLoader() {
+        return appLoader;
+    }
+
     /** Class loader to load classes compiled from scripts. */
     private final ScriptLoader scriptLoader;
 
@@ -486,13 +506,13 @@
     /** Optional class filter to use for Java classes. Can be null. */
     private final ClassFilter classFilter;
 
-    private static final ClassLoader myLoader = Context.class.getClassLoader();
-    private static final StructureLoader sharedLoader;
+    /** Process-wide singleton structure loader */
+    private static final StructureLoader theStructLoader;
     private static final ConcurrentMap<String, Class<?>> structureClasses = new ConcurrentHashMap<>();
 
     /*package-private*/ @SuppressWarnings("static-method")
-    StructureLoader getSharedLoader() {
-        return sharedLoader;
+    StructureLoader getStructLoader() {
+        return theStructLoader;
     }
 
     private static AccessControlContext createNoPermAccCtxt() {
@@ -508,9 +528,11 @@
     private static final AccessControlContext NO_PERMISSIONS_ACC_CTXT = createNoPermAccCtxt();
     private static final AccessControlContext CREATE_LOADER_ACC_CTXT  = createPermAccCtxt("createClassLoader");
     private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT  = createPermAccCtxt(NASHORN_CREATE_GLOBAL);
+    private static final AccessControlContext GET_LOADER_ACC_CTXT     = createPermAccCtxt("getClassLoader");
 
     static {
-        sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
+        final ClassLoader myLoader = Context.class.getClassLoader();
+        theStructLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
             @Override
             public StructureLoader run() {
                 return new StructureLoader(myLoader);
@@ -791,7 +813,7 @@
         // Nashorn extension: any 'eval' is unconditionally strict when -strict is specified.
         boolean strictFlag = strict || this._strict;
 
-        Class<?> clazz = null;
+        Class<?> clazz;
         try {
             clazz = compile(source, new ThrowErrorManager(), strictFlag, true);
         } catch (final ParserException e) {
@@ -1022,7 +1044,7 @@
         }
         return (Class<? extends ScriptObject>)structureClasses.computeIfAbsent(fullName, (name) -> {
             try {
-                return Class.forName(name, true, sharedLoader);
+                return Class.forName(name, true, theStructLoader);
             } catch (final ClassNotFoundException e) {
                 throw new AssertionError(e);
             }
@@ -1144,7 +1166,17 @@
         }
 
         // Try finding using the "app" loader.
-        return Class.forName(fullName, true, appLoader);
+        if (appLoader != null) {
+            return Class.forName(fullName, true, appLoader);
+        } else {
+            final Class<?> cl = Class.forName(fullName);
+            // return the Class only if it was loaded by boot loader
+            if (cl.getClassLoader() == null) {
+                return cl;
+            } else {
+                throw new ClassNotFoundException(fullName);
+            }
+        }
     }
 
     /**
@@ -1175,7 +1207,7 @@
             // No verification when security manager is around as verifier
             // may load further classes - which should be avoided.
             if (System.getSecurityManager() == null) {
-                CheckClassAdapter.verify(new ClassReader(bytecode), sharedLoader, false, new PrintWriter(System.err, true));
+                CheckClassAdapter.verify(new ClassReader(bytecode), theStructLoader, false, new PrintWriter(System.err, true));
             }
         }
     }
@@ -1281,6 +1313,78 @@
         return getContextTrusted().dynamicLinker;
     }
 
+    /**
+     * Creates a module layer with one module that is defined to the given class
+     * loader.
+     *
+     * @param descriptor the module descriptor for the newly created module
+     * @param loader the class loader of the module
+     * @return the new Module
+     */
+    public static Module createModule(final ModuleDescriptor descriptor, final ClassLoader loader) {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission(NASHORN_CREATE_MODULE));
+        }
+        return createModuleTrusted(descriptor, loader);
+    }
+
+    /**
+     * Creates a module layer with one module that is defined to the given class
+     * loader.
+     *
+     * @param descriptor the module descriptor for the newly created module
+     * @param loader the class loader of the module
+     * @return the new Module
+     */
+    static Module createModuleTrusted(final ModuleDescriptor descriptor, final ClassLoader loader) {
+        return createModuleTrusted(Layer.boot(), descriptor, loader);
+    }
+
+    /**
+     * Creates a module layer with one module that is defined to the given class
+     * loader.
+     *
+     * @param parent the parent layer of the new module
+     * @param descriptor the module descriptor for the newly created module
+     * @param loader the class loader of the module
+     * @return the new Module
+     */
+    static Module createModuleTrusted(final Layer parent, final ModuleDescriptor descriptor, final ClassLoader loader) {
+        final String mn = descriptor.name();
+
+        final ModuleReference mref = new ModuleReference(descriptor, null, () -> {
+            IOException ioe = new IOException("<dynamic module>");
+            throw new UncheckedIOException(ioe);
+        });
+
+        final ModuleFinder finder = new ModuleFinder() {
+            @Override
+            public Optional<ModuleReference> find(String name) {
+                if (name.equals(mn)) {
+                    return Optional.of(mref);
+                } else {
+                    return Optional.empty();
+                }
+            }
+            @Override
+            public Set<ModuleReference> findAll() {
+                return Set.of(mref);
+            }
+        };
+
+        final Configuration cf = parent.configuration()
+                .resolveRequires(finder, ModuleFinder.of(), Set.of(mn));
+
+        final PrivilegedAction<Layer> pa = () -> parent.defineModules(cf, name -> loader);
+        final Layer layer = AccessController.doPrivileged(pa, GET_LOADER_ACC_CTXT);
+
+        final Module m = layer.findModule(mn).get();
+        assert m.getLayer() == layer;
+
+        return m;
+    }
+
     static Context getContextTrustedOrNull() {
         final Global global = Context.getGlobal();
         return global == null ? null : getContext(global);
@@ -1463,7 +1567,7 @@
              new PrivilegedAction<ScriptLoader>() {
                 @Override
                 public ScriptLoader run() {
-                    return new ScriptLoader(appLoader, Context.this);
+                    return new ScriptLoader(Context.this);
                 }
              }, CREATE_LOADER_ACC_CTXT);
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/NashornLoader.java	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/NashornLoader.java	Thu Jun 02 21:14:32 2016 +0000
@@ -26,19 +26,22 @@
 package jdk.nashorn.internal.runtime;
 
 import java.io.File;
+import java.io.InputStream;
 import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.lang.reflect.Module;
+import java.security.AccessController;
 import java.security.CodeSource;
 import java.security.Permission;
 import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
 import java.security.Permissions;
 import java.security.SecureClassLoader;
-import java.util.HashSet;
-import java.util.Set;
-import jdk.internal.module.Modules;
 
 /**
  * Superclass for Nashorn class loader classes.
@@ -55,15 +58,14 @@
     protected static final String RUNTIME_LINKER_PKG_INTERNAL = "jdk/nashorn/internal/runtime/linker";
     protected static final String SCRIPTS_PKG_INTERNAL        = "jdk/nashorn/internal/scripts";
 
-    protected static final Module nashornModule = NashornLoader.class.getModule();
+    static final Module NASHORN_MODULE = Context.class.getModule();
 
     private static final Permission[] SCRIPT_PERMISSIONS;
 
-    private static final Set<String> scriptsPkgSet = new HashSet<>();
+    private static final String MODULE_MANIPULATOR_NAME = SCRIPTS_PKG + ".ModuleGraphManipulator";
+    private static final byte[] MODULE_MANIPULATOR_BYTES = readModuleManipulatorBytes();
 
     static {
-        scriptsPkgSet.add(SCRIPTS_PKG);
-
         /*
          * Generated classes get access to runtime, runtime.linker, objects, scripts packages.
          * Note that the actual scripts can not access these because Java.type, Packages
@@ -80,23 +82,42 @@
         };
     }
 
+    // addExport Method object on ModuleGraphManipulator
+    // class loaded by this loader
+    private Method addModuleExport;
+
     NashornLoader(final ClassLoader parent) {
         super(parent);
     }
 
-    protected static Module defineModule(final String moduleName, final ClassLoader loader) {
-        return Modules.defineModule(loader, moduleName, scriptsPkgSet);
+    void loadModuleManipulator() {
+        final Class<?> clazz = defineClass(MODULE_MANIPULATOR_NAME,
+                MODULE_MANIPULATOR_BYTES, 0, MODULE_MANIPULATOR_BYTES.length);
+        // force class initialization so that <clinit> runs!
+        try {
+            Class.forName(MODULE_MANIPULATOR_NAME, true, this);
+        } catch (final Exception ex) {
+            throw new RuntimeException(ex);
+        }
+        final PrivilegedAction<Void> pa = () -> {
+            try {
+                addModuleExport = clazz.getDeclaredMethod("addExport", Module.class);
+                addModuleExport.setAccessible(true);
+            } catch (final NoSuchMethodException | SecurityException ex) {
+                throw new RuntimeException(ex);
+            }
+            return null;
+        };
+        AccessController.doPrivileged(pa);
     }
 
-    protected static void addReadsModule(final Module from, final Module to) {
-        Modules.addReads(from, to);
-    }
-
-    protected static void addModuleExports(final Module from, final String pkg, final Module to) {
-        if (to == null) {
-            Modules.addExportsToAll(from, pkg);
-        } else {
-            Modules.addExports(from, pkg, to);
+    final void addModuleExport(final Module to) {
+        try {
+            addModuleExport.invoke(null, to);
+        } catch (final IllegalAccessException |
+                IllegalArgumentException |
+                InvocationTargetException ex) {
+            throw new RuntimeException(ex);
         }
     }
 
@@ -194,5 +215,17 @@
             throw new IllegalArgumentException("file");
         }
     }
+
+    private static byte[] readModuleManipulatorBytes() {
+        final PrivilegedAction<byte[]> pa = () -> {
+            final String res = "/"+ MODULE_MANIPULATOR_NAME.replace('.', '/') + ".class";
+            try (InputStream in = NashornLoader.class.getResourceAsStream(res)) {
+                return in.readAllBytes();
+            } catch (IOException exp) {
+                throw new UncheckedIOException(exp);
+            }
+        };
+        return AccessController.doPrivileged(pa);
+    }
 }
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java	Thu Jun 02 21:14:32 2016 +0000
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.internal.runtime;
 
+import java.lang.module.ModuleDescriptor;
 import java.lang.reflect.Module;
 import java.security.CodeSource;
 import java.util.Objects;
@@ -37,8 +38,8 @@
     private static final String NASHORN_PKG_PREFIX = "jdk.nashorn.internal.";
 
     private volatile boolean structureAccessAdded;
+    private final Context context;
     private final Module scriptModule;
-    private final Context context;
 
     /*package-private*/ Context getContext() {
         return context;
@@ -47,44 +48,77 @@
     /**
      * Constructor.
      */
-    ScriptLoader(final ClassLoader parent, final Context context) {
-        super(parent);
+    ScriptLoader(final Context context) {
+        super(context.getStructLoader());
         this.context = context;
 
         // new scripts module, it's specific exports and read-edges
-        scriptModule = defineModule("jdk.scripting.nashorn.scripts", this);
-        addModuleExports(scriptModule, SCRIPTS_PKG, nashornModule);
-        addReadsModule(scriptModule, nashornModule);
-        addReadsModule(scriptModule, Object.class.getModule());
+        scriptModule = createModule("jdk.scripting.nashorn.scripts");
 
         // specific exports from nashorn to new scripts module
-        nashornModule.addExports(OBJECTS_PKG, scriptModule);
-        nashornModule.addExports(RUNTIME_PKG, scriptModule);
-        nashornModule.addExports(RUNTIME_ARRAYS_PKG, scriptModule);
-        nashornModule.addExports(RUNTIME_LINKER_PKG, scriptModule);
-        nashornModule.addExports(SCRIPTS_PKG, scriptModule);
+        NASHORN_MODULE.addExports(OBJECTS_PKG, scriptModule);
+        NASHORN_MODULE.addExports(RUNTIME_PKG, scriptModule);
+        NASHORN_MODULE.addExports(RUNTIME_ARRAYS_PKG, scriptModule);
+        NASHORN_MODULE.addExports(RUNTIME_LINKER_PKG, scriptModule);
+        NASHORN_MODULE.addExports(SCRIPTS_PKG, scriptModule);
 
         // nashorn needs to read scripts module methods,fields
-        nashornModule.addReads(scriptModule);
+        NASHORN_MODULE.addReads(scriptModule);
+    }
+
+    private Module createModule(final String moduleName) {
+        final Module structMod = context.getStructLoader().getModule();
+        final ModuleDescriptor descriptor
+                = new ModuleDescriptor.Builder(moduleName)
+                    .requires(NASHORN_MODULE.getName())
+                    .requires(structMod.getName())
+                    .conceals(SCRIPTS_PKG)
+                    .build();
+
+        final Module mod = Context.createModuleTrusted(structMod.getLayer(), descriptor, this);
+        loadModuleManipulator();
+        return mod;
     }
 
     @Override
     protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
         checkPackageAccess(name);
-        if (name.startsWith(NASHORN_PKG_PREFIX)) {
-            final StructureLoader sharedCl = context.getSharedLoader();
-            final Class<?> cl = sharedCl.loadClass(name);
-            if (! structureAccessAdded) {
-                if (cl.getClassLoader() == sharedCl) {
-                    structureAccessAdded = true;
-                    final Module structModule = sharedCl.getModule();
-                    addModuleExports(structModule, SCRIPTS_PKG, scriptModule);
-                    addReadsModule(scriptModule, structModule);
-                }
+        final Class<?> cl = super.loadClass(name, resolve);
+        if (!structureAccessAdded) {
+            final StructureLoader structLoader = context.getStructLoader();
+            if (cl.getClassLoader() == structLoader) {
+                structureAccessAdded = true;
+                structLoader.addModuleExport(scriptModule);
             }
-            return cl;
         }
-        return super.loadClass(name, resolve);
+        return cl;
+    }
+
+    @Override
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        final ClassLoader appLoader = context.getAppLoader();
+
+        /*
+         * If the appLoader is null, don't bother side-delegating to it!
+         * Bootloader has been already attempted via parent loader
+         * delegation from the "loadClass" method.
+         *
+         * Also, make sure that we don't delegate to the app loader
+         * for nashorn's own classes or nashorn generated classes!
+         */
+        if (appLoader == null || name.startsWith(NASHORN_PKG_PREFIX)) {
+            throw new ClassNotFoundException(name);
+        }
+
+        /*
+         * This split-delegation is used so that caller loader
+         * based resolutions of classes would work. For example,
+         * java.sql.DriverManager uses caller's class loader to
+         * get Driver instances. Without this split-delegation
+         * a script class evaluating DriverManager.getDrivers()
+         * will not get back any JDBC driver!
+         */
+        return appLoader.loadClass(name);
     }
 
     // package-private and private stuff below this point
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StructureLoader.java	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StructureLoader.java	Thu Jun 02 21:14:32 2016 +0000
@@ -30,6 +30,7 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_DUAL_FIELD_PREFIX;
 import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_SINGLE_FIELD_PREFIX;
 
+import java.lang.module.ModuleDescriptor;
 import java.lang.reflect.Module;
 import java.security.ProtectionDomain;
 import jdk.nashorn.internal.codegen.ObjectClassGenerator;
@@ -50,17 +51,26 @@
         super(parent);
 
         // new structures module, it's exports, read edges
-        structuresModule = defineModule("jdk.scripting.nashorn.structures", this);
-        addModuleExports(structuresModule, SCRIPTS_PKG, nashornModule);
-        addReadsModule(structuresModule, nashornModule);
-        addReadsModule(structuresModule, Object.class.getModule());
+        structuresModule = createModule("jdk.scripting.nashorn.structures");
 
         // specific exports from nashorn to the structures module
-        nashornModule.addExports(SCRIPTS_PKG, structuresModule);
-        nashornModule.addExports(RUNTIME_PKG, structuresModule);
+        NASHORN_MODULE.addExports(SCRIPTS_PKG, structuresModule);
+        NASHORN_MODULE.addExports(RUNTIME_PKG, structuresModule);
 
         // nashorn has to read fields from classes of the new module
-        nashornModule.addReads(structuresModule);
+        NASHORN_MODULE.addReads(structuresModule);
+    }
+
+    private Module createModule(final String moduleName) {
+        final ModuleDescriptor descriptor
+                = new ModuleDescriptor.Builder(moduleName)
+                    .requires(NASHORN_MODULE.getName())
+                    .conceals(SCRIPTS_PKG)
+                    .build();
+
+        final Module mod = Context.createModuleTrusted(descriptor, this);
+        loadModuleManipulator();
+        return mod;
     }
 
     /**
@@ -90,7 +100,7 @@
         return isDualFieldStructure(name) || isSingleFieldStructure(name);
     }
 
-    protected Module getModule() {
+    Module getModule() {
         return structuresModule;
     }
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Thu Jun 02 21:14:32 2016 +0000
@@ -31,12 +31,24 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_VARARGS;
+import static jdk.internal.org.objectweb.asm.Opcodes.AALOAD;
 import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.ARRAYLENGTH;
 import static jdk.internal.org.objectweb.asm.Opcodes.ASTORE;
 import static jdk.internal.org.objectweb.asm.Opcodes.D2F;
+import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.GOTO;
 import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
+import static jdk.internal.org.objectweb.asm.Opcodes.IF_ICMPGE;
+import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.ISTORE;
 import static jdk.internal.org.objectweb.asm.Opcodes.I2B;
 import static jdk.internal.org.objectweb.asm.Opcodes.I2S;
+import static jdk.internal.org.objectweb.asm.Opcodes.POP;
+import static jdk.internal.org.objectweb.asm.Opcodes.PUTSTATIC;
 import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
 import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup;
 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
@@ -62,6 +74,12 @@
 import java.util.List;
 import java.util.Set;
 import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.FieldVisitor;
+import jdk.internal.org.objectweb.asm.Handle;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.Type;
 import jdk.internal.org.objectweb.asm.Handle;
 import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.Opcodes;
@@ -69,6 +87,7 @@
 import jdk.internal.org.objectweb.asm.commons.InstructionAdapter;
 import jdk.nashorn.api.scripting.ScriptUtils;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.linker.AdaptationResult.Outcome;
@@ -136,6 +155,9 @@
  * implemented securely.
  */
 final class JavaAdapterBytecodeGenerator {
+    private static final Module NASHORN_MODULE = Context.class.getModule();
+    private static final Module JAVA_BASE_MODULE = Object.class.getModule();
+
     // Field names in adapters
     private static final String GLOBAL_FIELD_NAME = "global";
     private static final String DELEGATE_FIELD_NAME = "delegate";
@@ -211,6 +233,17 @@
     private static final String FINALIZER_DELEGATE_NAME = "$$nashornFinalizerDelegate";
     private static final String FINALIZER_DELEGATE_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE);
 
+    // adapter class may need module read-edges from other modules.
+    // We generate a class to add those required module read-edges.
+    // This is the name of the module read edge adder class.
+    static final String MODULES_READ_ADDER_INTERNAL = ADAPTER_PACKAGE_INTERNAL + "$ModulesReadAdder";
+    static final String MODULES_READ_ADDER = MODULES_READ_ADDER_INTERNAL.replace('/', '.');
+    // module add read method
+    static final String MODULES_ADD_READS = "addReads";
+
+    // .class bytes of module add reader class. Lazily generated and cached.
+    private static byte[] MODULES_READ_ADDER_BYRES;
+
     /**
      * Collection of methods we never override: Object.clone(), Object.finalize().
      */
@@ -307,6 +340,21 @@
         return autoConvertibleFromFunction;
     }
 
+    static synchronized byte[] getModulesAddReadsBytes() {
+        if (MODULES_READ_ADDER_BYRES == null) {
+            // lazily generate module read edge adder class
+            MODULES_READ_ADDER_BYRES = generateModulesReadAdderClass();
+        }
+
+        return MODULES_READ_ADDER_BYRES;
+    }
+
+    private void addAccessedModule(Module m) {
+        if (m != null && m != JAVA_BASE_MODULE && m != NASHORN_MODULE) {
+            accessedModules.add(m);
+        }
+    }
+
     private static String getGeneratedClassName(final Class<?> superType, final List<Class<?>> interfaces) {
         // The class we use to primarily name our adapter is either the superclass, or if it is Object (meaning we're
         // just implementing interfaces or extending Object), then the first implemented interface or Object.
@@ -1086,10 +1134,7 @@
      */
     private void gatherMethods(final Class<?> type) throws AdaptationException {
         if (Modifier.isPublic(type.getModifiers())) {
-            final Module module = type.getModule();
-            if (module != null) {
-                accessedModules.add(module);
-            }
+            addAccessedModule(type.getModule());
 
             final Method[] typeMethods = type.isInterface() ? type.getMethods() : type.getDeclaredMethods();
 
@@ -1117,16 +1162,12 @@
 
                     for (final Class<?> pt : typeMethod.getParameterTypes()) {
                         if (pt.isPrimitive()) continue;
-                        final Module ptMod = pt.getModule();
-                        if (ptMod != null) {
-                            accessedModules.add(ptMod);
-                        }
+                        addAccessedModule(pt.getModule());
                     }
 
                     final Class<?> rt = typeMethod.getReturnType();
                     if (!rt.isPrimitive()) {
-                        final Module rtMod = rt.getModule();
-                        if (rtMod != null) accessedModules.add(rtMod);
+                        addAccessedModule(rt.getModule());
                     }
 
                     final MethodInfo mi = new MethodInfo(typeMethod);
@@ -1211,7 +1252,95 @@
         return e.isAnnotationPresent(CallerSensitive.class);
     }
 
-    private static final Call lookupServiceMethod(final String name, final Class<?> rtype, final Class<?>... ptypes) {
+    private static Call lookupServiceMethod(final String name, final Class<?> rtype, final Class<?>... ptypes) {
         return staticCallNoLookup(JavaAdapterServices.class, name, rtype, ptypes);
     }
+
+    /*
+     * Generate a class that adds module read edges from adapter module to the
+     * modules of the reference types used by the generated adapter class.
+     */
+    private static byte[] generateModulesReadAdderClass() {
+        final ClassWriter cw = new ClassWriter(0);
+        MethodVisitor mv;
+
+        // make the class package private
+        cw.visit(Opcodes.V1_7, ACC_SUPER | ACC_FINAL, MODULES_READ_ADDER_INTERNAL,
+            null, "java/lang/Object", null);
+
+        // private static final Module MY_MODULE;
+        {
+            FieldVisitor fv = cw.visitField(ACC_PRIVATE | ACC_FINAL | ACC_STATIC,
+                "MY_MODULE", "Ljava/lang/reflect/Module;", null, null);
+            fv.visitEnd();
+        }
+
+        /*
+         * private static void addReads(Module[] modules) {
+         *     for (Module m : mods) {
+         *         MY_MODULE.addRead(m);
+         *     }
+         * }
+         */
+        {
+            mv = cw.visitMethod(ACC_PRIVATE | ACC_STATIC,
+                MODULES_ADD_READS,
+                "([Ljava/lang/reflect/Module;)V", null, null);
+            mv.visitCode();
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitVarInsn(ASTORE, 1);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitInsn(ARRAYLENGTH);
+            mv.visitVarInsn(ISTORE, 2);
+            mv.visitInsn(ICONST_0);
+            mv.visitVarInsn(ISTORE, 3);
+            Label l0 = new Label();
+            mv.visitLabel(l0);
+            mv.visitFrame(Opcodes.F_APPEND, 3,
+                new Object[]{"[Ljava/lang/reflect/Module;",
+                Opcodes.INTEGER, Opcodes.INTEGER}, 0, null);
+            mv.visitVarInsn(ILOAD, 3);
+            mv.visitVarInsn(ILOAD, 2);
+            Label l1 = new Label();
+            mv.visitJumpInsn(IF_ICMPGE, l1);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitVarInsn(ILOAD, 3);
+            mv.visitInsn(AALOAD);
+            mv.visitVarInsn(ASTORE, 4);
+            mv.visitFieldInsn(GETSTATIC, MODULES_READ_ADDER_INTERNAL,
+                "MY_MODULE", "Ljava/lang/reflect/Module;");
+            mv.visitVarInsn(ALOAD, 4);
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/Module",
+                "addReads", "(Ljava/lang/reflect/Module;)Ljava/lang/reflect/Module;", false);
+            mv.visitInsn(POP);
+            mv.visitIincInsn(3, 1);
+            mv.visitJumpInsn(GOTO, l0);
+            mv.visitLabel(l1);
+            mv.visitFrame(Opcodes.F_CHOP, 3, null, 0, null);
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(2, 5);
+            mv.visitEnd();
+        }
+
+        /*
+         * static {
+         *      MY_MODULE = ThisClass.class.getModule();
+         * }
+         */
+        {
+            mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
+            mv.visitCode();
+            mv.visitLdcInsn(Type.getType("L" + MODULES_READ_ADDER_INTERNAL + ";"));
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class",
+                "getModule", "()Ljava/lang/reflect/Module;", false);
+            mv.visitFieldInsn(PUTSTATIC, MODULES_READ_ADDER_INTERNAL,
+                "MY_MODULE", "Ljava/lang/reflect/Module;");
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(1, 0);
+            mv.visitEnd();
+        }
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Thu Jun 02 21:14:32 2016 +0000
@@ -25,6 +25,9 @@
 
 package jdk.nashorn.internal.runtime.linker;
 
+import java.lang.module.ModuleDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.lang.reflect.Module;
 import java.security.AccessControlContext;
 import java.security.AccessController;
@@ -42,7 +45,6 @@
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.internal.module.Modules;
 
 /**
  * This class encapsulates the bytecode of the adapter class and can be used to load it into the JVM as an actual Class.
@@ -52,14 +54,12 @@
  * class are normally created by {@code JavaAdapterBytecodeGenerator}.
  */
 final class JavaAdapterClassLoader {
-    private static final Module nashornModule = JavaAdapterClassLoader.class.getModule();
-    private static final Set<String> adapterPkgs = new HashSet<>();
-    static {
-        adapterPkgs.add(JavaAdapterBytecodeGenerator.ADAPTER_PACKAGE);
-    }
+    private static final Module NASHORN_MODULE = Context.class.getModule();
 
     private static final AccessControlContext CREATE_LOADER_ACC_CTXT = ClassAndLoader.createPermAccCtxt("createClassLoader");
     private static final AccessControlContext GET_CONTEXT_ACC_CTXT = ClassAndLoader.createPermAccCtxt(Context.NASHORN_GET_CONTEXT);
+    private static final AccessControlContext CREATE_MODULE_ACC_CTXT = ClassAndLoader.createPermAccCtxt(Context.NASHORN_CREATE_MODULE);
+
     private static final Collection<String> VISIBLE_INTERNAL_CLASS_NAMES = Collections.unmodifiableCollection(new HashSet<>(
             Arrays.asList(JavaAdapterServices.class.getName(), ScriptObject.class.getName(), ScriptFunction.class.getName(), JSType.class.getName())));
 
@@ -93,12 +93,19 @@
         }, CREATE_LOADER_ACC_CTXT);
     }
 
-    private static void addExports(final Module from, final String pkg, final Module to) {
-        if (to == null) {
-            Modules.addExportsToAll(from, pkg);
-        } else {
-            Modules.addExports(from, pkg, to);
-        }
+    private static Module createAdapterModule(final ClassLoader loader) {
+        final ModuleDescriptor descriptor =
+            new ModuleDescriptor.Builder("jdk.scripting.nashorn.javaadapters")
+                .requires(NASHORN_MODULE.getName())
+                .exports(JavaAdapterBytecodeGenerator.ADAPTER_PACKAGE)
+                .build();
+
+        return AccessController.doPrivileged(new PrivilegedAction<Module>() {
+            @Override
+            public Module run() {
+                return Context.createModule(descriptor, loader);
+            }
+        }, CREATE_MODULE_ACC_CTXT);
     }
 
     // Note that the adapter class is created in the protection domain of the class/interface being
@@ -113,23 +120,44 @@
             private final ClassLoader myLoader = getClass().getClassLoader();
 
             // new adapter module
-            private final Module adapterModule = Modules.defineModule(this, "jdk.scripting.nashorn.javaadapters", adapterPkgs);
+            private final Module adapterModule = createAdapterModule(this);
 
             {
-                // new adapter module exports and read-edges
-                addExports(adapterModule, JavaAdapterBytecodeGenerator.ADAPTER_PACKAGE, null);
-                Modules.addReads(adapterModule, nashornModule);
-                Modules.addReads(adapterModule, Object.class.getModule());
-                for (Module mod : accessedModules) {
-                    Modules.addReads(adapterModule, mod);
+                // new adapter module read-edges
+                if (!accessedModules.isEmpty()) {
+
+                    // There are modules accessed from this adapter. We need to add module-read
+                    // edges to those from the adapter module. We do this by generating a
+                    // package-private class, loading it with this adapter class loader and
+                    // then calling a private static method on it.
+                    final byte[] buf = JavaAdapterBytecodeGenerator.getModulesAddReadsBytes();
+                    final Class<?> addReader = defineClass(
+                        JavaAdapterBytecodeGenerator.MODULES_READ_ADDER, buf, 0, buf.length);
+                    final PrivilegedAction<Method> pa = () -> {
+                        try {
+                            final Method m = addReader.getDeclaredMethod(
+                                JavaAdapterBytecodeGenerator.MODULES_ADD_READS, Module[].class);
+                            m.setAccessible(true);
+                            return m;
+                        } catch (final NoSuchMethodException | SecurityException ex) {
+                            throw new RuntimeException(ex);
+                        }
+                    };
+                    final Method addReads = AccessController.doPrivileged(pa);
+                    try {
+                        addReads.invoke(null, (Object)accessedModules.toArray(new Module[0]));
+                    } catch (final IllegalAccessException | IllegalArgumentException |
+                            InvocationTargetException ex) {
+                        throw new RuntimeException(ex);
+                    }
                 }
 
                 // specific exports from nashorn to the new adapter module
-                nashornModule.addExports("jdk.nashorn.internal.runtime", adapterModule);
-                nashornModule.addExports("jdk.nashorn.internal.runtime.linker", adapterModule);
+                NASHORN_MODULE.addExports("jdk.nashorn.internal.runtime", adapterModule);
+                NASHORN_MODULE.addExports("jdk.nashorn.internal.runtime.linker", adapterModule);
 
                 // nashorn should be be able to read methods of classes loaded in adapter module
-                nashornModule.addReads(adapterModule);
+                NASHORN_MODULE.addReads(adapterModule);
             }
 
             @Override
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java	Thu Jun 02 20:33:36 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java	Thu Jun 02 21:14:32 2016 +0000
@@ -27,7 +27,6 @@
 
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.Modifier;
-import jdk.internal.module.Modules;
 import jdk.dynalink.CallSiteDescriptor;
 import jdk.dynalink.NamedOperation;
 import jdk.dynalink.StandardOperation;
@@ -93,7 +92,6 @@
                         NashornCallSiteDescriptor.getLookupInternal(request.getCallSiteDescriptor());
 
                 args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass }, null, lookup);
-                Modules.addReads(lookup.lookupClass().getModule(), ((StaticClass)args[0]).getRepresentedClass().getModule());
                 final LinkRequest adapterRequest = request.replaceArguments(request.getCallSiteDescriptor(), args);
                 final GuardedInvocation gi = checkNullConstructor(delegate(linkerServices, adapterRequest), receiverClass);
                 // Finally, modify the guard to test for the original abstract class.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/scripts/ModuleGraphManipulator.java	Thu Jun 02 21:14:32 2016 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package jdk.nashorn.internal.scripts;
+
+import java.lang.reflect.Module;
+import jdk.nashorn.api.scripting.JSObject;
+
+/**
+ * Nashorn's StructureLoader and ScriptLoader instances load
+ * this class in the respective dynamic modules created. This
+ * class is never loaded by Nashorn's own class loader. The
+ * .class bytes of this class are loaded as resource by the
+ * {@link jdk.nashorn.internal.runtime.NashornLoader} class. This class
+ * exists in this package because nashorn structures and scripts
+ * modules use this package name for the only exported package
+ * from those modules.
+ *
+ * Note that this class may be dynamically generated at runtime.
+ * But, this java source is used for ease of reading.
+ */
+final class ModuleGraphManipulator {
+    private ModuleGraphManipulator() {}
+
+    private static final Module MY_MODULE;
+    private static final String MY_PKG_NAME;
+
+    static {
+        final Class<?> myClass = ModuleGraphManipulator.class;
+        MY_MODULE = myClass.getModule();
+        final String myName = myClass.getName();
+        MY_PKG_NAME = myName.substring(0, myName.lastIndexOf('.'));
+
+        // nashorn's module is the module of the class loader of current class
+        final Module nashornModule = myClass.getClassLoader().getClass().getModule();
+
+        // Make sure this class was not loaded by Nashorn's own loader!
+        if (MY_MODULE == nashornModule) {
+            throw new IllegalStateException(myClass + " loaded by wrong loader!");
+        }
+
+        // From this module add a qualified export to nashorn module
+        MY_MODULE.addExports(MY_PKG_NAME, nashornModule);
+    }
+
+    // The following method is reflectively invoked from Nashorn
+    // to add required module export edges. Because this package
+    // itself is qualified exported only to nashorn and this
+    // method is private, unsafe calls are not possible.
+
+    private static void addExport(final Module otherMod) {
+        MY_MODULE.addExports(MY_PKG_NAME, otherMod);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8158467.js	Thu Jun 02 21:14:32 2016 +0000
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/**
+ * JDK-8158467: AccessControlException is thrown on public Java class access if "script app loader" is set to null
+ *
+ * @option -scripting
+ * @test
+ * @run
+ */
+
+var Factory = Java.type("jdk.nashorn.api.scripting.NashornScriptEngineFactory");
+var fac = new Factory();
+
+// This script has to be given RuntimePermission("nashorn.setConfig")
+var e = fac["getScriptEngine(java.lang.ClassLoader)"](null);
+
+print(e.eval("java.lang.System"));
+print(e.eval("({ foo: 42})").foo);
+print((e.eval("function(x) x*x"))(31));
+
+e.put("output", print);
+var runnable = e.eval(<<EOF
+    new java.lang.Runnable() {
+        run: function() {
+            output("hello Runnable");
+        }
+    }
+EOF);
+
+runnable.run();
+
+var obj = e.eval(<<EOF
+new (Java.extend(Java.type("java.lang.Object"))) {
+    hashCode: function() 33,
+    toString: function() "I'm object"
+}
+EOF);
+
+print(obj.hashCode());
+print(obj.toString());
+
+// should throw SecurityException!
+try {
+    e.eval("Packages.jdk.internal");
+} catch (ex) {
+    print(ex);
+}
+
+// should throw SecurityException!
+try {
+    e.eval("Java.type('jdk.internal.misc.Unsafe')");
+} catch (ex) {
+    print(ex);
+}
+
+// should throw SecurityException!
+try {
+    e.eval("Java.type('jdk.nashorn.internal.Context')");
+} catch (ex) {
+    print(ex);
+}
+
+// should throw ClassNotFoundException as null is script
+// "app loader" [and not platform loader which loads nashorn]
+e.eval(<<EOF
+try {
+    Java.type('jdk.nashorn.api.scripting.JSObject');
+} catch (ex) {
+    output(ex);
+}
+EOF);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8158467.js.EXPECTED	Thu Jun 02 21:14:32 2016 +0000
@@ -0,0 +1,10 @@
+[JavaClass java.lang.System]
+42
+961
+hello Runnable
+33
+I'm object
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.jdk.internal")
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.jdk.internal.misc")
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.jdk.nashorn.internal")
+java.lang.ClassNotFoundException: jdk.nashorn.api.scripting.JSObject