8150668: Layer.defineModulesXXX with a Configuration containing java.base throws undocumented exception

Reviewed-by: chegar, mchung
This commit is contained in:
Alan Bateman 2016-05-25 19:58:03 +01:00
parent 600aaed0a7
commit 53e204dc49
4 changed files with 106 additions and 52 deletions

View File

@ -75,11 +75,12 @@ import sun.security.util.SecurityConstants;
*
* <p> A Java virtual machine has at least one non-empty layer, the {@link
* #boot() boot} layer, that is created when the Java virtual machine is
* started. The <em>system modules</em>, including {@code java.base}, are in
* the boot layer. The modules in the boot layer are mapped to the bootstrap
* class loader and other class loaders that are built-in into the Java virtual
* machine. The boot layer will often be the {@link #parent() parent} when
* creating additional layers. </p>
* started. The boot layer contains module {@code java.base} and is the only
* layer in the Java virtual machine with a module named "{@code java.base}".
* The modules in the boot layer are mapped to the bootstrap class loader and
* other class loaders that are <a href="../ClassLoader.html#builtinLoaders">
* built-in</a> into the Java virtual machine. The boot layer will often be
* the {@link #parent() parent} when creating additional layers. </p>
*
* <p> As when creating a {@code Configuration},
* {@link ModuleDescriptor#isAutomatic() automatic} modules receive
@ -204,7 +205,8 @@ public final class Layer {
* for this layer
* @throws LayerInstantiationException
* If all modules cannot be defined to the same class loader for any
* of the reasons listed above
* of the reasons listed above or the layer cannot be created because
* the configuration contains a module named "{@code java.base}"
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
@ -219,14 +221,13 @@ public final class Layer {
checkCreateClassLoaderPermission();
checkGetClassLoaderPermission();
Loader loader;
try {
loader = new Loader(cf.modules(), parentLoader);
Loader loader = new Loader(cf.modules(), parentLoader);
loader.initRemotePackageMap(cf, this);
return new Layer(cf, this, mn -> loader);
} catch (IllegalArgumentException e) {
throw new LayerInstantiationException(e.getMessage());
}
return new Layer(cf, this, mn -> loader);
}
@ -266,6 +267,9 @@ public final class Layer {
* @throws IllegalArgumentException
* If the parent of the given configuration is not the configuration
* for this layer
* @throws LayerInstantiationException
* If the layer cannot be created because the configuration contains
* a module named "{@code java.base}"
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
@ -281,7 +285,11 @@ public final class Layer {
checkGetClassLoaderPermission();
LoaderPool pool = new LoaderPool(cf, this, parentLoader);
return new Layer(cf, this, pool::loaderFor);
try {
return new Layer(cf, this, pool::loaderFor);
} catch (IllegalArgumentException e) {
throw new LayerInstantiationException(e.getMessage());
}
}
@ -330,7 +338,8 @@ public final class Layer {
* for this layer
* @throws LayerInstantiationException
* If creating the {@code Layer} fails for any of the reasons
* listed above
* listed above or the layer cannot be created because the
* configuration contains a module named "{@code java.base}"
* @throws SecurityException
* If {@code RuntimePermission("getClassLoader")} is denied by
* the security manager

View File

@ -513,7 +513,7 @@ public final class Module {
* package {@code pn} to the given module.
*
* <p> This method has no effect if the package is already exported to the
* given module. If also has no effect if invoked on an unnamed module (as
* given module. It also has no effect if invoked on an unnamed module (as
* unnamed modules export all packages). </p>
*
* @param pn
@ -866,7 +866,7 @@ public final class Module {
URI uri = mref.location().orElse(null);
Module m;
if (loader == null && name.equals("java.base")) {
if (loader == null && name.equals("java.base") && Layer.boot() == null) {
m = Object.class.getModule();
} else {
m = new Module(layer, loader, descriptor, uri);

View File

@ -103,7 +103,7 @@ public class BasicLayerTest {
/**
* Exercise Layer.create, created on an empty layer
* Exercise Layer defineModules, created with empty layer as parent
*/
public void testLayerOnEmpty() {
ModuleDescriptor descriptor1
@ -184,7 +184,7 @@ public class BasicLayerTest {
/**
* Exercise Layer.create, created over the boot layer
* Exercise Layer defineModules, created with boot layer as parent
*/
public void testLayerOnBoot() {
ModuleDescriptor descriptor1
@ -247,8 +247,8 @@ public class BasicLayerTest {
/**
* Layer.create with a configuration of two modules that have the same
* module-private package.
* Exercise Layer defineModules with a configuration of two modules that
* have the same module-private package.
*/
public void testSameConcealedPackage() {
ModuleDescriptor descriptor1
@ -281,8 +281,8 @@ public class BasicLayerTest {
/**
* Layer.create with a configuration with a partitioned graph. The same
* package is exported in both partitions.
* Exercise Layer defineModules with a configuration that is a partitioned
* graph. The same package is exported in both partitions.
*/
public void testSameExportInPartitionedGraph() {
@ -338,9 +338,9 @@ public class BasicLayerTest {
/**
* Layer.create with a configuration that contains a module that has a
* concealed package that is the same name as a non-exported package
* in a parent layer.
* Exercise Layer defineModules with a configuration that contains a module
* that has a concealed package that is the same name as a non-exported
* package in a parent layer.
*/
public void testConcealSamePackageAsBootLayer() {
@ -667,9 +667,9 @@ public class BasicLayerTest {
/**
* Attempt to use Layer.create to create a layer with a module defined to a
* class loader that already has a module of the same name defined to the
* class loader.
* Attempt to use Layer defineModules to create a layer with a module
* defined to a class loader that already has a module of the same name
* defined to the class loader.
*/
@Test(expectedExceptions = { LayerInstantiationException.class })
public void testModuleAlreadyDefinedToLoader() {
@ -696,9 +696,9 @@ public class BasicLayerTest {
/**
* Attempt to use Layer.create to create a Layer with a module containing
* package {@code p} where the class loader already has a module defined
* to it containing package {@code p}.
* Attempt to use Layer defineModules to create a Layer with a module
* containing package {@code p} where the class loader already has a module
* defined to it containing package {@code p}.
*/
@Test(expectedExceptions = { LayerInstantiationException.class })
public void testPackageAlreadyInNamedModule() {
@ -738,8 +738,9 @@ public class BasicLayerTest {
/**
* Attempt to use Layer.create to create a Layer with a module containing
* a package in which a type is already loaded by the class loader.
* Attempt to use Layer defineModules to create a Layer with a module
* containing a package in which a type is already loaded by the class
* loader.
*/
@Test(expectedExceptions = { LayerInstantiationException.class })
public void testPackageAlreadyInUnnamedModule() throws Exception {
@ -762,6 +763,46 @@ public class BasicLayerTest {
}
/**
* Attempt to create a Layer with a module named "java.base".
*/
public void testLayerWithJavaBase() {
ModuleDescriptor descriptor
= new ModuleDescriptor.Builder("java.base")
.exports("java.lang")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor);
Configuration cf = Layer.boot()
.configuration()
.resolveRequires(finder, ModuleFinder.of(), Set.of("java.base"));
assertTrue(cf.modules().size() == 1);
ClassLoader scl = ClassLoader.getSystemClassLoader();
try {
Layer.boot().defineModules(cf, loader -> null );
assertTrue(false);
} catch (LayerInstantiationException e) { }
try {
Layer.boot().defineModules(cf, loader -> new ClassLoader() { });
assertTrue(false);
} catch (LayerInstantiationException e) { }
try {
Layer.boot().defineModulesWithOneLoader(cf, scl);
assertTrue(false);
} catch (LayerInstantiationException e) { }
try {
Layer.boot().defineModulesWithManyLoaders(cf, scl);
assertTrue(false);
} catch (LayerInstantiationException e) { }
}
/**
* Parent of configuration != configuration of parent Layer
*/
@ -812,7 +853,6 @@ public class BasicLayerTest {
@Test(expectedExceptions = { NullPointerException.class })
public void testCreateWithNull2() {
ClassLoader loader = new ClassLoader() { };
Configuration cf = resolveRequires(Layer.boot().configuration(), ModuleFinder.of());
Layer.boot().defineModules(cf, null);
}

View File

@ -70,7 +70,7 @@ public class LayerAndLoadersTest {
/**
* Basic test of Layer.defineModulesWithOneLoader
* Basic test of Layer defineModulesWithOneLoader
*
* Test scenario:
* m1 requires m2 and m3
@ -99,7 +99,7 @@ public class LayerAndLoadersTest {
/**
* Basic test of Layer.defineModulesWithManyLoaders
* Basic test of Layer defineModulesWithManyLoaders
*
* Test scenario:
* m1 requires m2 and m3
@ -131,7 +131,7 @@ public class LayerAndLoadersTest {
/**
* Basic test of Layer.defineModulesWithOneLoader where one of the modules
* Basic test of Layer defineModulesWithOneLoader where one of the modules
* is a service provider module.
*
* Test scenario:
@ -172,8 +172,8 @@ public class LayerAndLoadersTest {
/**
* Basic test of Layer.defineModulesWithManyLoaders where one of the modules
* is a service provider module.
* Basic test of Layer defineModulesWithManyLoaders where one of the
* modules is a service provider module.
*
* Test scenario:
* m1 requires m2 and m3
@ -224,7 +224,7 @@ public class LayerAndLoadersTest {
/**
* Tests that the class loaders created by Layer.createWithXXX delegate
* Tests that the class loaders created by defineModulesWithXXX delegate
* to the given parent class loader.
*/
public void testDelegationToParent() throws Exception {
@ -254,7 +254,7 @@ public class LayerAndLoadersTest {
/**
* Test Layer.createWithXXX when modules that have overlapping packages.
* Test defineModulesWithXXX when modules that have overlapping packages.
*
* Test scenario:
* m1 exports p
@ -288,7 +288,7 @@ public class LayerAndLoadersTest {
/**
* Test Layer.createWithXXX with split delegation.
* Test Layer defineModulesWithXXX with split delegation.
*
* Test scenario:
* layer1: m1 exports p, m2 exports p
@ -319,7 +319,8 @@ public class LayerAndLoadersTest {
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
Configuration cf2 = cf1.resolveRequires(finder2, ModuleFinder.of(), Set.of("m3", "m4"));
Configuration cf2 = cf1.resolveRequires(finder2, ModuleFinder.of(),
Set.of("m3", "m4"));
// package p cannot be supplied by two class loaders
try {
@ -335,8 +336,8 @@ public class LayerAndLoadersTest {
/**
* Test Layer.createWithXXX when the modules that override same named
* modules in the parent layer.
* Test Layer defineModulesWithXXX when the modules that override same
* named modules in the parent layer.
*
* Test scenario:
* layer1: m1, m2, m3 => same loader
@ -350,7 +351,8 @@ public class LayerAndLoadersTest {
checkLayer(layer1, "m1", "m2", "m3");
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
Set.of("m1"));
Layer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
checkLayer(layer2, "m1", "m2", "m3");
@ -383,8 +385,8 @@ public class LayerAndLoadersTest {
/**
* Test Layer.createWithXXX when the modules that override same named
* modules in the parent layer.
* Test Layer defineModulesWithXXX when the modules that override same
* named modules in the parent layer.
*
* Test scenario:
* layer1: m1, m2, m3 => loader pool
@ -398,7 +400,8 @@ public class LayerAndLoadersTest {
checkLayer(layer1, "m1", "m2", "m3");
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
Set.of("m1"));
Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
checkLayer(layer2, "m1", "m2", "m3");
@ -477,8 +480,8 @@ public class LayerAndLoadersTest {
/**
* Test Layer.createWithXXX when the modules that override same named
* modules in the parent layer.
* Test Layer defineModulesWithXXX when the modules that override same
* named modules in the parent layer.
*
* layer1: m1, m2, m3 => same loader
* layer2: m1, m3 => same loader
@ -492,7 +495,8 @@ public class LayerAndLoadersTest {
ModuleFinder finder = finderFor("m1", "m3");
Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
Set.of("m1"));
Layer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
checkLayer(layer2, "m1", "m3");
@ -513,8 +517,8 @@ public class LayerAndLoadersTest {
/**
* Test Layer.createWithXXX when the modules that override same named
* modules in the parent layer.
* Test Layer defineModulesWithXXX when the modules that override same
* named modules in the parent layer.
*
* layer1: m1, m2, m3 => loader pool
* layer2: m1, m3 => loader pool
@ -528,7 +532,8 @@ public class LayerAndLoadersTest {
ModuleFinder finder = finderFor("m1", "m3");
Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
Set.of("m1"));
Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
checkLayer(layer2, "m1", "m3");