Merge
authoralanb
Wed, 25 May 2016 20:26:43 +0100
changeset 38566 6a1386b76fdd
parent 38565 e97761823da2 (diff)
parent 38563 3ab5f00bd5a3 (current diff)
child 38567 6d4c5a278fff
child 38997 737cce90a6d4
Merge
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java	Wed May 25 20:04:57 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java	Wed May 25 20:26:43 2016 +0100
@@ -30,6 +30,7 @@
 import java.io.InputStream;
 import java.net.URI;
 import java.nio.ByteBuffer;
+import java.util.Objects;
 import java.util.Optional;
 
 
@@ -163,9 +164,12 @@
      * @param  bb
      *         The byte buffer to release
      *
-     * @implSpec The default implementation does nothing.
+     * @implSpec The default implementation doesn't do anything except check
+     * if the byte buffer is null.
      */
-    default void release(ByteBuffer bb) { }
+    default void release(ByteBuffer bb) {
+        Objects.requireNonNull(bb);
+    }
 
     /**
      * Closes the module reader. Once closed then subsequent calls to locate or
--- a/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java	Wed May 25 20:04:57 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java	Wed May 25 20:26:43 2016 +0100
@@ -272,9 +272,9 @@
          * if not found.
          */
         private ImageLocation findImageLocation(String name) throws IOException {
+            Objects.requireNonNull(name);
             if (closed)
                 throw new IOException("ModuleReader is closed");
-
             if (imageReader != null) {
                 return imageReader.findLocation(module, name);
             } else {
@@ -322,6 +322,7 @@
 
         @Override
         public void release(ByteBuffer bb) {
+            Objects.requireNonNull(bb);
             ImageReader.releaseByteBuffer(bb);
         }
 
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Layer.java	Wed May 25 20:04:57 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Layer.java	Wed May 25 20:26:43 2016 +0100
@@ -75,11 +75,12 @@
  *
  * <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 @@
      *         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 @@
         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 @@
      * @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 @@
         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 @@
      *         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
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Module.java	Wed May 25 20:04:57 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Module.java	Wed May 25 20:26:43 2016 +0100
@@ -513,7 +513,7 @@
      * 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 @@
             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);
--- a/jdk/test/java/lang/module/ModuleReader/ModuleReaderTest.java	Wed May 25 20:04:57 2016 +0100
+++ b/jdk/test/java/lang/module/ModuleReader/ModuleReaderTest.java	Wed May 25 20:26:43 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -38,6 +38,7 @@
 import java.lang.module.ModuleFinder;
 import java.lang.module.ModuleReader;
 import java.lang.module.ModuleReference;
+import java.lang.reflect.Module;
 import java.net.URI;
 import java.net.URL;
 import java.net.URLConnection;
@@ -64,16 +65,24 @@
     private static final Path SRC_DIR    = Paths.get(TEST_SRC, "src");
     private static final Path MODS_DIR   = Paths.get("mods");
 
+    // the module name of the base module
+    private static final String BASE_MODULE = "java.base";
+
     // the module name of the test module
     private static final String TEST_MODULE = "m";
 
+    // resources in the base module
+    private static final String[] BASE_RESOURCES = {
+        "java/lang/Object.class"
+    };
+
     // resources in test module (can't use module-info.class as a test
     // resource as it will be modified by the jmod tool)
-    private static final String[] RESOURCES = {
+    private static final String[] TEST_RESOURCES = {
         "p/Main.class"
     };
 
-    // a resource that is not in the test module
+    // a resource that is not in the base or test module
     private static final String NOT_A_RESOURCE = "NotAResource";
 
 
@@ -89,7 +98,74 @@
 
 
     /**
-     * Test exploded module
+     * Test ModuleReader to module in runtime image
+     */
+    public void testImage() throws Exception {
+
+        ModuleFinder finder = ModuleFinder.ofSystem();
+        ModuleReference mref = finder.find(BASE_MODULE).get();
+        ModuleReader reader = mref.open();
+
+        try (reader) {
+
+            for (String name : BASE_RESOURCES) {
+                byte[] expectedBytes;
+                Module baseModule = Object.class.getModule();
+                try (InputStream in = baseModule.getResourceAsStream(name)) {
+                    expectedBytes = in.readAllBytes();
+                }
+
+                testFind(reader, name, expectedBytes);
+                testOpen(reader, name, expectedBytes);
+                testRead(reader, name, expectedBytes);
+
+            }
+
+            // test "not found"
+            assertFalse(reader.find(NOT_A_RESOURCE).isPresent());
+            assertFalse(reader.open(NOT_A_RESOURCE).isPresent());
+            assertFalse(reader.read(NOT_A_RESOURCE).isPresent());
+
+
+            // test nulls
+            try {
+                reader.find(null);
+                assertTrue(false);
+            } catch (NullPointerException expected) { }
+
+            try {
+                reader.open(null);
+                assertTrue(false);
+            } catch (NullPointerException expected) { }
+
+            try {
+                reader.read(null);
+                assertTrue(false);
+            } catch (NullPointerException expected) { }
+
+            try {
+                reader.release(null);
+                assertTrue(false);
+            } catch (NullPointerException expected) { }
+
+        }
+
+        // test closed ModuleReader
+        try {
+            reader.open(BASE_RESOURCES[0]);
+            assertTrue(false);
+        } catch (IOException expected) { }
+
+
+        try {
+            reader.read(BASE_RESOURCES[0]);
+            assertTrue(false);
+        } catch (IOException expected) { }
+    }
+
+
+    /**
+     * Test ModuleReader to exploded module
      */
     public void testExplodedModule() throws Exception {
         test(MODS_DIR);
@@ -97,7 +173,7 @@
 
 
     /**
-     * Test modular JAR
+     * Test ModuleReader to modular JAR
      */
     public void testModularJar() throws Exception {
         Path dir = Files.createTempDirectory(USER_DIR, "mlib");
@@ -111,7 +187,7 @@
 
 
     /**
-     * Test JMOD
+     * Test ModuleReader to JMOD
      */
     public void testJMod() throws Exception {
         Path dir = Files.createTempDirectory(USER_DIR, "mlib");
@@ -145,7 +221,7 @@
         try (reader) {
 
             // test each of the known resources in the module
-            for (String name : RESOURCES) {
+            for (String name : TEST_RESOURCES) {
                 byte[] expectedBytes
                     = Files.readAllBytes(MODS_DIR
                         .resolve(TEST_MODULE)
@@ -157,6 +233,7 @@
             }
 
             // test "not found"
+            assertFalse(reader.find(NOT_A_RESOURCE).isPresent());
             assertFalse(reader.open(NOT_A_RESOURCE).isPresent());
             assertFalse(reader.read(NOT_A_RESOURCE).isPresent());
 
@@ -176,19 +253,22 @@
                 assertTrue(false);
             } catch (NullPointerException expected) { }
 
-            // should release(null) throw NPE?
+            try {
+                reader.release(null);
+                throw new RuntimeException();
+            } catch (NullPointerException expected) { }
 
         }
 
         // test closed ModuleReader
         try {
-            reader.open(RESOURCES[0]);
+            reader.open(TEST_RESOURCES[0]);
             assertTrue(false);
         } catch (IOException expected) { }
 
 
         try {
-            reader.read(RESOURCES[0]);
+            reader.read(TEST_RESOURCES[0]);
             assertTrue(false);
         } catch (IOException expected) { }
     }
--- a/jdk/test/java/lang/reflect/Layer/BasicLayerTest.java	Wed May 25 20:04:57 2016 +0100
+++ b/jdk/test/java/lang/reflect/Layer/BasicLayerTest.java	Wed May 25 20:26:43 2016 +0100
@@ -103,7 +103,7 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 {
@@ -763,6 +764,46 @@
 
 
     /**
+     * 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
      */
     @Test(expectedExceptions = { IllegalArgumentException.class })
@@ -812,7 +853,6 @@
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testCreateWithNull2() {
-        ClassLoader loader = new ClassLoader() { };
         Configuration cf = resolveRequires(Layer.boot().configuration(), ModuleFinder.of());
         Layer.boot().defineModules(cf, null);
     }
--- a/jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java	Wed May 25 20:04:57 2016 +0100
+++ b/jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java	Wed May 25 20:26:43 2016 +0100
@@ -70,7 +70,7 @@
 
 
     /**
-     * Basic test of Layer.defineModulesWithOneLoader
+     * Basic test of Layer defineModulesWithOneLoader
      *
      * Test scenario:
      *   m1 requires m2 and m3
@@ -99,7 +99,7 @@
 
 
     /**
-     * Basic test of Layer.defineModulesWithManyLoaders
+     * Basic test of Layer defineModulesWithManyLoaders
      *
      * Test scenario:
      *   m1 requires m2 and m3
@@ -131,7 +131,7 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 @@
 
 
     /**
-     * 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 @@
 
         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 @@
 
 
     /**
-     * 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 @@
         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 @@
 
 
     /**
-     * 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 @@
         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 @@
 
 
     /**
-     * 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 @@
 
         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 @@
 
 
     /**
-     * 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 @@
 
         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");