8211825: ModuleLayer.defineModulesWithXXX does not setup delegation when module reads automatic module

Reviewed-by: mchung
This commit is contained in:
Alan Bateman 2018-10-09 07:06:32 +01:00
parent 61f453edf7
commit cb3fe46b95
7 changed files with 283 additions and 25 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2018, 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
@ -477,7 +477,7 @@ public final class Module implements AnnotatedElement {
*
* @see ModuleDescriptor#opens()
* @see #addOpens(String,Module)
* @see AccessibleObject#setAccessible(boolean)
* @see java.lang.reflect.AccessibleObject#setAccessible(boolean)
* @see java.lang.invoke.MethodHandles#privateLookupIn
*/
public boolean isOpen(String pn, Module other) {
@ -747,7 +747,7 @@ public final class Module implements AnnotatedElement {
* package to at least the caller's module
*
* @see #isOpen(String,Module)
* @see AccessibleObject#setAccessible(boolean)
* @see java.lang.reflect.AccessibleObject#setAccessible(boolean)
* @see java.lang.invoke.MethodHandles#privateLookupIn
*/
@CallerSensitive
@ -1061,7 +1061,10 @@ public final class Module implements AnnotatedElement {
* @return a map of module name to runtime {@code Module}
*
* @throws IllegalArgumentException
* If defining any of the modules to the VM fails
* If the function maps a module to the null or platform class loader
* @throws IllegalStateException
* If the module cannot be defined to the VM or its packages overlap
* with another module mapped to the same class loader
*/
static Map<String, Module> defineModules(Configuration cf,
Function<String, ClassLoader> clf,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2018, 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
@ -198,7 +198,6 @@ public final class Loader extends SecureClassLoader {
this.acc = AccessController.getContext();
}
/**
* Completes initialization of this Loader. This method populates
* remotePackageToLoader with the packages of the remote modules, where
@ -253,25 +252,25 @@ public final class Loader extends SecureClassLoader {
}
// find the packages that are exported to the target module
String target = resolvedModule.name();
ModuleDescriptor descriptor = other.reference().descriptor();
for (ModuleDescriptor.Exports e : descriptor.exports()) {
boolean delegate;
if (e.isQualified()) {
// qualified export in same configuration
delegate = (other.configuration() == cf)
&& e.targets().contains(target);
} else {
// unqualified
delegate = true;
}
if (descriptor.isAutomatic()) {
ClassLoader l = loader;
descriptor.packages().forEach(pn -> remotePackage(pn, l));
} else {
String target = resolvedModule.name();
for (ModuleDescriptor.Exports e : descriptor.exports()) {
boolean delegate;
if (e.isQualified()) {
// qualified export in same configuration
delegate = (other.configuration() == cf)
&& e.targets().contains(target);
} else {
// unqualified
delegate = true;
}
if (delegate) {
String pn = e.source();
ClassLoader l = remotePackageToLoader.putIfAbsent(pn, loader);
if (l != null && l != loader) {
throw new IllegalArgumentException("Package "
+ pn + " cannot be imported from multiple loaders");
if (delegate) {
remotePackage(e.source(), loader);
}
}
}
@ -282,6 +281,22 @@ public final class Loader extends SecureClassLoader {
return this;
}
/**
* Adds to remotePackageToLoader so that an attempt to load a class in
* the package delegates to the given class loader.
*
* @throws IllegalStateException
* if the package is already mapped to a different class loader
*/
private void remotePackage(String pn, ClassLoader loader) {
ClassLoader l = remotePackageToLoader.putIfAbsent(pn, loader);
if (l != null && l != loader) {
throw new IllegalStateException("Package "
+ pn + " cannot be imported from multiple loaders");
}
}
/**
* Find the layer corresponding to the given configuration in the tree
* of layers rooted at the given parent.

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2018, 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
@ -46,7 +46,7 @@ public final class LoaderPool {
/**
* Creates a pool of class loaders. Each module in the given configuration
* will be loaded its own class loader in the pool. The class loader is
* is mapped to its own class loader in the pool. The class loader is
* created with the given parent class loader as its parent.
*/
public LoaderPool(Configuration cf,