mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-02 11:10:06 +00:00
8158338: Nashorn's ScriptLoader split delegation has to be adjusted
Reviewed-by: lagergren, hannesw
This commit is contained in:
parent
5f49606225
commit
3c9941bd80
@ -486,6 +486,11 @@ public final class Context {
|
||||
/** 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;
|
||||
|
||||
@ -501,12 +506,13 @@ public final class Context {
|
||||
/** Optional class filter to use for Java classes. Can be null. */
|
||||
private final ClassFilter classFilter;
|
||||
|
||||
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() {
|
||||
@ -526,7 +532,7 @@ public final class Context {
|
||||
|
||||
static {
|
||||
final ClassLoader myLoader = Context.class.getClassLoader();
|
||||
sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
|
||||
theStructLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
|
||||
@Override
|
||||
public StructureLoader run() {
|
||||
return new StructureLoader(myLoader);
|
||||
@ -1038,7 +1044,7 @@ public final class Context {
|
||||
}
|
||||
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);
|
||||
}
|
||||
@ -1191,7 +1197,7 @@ public final class Context {
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1551,7 +1557,7 @@ public final class Context {
|
||||
new PrivilegedAction<ScriptLoader>() {
|
||||
@Override
|
||||
public ScriptLoader run() {
|
||||
return new ScriptLoader(appLoader, Context.this);
|
||||
return new ScriptLoader(Context.this);
|
||||
}
|
||||
}, CREATE_LOADER_ACC_CTXT);
|
||||
}
|
||||
|
||||
@ -38,8 +38,8 @@ final class ScriptLoader extends NashornLoader {
|
||||
private static final String NASHORN_PKG_PREFIX = "jdk.nashorn.internal.";
|
||||
|
||||
private volatile boolean structureAccessAdded;
|
||||
private final Module scriptModule;
|
||||
private final Context context;
|
||||
private final Module scriptModule;
|
||||
|
||||
/*package-private*/ Context getContext() {
|
||||
return context;
|
||||
@ -48,8 +48,8 @@ final class ScriptLoader extends NashornLoader {
|
||||
/**
|
||||
* 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
|
||||
@ -67,7 +67,7 @@ final class ScriptLoader extends NashornLoader {
|
||||
}
|
||||
|
||||
private Module createModule(final String moduleName) {
|
||||
final Module structMod = context.getSharedLoader().getModule();
|
||||
final Module structMod = context.getStructLoader().getModule();
|
||||
final ModuleDescriptor descriptor
|
||||
= new ModuleDescriptor.Builder(moduleName)
|
||||
.requires(NASHORN_MODULE.getName())
|
||||
@ -80,20 +80,45 @@ final class ScriptLoader extends NashornLoader {
|
||||
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 && cl.getClassLoader() == sharedCl) {
|
||||
final Class<?> cl = super.loadClass(name, resolve);
|
||||
if (!structureAccessAdded) {
|
||||
final StructureLoader structLoader = context.getStructLoader();
|
||||
if (cl.getClassLoader() == structLoader) {
|
||||
structureAccessAdded = true;
|
||||
sharedCl.addModuleExport(scriptModule);
|
||||
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user