src/java.base/share/classes/java/lang/ModuleLayer.java
author igerasim
Tue, 11 Sep 2018 14:51:45 -0700
changeset 51703 4ffb0a33f265
parent 51327 a19fda433921
child 54206 003cc64366da
permissions -rw-r--r--
8210347: Combine subsequent calls to Set.contains() and Set.add() Reviewed-by: smarks, bpb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
     1
/*
51703
4ffb0a33f265 8210347: Combine subsequent calls to Set.contains() and Set.add()
igerasim
parents: 51327
diff changeset
     2
 * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
     4
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    10
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    15
 * accompanied this code).
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    16
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    20
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    23
 * questions.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    24
 */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    25
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    26
package java.lang;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    27
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    28
import java.lang.module.Configuration;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    29
import java.lang.module.ModuleDescriptor;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    30
import java.lang.module.ResolvedModule;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    31
import java.util.ArrayDeque;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    32
import java.util.ArrayList;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    33
import java.util.Collections;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    34
import java.util.Deque;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    35
import java.util.HashMap;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    36
import java.util.HashSet;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    37
import java.util.List;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    38
import java.util.Map;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    39
import java.util.Objects;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    40
import java.util.Optional;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    41
import java.util.Set;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    42
import java.util.concurrent.CopyOnWriteArrayList;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    43
import java.util.function.Function;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    44
import java.util.stream.Collectors;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    45
import java.util.stream.Stream;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    46
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    47
import jdk.internal.loader.ClassLoaderValue;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    48
import jdk.internal.loader.Loader;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    49
import jdk.internal.loader.LoaderPool;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    50
import jdk.internal.module.ServicesCatalog;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    51
import sun.security.util.SecurityConstants;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    52
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    53
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    54
/**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    55
 * A layer of modules in the Java virtual machine.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    56
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    57
 * <p> A layer is created from a graph of modules in a {@link Configuration}
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    58
 * and a function that maps each module to a {@link ClassLoader}.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    59
 * Creating a layer informs the Java virtual machine about the classes that
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    60
 * may be loaded from the modules so that the Java virtual machine knows which
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    61
 * module that each class is a member of. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    62
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    63
 * <p> Creating a layer creates a {@link Module} object for each {@link
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    64
 * ResolvedModule} in the configuration. For each resolved module that is
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    65
 * {@link ResolvedModule#reads() read}, the {@code Module} {@link
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    66
 * Module#canRead reads} the corresponding run-time {@code Module}, which may
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    67
 * be in the same layer or a {@link #parents() parent} layer. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    68
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    69
 * <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    70
 * {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    71
 * provide convenient ways to create a module layer where all modules are
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    72
 * mapped to a single class loader or where each module is mapped to its own
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    73
 * class loader. The {@link #defineModules defineModules} method is for more
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    74
 * advanced cases where modules are mapped to custom class loaders by means of
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    75
 * a function specified to the method. Each of these methods has an instance
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    76
 * and static variant. The instance methods create a layer with the receiver
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    77
 * as the parent layer. The static methods are for more advanced cases where
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    78
 * there can be more than one parent layer or where a {@link
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    79
 * ModuleLayer.Controller Controller} is needed to control modules in the layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    80
 * </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    81
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    82
 * <p> A Java virtual machine has at least one non-empty layer, the {@link
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    83
 * #boot() boot} layer, that is created when the Java virtual machine is
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    84
 * started. The boot layer contains module {@code java.base} and is the only
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    85
 * layer in the Java virtual machine with a module named "{@code java.base}".
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    86
 * The modules in the boot layer are mapped to the bootstrap class loader and
45138
ddcafe0d0ea3 8180082: Broken javadoc links
rriggs
parents: 44545
diff changeset
    87
 * other class loaders that are <a href="ClassLoader.html#builtinLoaders">
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    88
 * built-in</a> into the Java virtual machine. The boot layer will often be
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    89
 * the {@link #parents() parent} when creating additional layers. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    90
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    91
 * <p> Each {@code Module} in a layer is created so that it {@link
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    92
 * Module#isExported(String) exports} and {@link Module#isOpen(String) opens}
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    93
 * the packages described by its {@link ModuleDescriptor}. Qualified exports
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    94
 * (where a package is exported to a set of target modules rather than all
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    95
 * modules) are reified when creating the layer as follows: </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    96
 * <ul>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    97
 *     <li> If module {@code X} exports a package to {@code Y}, and if the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    98
 *     runtime {@code Module} {@code X} reads {@code Module} {@code Y}, then
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
    99
 *     the package is exported to {@code Module} {@code Y} (which may be in
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   100
 *     the same layer as {@code X} or a parent layer). </li>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   101
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   102
 *     <li> If module {@code X} exports a package to {@code Y}, and if the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   103
 *     runtime {@code Module} {@code X} does not read {@code Y} then target
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   104
 *     {@code Y} is located as if by invoking {@link #findModule(String)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   105
 *     findModule} to find the module in the layer or its parent layers. If
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   106
 *     {@code Y} is found then the package is exported to the instance of
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   107
 *     {@code Y} that was found. If {@code Y} is not found then the qualified
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   108
 *     export is ignored. </li>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   109
 * </ul>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   110
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   111
 * <p> Qualified opens are handled in same way as qualified exports. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   112
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   113
 * <p> As when creating a {@code Configuration},
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   114
 * {@link ModuleDescriptor#isAutomatic() automatic} modules receive special
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   115
 * treatment when creating a layer. An automatic module is created in the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   116
 * Java virtual machine as a {@code Module} that reads every unnamed {@code
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   117
 * Module} in the Java virtual machine. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   118
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   119
 * <p> Unless otherwise specified, passing a {@code null} argument to a method
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   120
 * in this class causes a {@link NullPointerException NullPointerException} to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   121
 * be thrown. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   122
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   123
 * <h3> Example usage: </h3>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   124
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   125
 * <p> This example creates a configuration by resolving a module named
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   126
 * "{@code myapp}" with the configuration for the boot layer as the parent. It
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   127
 * then creates a new layer with the modules in this configuration. All modules
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   128
 * are defined to the same class loader. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   129
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   130
 * <pre>{@code
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   131
 *     ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   132
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   133
 *     ModuleLayer parent = ModuleLayer.boot();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   134
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   135
 *     Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   136
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   137
 *     ClassLoader scl = ClassLoader.getSystemClassLoader();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   138
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   139
 *     ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   140
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   141
 *     Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   142
 * }</pre>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   143
 *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   144
 * @since 9
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   145
 * @spec JPMS
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   146
 * @see Module#getLayer()
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   147
 */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   148
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   149
public final class ModuleLayer {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   150
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   151
    // the empty layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   152
    private static final ModuleLayer EMPTY_LAYER
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   153
        = new ModuleLayer(Configuration.empty(), List.of(), null);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   154
49528
c1eb35eb5f38 8200125: Fix some classloader/module typos
martin
parents: 48222
diff changeset
   155
    // the configuration from which this layer was created
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   156
    private final Configuration cf;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   157
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   158
    // parent layers, empty in the case of the empty layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   159
    private final List<ModuleLayer> parents;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   160
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   161
    // maps module name to jlr.Module
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   162
    private final Map<String, Module> nameToModule;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   163
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   164
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   165
     * Creates a new module layer from the modules in the given configuration.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   166
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   167
    private ModuleLayer(Configuration cf,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   168
                        List<ModuleLayer> parents,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   169
                        Function<String, ClassLoader> clf)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   170
    {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   171
        this.cf = cf;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   172
        this.parents = parents; // no need to do defensive copy
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   173
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   174
        Map<String, Module> map;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   175
        if (parents.isEmpty()) {
51327
a19fda433921 8209003: Consolidate use of empty collections in java.lang.module
redestad
parents: 49528
diff changeset
   176
            map = Map.of();
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   177
        } else {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   178
            map = Module.defineModules(cf, clf, this);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   179
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   180
        this.nameToModule = map; // no need to do defensive copy
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   181
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   182
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   183
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   184
     * Controls a module layer. The static methods defined by {@link ModuleLayer}
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   185
     * to create module layers return a {@code Controller} that can be used to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   186
     * control modules in the layer.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   187
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   188
     * <p> Unless otherwise specified, passing a {@code null} argument to a
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   189
     * method in this class causes a {@link NullPointerException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   190
     * NullPointerException} to be thrown. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   191
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   192
     * @apiNote Care should be taken with {@code Controller} objects, they
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   193
     * should never be shared with untrusted code.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   194
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   195
     * @since 9
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   196
     * @spec JPMS
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   197
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   198
    public static final class Controller {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   199
        private final ModuleLayer layer;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   200
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   201
        Controller(ModuleLayer layer) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   202
            this.layer = layer;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   203
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   204
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   205
        /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   206
         * Returns the layer that this object controls.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   207
         *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   208
         * @return the module layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   209
         */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   210
        public ModuleLayer layer() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   211
            return layer;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   212
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   213
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   214
        private void ensureInLayer(Module source) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   215
            if (source.getLayer() != layer)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   216
                throw new IllegalArgumentException(source + " not in layer");
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   217
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   218
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   219
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   220
        /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   221
         * Updates module {@code source} in the layer to read module
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   222
         * {@code target}. This method is a no-op if {@code source} already
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   223
         * reads {@code target}.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   224
         *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   225
         * @implNote <em>Read edges</em> added by this method are <em>weak</em>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   226
         * and do not prevent {@code target} from being GC'ed when {@code source}
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   227
         * is strongly reachable.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   228
         *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   229
         * @param  source
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   230
         *         The source module
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   231
         * @param  target
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   232
         *         The target module to read
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   233
         *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   234
         * @return This controller
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   235
         *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   236
         * @throws IllegalArgumentException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   237
         *         If {@code source} is not in the module layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   238
         *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   239
         * @see Module#addReads
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   240
         */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   241
        public Controller addReads(Module source, Module target) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   242
            ensureInLayer(source);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   243
            source.implAddReads(target);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   244
            return this;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   245
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   246
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   247
        /**
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   248
         * Updates module {@code source} in the layer to export a package to
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   249
         * module {@code target}. This method is a no-op if {@code source}
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   250
         * already exports the package to at least {@code target}.
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   251
         *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   252
         * @param  source
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   253
         *         The source module
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   254
         * @param  pn
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   255
         *         The package name
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   256
         * @param  target
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   257
         *         The target module
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   258
         *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   259
         * @return This controller
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   260
         *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   261
         * @throws IllegalArgumentException
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   262
         *         If {@code source} is not in the module layer or the package
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   263
         *         is not in the source module
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   264
         *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   265
         * @see Module#addExports
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   266
         */
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   267
        public Controller addExports(Module source, String pn, Module target) {
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   268
            ensureInLayer(source);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   269
            source.implAddExports(pn, target);
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   270
            return this;
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   271
        }
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   272
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   273
        /**
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   274
         * Updates module {@code source} in the layer to open a package to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   275
         * module {@code target}. This method is a no-op if {@code source}
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   276
         * already opens the package to at least {@code target}.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   277
         *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   278
         * @param  source
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   279
         *         The source module
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   280
         * @param  pn
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   281
         *         The package name
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   282
         * @param  target
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   283
         *         The target module
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   284
         *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   285
         * @return This controller
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   286
         *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   287
         * @throws IllegalArgumentException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   288
         *         If {@code source} is not in the module layer or the package
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   289
         *         is not in the source module
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   290
         *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   291
         * @see Module#addOpens
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   292
         */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   293
        public Controller addOpens(Module source, String pn, Module target) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   294
            ensureInLayer(source);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   295
            source.implAddOpens(pn, target);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   296
            return this;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   297
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   298
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   299
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   300
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   301
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   302
     * Creates a new module layer, with this layer as its parent, by defining the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   303
     * modules in the given {@code Configuration} to the Java virtual machine.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   304
     * This method creates one class loader and defines all modules to that
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   305
     * class loader. The {@link ClassLoader#getParent() parent} of each class
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   306
     * loader is the given parent class loader. This method works exactly as
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   307
     * specified by the static {@link
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   308
     * #defineModulesWithOneLoader(Configuration,List,ClassLoader)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   309
     * defineModulesWithOneLoader} method when invoked with this layer as the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   310
     * parent. In other words, if this layer is {@code thisLayer} then this
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   311
     * method is equivalent to invoking:
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   312
     * <pre> {@code
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   313
     *     ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   314
     * }</pre>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   315
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   316
     * @param  cf
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   317
     *         The configuration for the layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   318
     * @param  parentLoader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   319
     *         The parent class loader for the class loader created by this
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   320
     *         method; may be {@code null} for the bootstrap class loader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   321
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   322
     * @return The newly created layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   323
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   324
     * @throws IllegalArgumentException
48075
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   325
     *         If the given configuration has more than one parent or the parent
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   326
     *         of the configuration is not the configuration for this layer
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   327
     * @throws LayerInstantiationException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   328
     *         If the layer cannot be created for any of the reasons specified
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   329
     *         by the static {@code defineModulesWithOneLoader} method
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   330
     * @throws SecurityException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   331
     *         If {@code RuntimePermission("createClassLoader")} or
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   332
     *         {@code RuntimePermission("getClassLoader")} is denied by
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   333
     *         the security manager
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   334
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   335
     * @see #findLoader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   336
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   337
    public ModuleLayer defineModulesWithOneLoader(Configuration cf,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   338
                                                  ClassLoader parentLoader) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   339
        return defineModulesWithOneLoader(cf, List.of(this), parentLoader).layer();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   340
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   341
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   342
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   343
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   344
     * Creates a new module layer, with this layer as its parent, by defining the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   345
     * modules in the given {@code Configuration} to the Java virtual machine.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   346
     * Each module is defined to its own {@link ClassLoader} created by this
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   347
     * method. The {@link ClassLoader#getParent() parent} of each class loader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   348
     * is the given parent class loader. This method works exactly as specified
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   349
     * by the static {@link
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   350
     * #defineModulesWithManyLoaders(Configuration,List,ClassLoader)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   351
     * defineModulesWithManyLoaders} method when invoked with this layer as the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   352
     * parent. In other words, if this layer is {@code thisLayer} then this
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   353
     * method is equivalent to invoking:
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   354
     * <pre> {@code
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   355
     *     ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   356
     * }</pre>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   357
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   358
     * @param  cf
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   359
     *         The configuration for the layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   360
     * @param  parentLoader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   361
     *         The parent class loader for each of the class loaders created by
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   362
     *         this method; may be {@code null} for the bootstrap class loader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   363
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   364
     * @return The newly created layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   365
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   366
     * @throws IllegalArgumentException
48075
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   367
     *         If the given configuration has more than one parent or the parent
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   368
     *         of the configuration is not the configuration for this layer
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   369
     * @throws LayerInstantiationException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   370
     *         If the layer cannot be created for any of the reasons specified
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   371
     *         by the static {@code defineModulesWithManyLoaders} method
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   372
     * @throws SecurityException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   373
     *         If {@code RuntimePermission("createClassLoader")} or
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   374
     *         {@code RuntimePermission("getClassLoader")} is denied by
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   375
     *         the security manager
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   376
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   377
     * @see #findLoader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   378
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   379
    public ModuleLayer defineModulesWithManyLoaders(Configuration cf,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   380
                                                    ClassLoader parentLoader) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   381
        return defineModulesWithManyLoaders(cf, List.of(this), parentLoader).layer();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   382
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   383
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   384
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   385
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   386
     * Creates a new module layer, with this layer as its parent, by defining the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   387
     * modules in the given {@code Configuration} to the Java virtual machine.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   388
     * Each module is mapped, by name, to its class loader by means of the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   389
     * given function. This method works exactly as specified by the static
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   390
     * {@link #defineModules(Configuration,List,Function) defineModules}
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   391
     * method when invoked with this layer as the parent. In other words, if
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   392
     * this layer is {@code thisLayer} then this method is equivalent to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   393
     * invoking:
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   394
     * <pre> {@code
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   395
     *     ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   396
     * }</pre>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   397
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   398
     * @param  cf
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   399
     *         The configuration for the layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   400
     * @param  clf
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   401
     *         The function to map a module name to a class loader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   402
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   403
     * @return The newly created layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   404
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   405
     * @throws IllegalArgumentException
48075
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   406
     *         If the given configuration has more than one parent or the parent
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   407
     *         of the configuration is not the configuration for this layer
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   408
     * @throws LayerInstantiationException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   409
     *         If the layer cannot be created for any of the reasons specified
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   410
     *         by the static {@code defineModules} method
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   411
     * @throws SecurityException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   412
     *         If {@code RuntimePermission("getClassLoader")} is denied by
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   413
     *         the security manager
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   414
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   415
    public ModuleLayer defineModules(Configuration cf,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   416
                                     Function<String, ClassLoader> clf) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   417
        return defineModules(cf, List.of(this), clf).layer();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   418
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   419
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   420
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   421
     * Creates a new module layer by defining the modules in the given {@code
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   422
     * Configuration} to the Java virtual machine. This method creates one
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   423
     * class loader and defines all modules to that class loader.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   424
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   425
     * <p> The class loader created by this method implements <em>direct
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   426
     * delegation</em> when loading classes from modules. If the {@link
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   427
     * ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   428
     * load a class then it uses the package name of the class to map it to a
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   429
     * module. This may be a module in this layer and hence defined to the same
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   430
     * class loader. It may be a package in a module in a parent layer that is
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   431
     * exported to one or more of the modules in this layer. The class
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   432
     * loader delegates to the class loader of the module, throwing {@code
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   433
     * ClassNotFoundException} if not found by that class loader.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   434
     * When {@code loadClass} is invoked to load classes that do not map to a
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   435
     * module then it delegates to the parent class loader. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   436
     *
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   437
     * <p> The class loader created by this method locates resources
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   438
     * ({@link ClassLoader#getResource(String) getResource}, {@link
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   439
     * ClassLoader#getResources(String) getResources}, and other resource
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   440
     * methods) in all modules in the layer before searching the parent class
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   441
     * loader. </p>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   442
     *
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   443
     * <p> Attempting to create a layer with all modules defined to the same
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   444
     * class loader can fail for the following reasons:
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   445
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   446
     * <ul>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   447
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   448
     *     <li><p> <em>Overlapping packages</em>: Two or more modules in the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   449
     *     configuration have the same package. </p></li>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   450
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   451
     *     <li><p> <em>Split delegation</em>: The resulting class loader would
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   452
     *     need to delegate to more than one class loader in order to load
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   453
     *     classes in a specific package. </p></li>
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   454
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   455
     * </ul>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   456
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   457
     * <p> In addition, a layer cannot be created if the configuration contains
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   458
     * a module named "{@code java.base}", or a module contains a package named
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   459
     * "{@code java}" or a package with a name starting with "{@code java.}". </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   460
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   461
     * <p> If there is a security manager then the class loader created by
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   462
     * this method will load classes and resources with privileges that are
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   463
     * restricted by the calling context of this method. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   464
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   465
     * @param  cf
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   466
     *         The configuration for the layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   467
     * @param  parentLayers
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   468
     *         The list of parent layers in search order
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   469
     * @param  parentLoader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   470
     *         The parent class loader for the class loader created by this
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   471
     *         method; may be {@code null} for the bootstrap class loader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   472
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   473
     * @return A controller that controls the newly created layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   474
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   475
     * @throws IllegalArgumentException
48075
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   476
     *         If the parent(s) of the given configuration do not match the
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   477
     *         configuration of the parent layers, including order
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   478
     * @throws LayerInstantiationException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   479
     *         If all modules cannot be defined to the same class loader for any
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   480
     *         of the reasons listed above
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   481
     * @throws SecurityException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   482
     *         If {@code RuntimePermission("createClassLoader")} or
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   483
     *         {@code RuntimePermission("getClassLoader")} is denied by
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   484
     *         the security manager
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   485
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   486
     * @see #findLoader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   487
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   488
    public static Controller defineModulesWithOneLoader(Configuration cf,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   489
                                                        List<ModuleLayer> parentLayers,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   490
                                                        ClassLoader parentLoader)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   491
    {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   492
        List<ModuleLayer> parents = new ArrayList<>(parentLayers);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   493
        checkConfiguration(cf, parents);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   494
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   495
        checkCreateClassLoaderPermission();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   496
        checkGetClassLoaderPermission();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   497
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   498
        try {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   499
            Loader loader = new Loader(cf.modules(), parentLoader);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   500
            loader.initRemotePackageMap(cf, parents);
49528
c1eb35eb5f38 8200125: Fix some classloader/module typos
martin
parents: 48222
diff changeset
   501
            ModuleLayer layer = new ModuleLayer(cf, parents, mn -> loader);
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   502
            return new Controller(layer);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   503
        } catch (IllegalArgumentException | IllegalStateException e) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   504
            throw new LayerInstantiationException(e.getMessage());
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   505
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   506
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   507
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   508
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   509
     * Creates a new module layer by defining the modules in the given {@code
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   510
     * Configuration} to the Java virtual machine. Each module is defined to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   511
     * its own {@link ClassLoader} created by this method. The {@link
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   512
     * ClassLoader#getParent() parent} of each class loader is the given parent
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   513
     * class loader.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   514
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   515
     * <p> The class loaders created by this method implement <em>direct
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   516
     * delegation</em> when loading classes from modules. If the {@link
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   517
     * ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   518
     * load a class then it uses the package name of the class to map it to a
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   519
     * module. The package may be in the module defined to the class loader.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   520
     * The package may be exported by another module in this layer to the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   521
     * module defined to the class loader. It may be in a package exported by a
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   522
     * module in a parent layer. The class loader delegates to the class loader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   523
     * of the module, throwing {@code ClassNotFoundException} if not found by
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   524
     * that class loader. When {@code loadClass} is invoked to load a class
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   525
     * that does not map to a module then it delegates to the parent class
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   526
     * loader. </p>
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   527
     *
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   528
     * <p> The class loaders created by this method locate resources
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   529
     * ({@link ClassLoader#getResource(String) getResource}, {@link
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   530
     * ClassLoader#getResources(String) getResources}, and other resource
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   531
     * methods) in the module defined to the class loader before searching
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   532
     * the parent class loader. </p>
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   533
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   534
     * <p> If there is a security manager then the class loaders created by
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   535
     * this method will load classes and resources with privileges that are
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   536
     * restricted by the calling context of this method. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   537
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   538
     * @param  cf
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   539
     *         The configuration for the layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   540
     * @param  parentLayers
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   541
     *         The list of parent layers in search order
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   542
     * @param  parentLoader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   543
     *         The parent class loader for each of the class loaders created by
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   544
     *         this method; may be {@code null} for the bootstrap class loader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   545
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   546
     * @return A controller that controls the newly created layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   547
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   548
     * @throws IllegalArgumentException
48075
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   549
     *         If the parent(s) of the given configuration do not match the
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   550
     *         configuration of the parent layers, including order
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   551
     * @throws LayerInstantiationException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   552
     *         If the layer cannot be created because the configuration contains
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   553
     *         a module named "{@code java.base}" or a module contains a package
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   554
     *         named "{@code java}" or a package with a name starting with
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   555
     *         "{@code java.}"
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   556
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   557
     * @throws SecurityException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   558
     *         If {@code RuntimePermission("createClassLoader")} or
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   559
     *         {@code RuntimePermission("getClassLoader")} is denied by
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   560
     *         the security manager
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   561
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   562
     * @see #findLoader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   563
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   564
    public static Controller defineModulesWithManyLoaders(Configuration cf,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   565
                                                          List<ModuleLayer> parentLayers,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   566
                                                          ClassLoader parentLoader)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   567
    {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   568
        List<ModuleLayer> parents = new ArrayList<>(parentLayers);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   569
        checkConfiguration(cf, parents);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   570
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   571
        checkCreateClassLoaderPermission();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   572
        checkGetClassLoaderPermission();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   573
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   574
        LoaderPool pool = new LoaderPool(cf, parents, parentLoader);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   575
        try {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   576
            ModuleLayer layer = new ModuleLayer(cf, parents, pool::loaderFor);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   577
            return new Controller(layer);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   578
        } catch (IllegalArgumentException | IllegalStateException e) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   579
            throw new LayerInstantiationException(e.getMessage());
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   580
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   581
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   582
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   583
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   584
     * Creates a new module layer by defining the modules in the given {@code
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   585
     * Configuration} to the Java virtual machine. The given function maps each
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   586
     * module in the configuration, by name, to a class loader. Creating the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   587
     * layer informs the Java virtual machine about the classes that may be
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   588
     * loaded so that the Java virtual machine knows which module that each
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   589
     * class is a member of.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   590
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   591
     * <p> The class loader delegation implemented by the class loaders must
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   592
     * respect module readability. The class loaders should be
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   593
     * {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   594
     * avoid deadlocks during class loading. In addition, the entity creating
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   595
     * a new layer with this method should arrange that the class loaders be
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   596
     * ready to load from these modules before there are any attempts to load
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   597
     * classes or resources. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   598
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   599
     * <p> Creating a layer can fail for the following reasons: </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   600
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   601
     * <ul>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   602
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   603
     *     <li><p> Two or more modules with the same package are mapped to the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   604
     *     same class loader. </p></li>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   605
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   606
     *     <li><p> A module is mapped to a class loader that already has a
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   607
     *     module of the same name defined to it. </p></li>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   608
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   609
     *     <li><p> A module is mapped to a class loader that has already
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   610
     *     defined types in any of the packages in the module. </p></li>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   611
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   612
     * </ul>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   613
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   614
     * <p> In addition, a layer cannot be created if the configuration contains
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   615
     * a module named "{@code java.base}", a configuration contains a module
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   616
     * with a package named "{@code java}" or a package name starting with
45652
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   617
     * "{@code java.}", or the function to map a module name to a class loader
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   618
     * returns {@code null} or the {@linkplain ClassLoader#getPlatformClassLoader()
33342314ce89 8181087: Module system implementation refresh (6/2017)
alanb
parents: 45138
diff changeset
   619
     * platform class loader}. </p>
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   620
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   621
     * <p> If the function to map a module name to class loader throws an error
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   622
     * or runtime exception then it is propagated to the caller of this method.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   623
     * </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   624
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   625
     * @apiNote It is implementation specific as to whether creating a layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   626
     * with this method is an atomic operation or not. Consequentially it is
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   627
     * possible for this method to fail with some modules, but not all, defined
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   628
     * to the Java virtual machine.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   629
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   630
     * @param  cf
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   631
     *         The configuration for the layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   632
     * @param  parentLayers
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   633
     *         The list of parent layers in search order
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   634
     * @param  clf
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   635
     *         The function to map a module name to a class loader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   636
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   637
     * @return A controller that controls the newly created layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   638
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   639
     * @throws IllegalArgumentException
48075
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   640
     *         If the parent(s) of the given configuration do not match the
c51f9eea6d2b 8186736: Spec clarifications for IllegalArgumentException throwing - ModuleLayer.defineX methods
alanb
parents: 47866
diff changeset
   641
     *         configuration of the parent layers, including order
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   642
     * @throws LayerInstantiationException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   643
     *         If creating the layer fails for any of the reasons listed above
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   644
     * @throws SecurityException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   645
     *         If {@code RuntimePermission("getClassLoader")} is denied by
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   646
     *         the security manager
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   647
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   648
    public static Controller defineModules(Configuration cf,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   649
                                           List<ModuleLayer> parentLayers,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   650
                                           Function<String, ClassLoader> clf)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   651
    {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   652
        List<ModuleLayer> parents = new ArrayList<>(parentLayers);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   653
        checkConfiguration(cf, parents);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   654
        Objects.requireNonNull(clf);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   655
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   656
        checkGetClassLoaderPermission();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   657
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   658
        // The boot layer is checked during module system initialization
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   659
        if (boot() != null) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   660
            checkForDuplicatePkgs(cf, clf);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   661
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   662
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   663
        try {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   664
            ModuleLayer layer = new ModuleLayer(cf, parents, clf);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   665
            return new Controller(layer);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   666
        } catch (IllegalArgumentException | IllegalStateException e) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   667
            throw new LayerInstantiationException(e.getMessage());
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   668
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   669
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   670
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   671
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   672
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   673
     * Checks that the parent configurations match the configuration of
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   674
     * the parent layers.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   675
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   676
    private static void checkConfiguration(Configuration cf,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   677
                                           List<ModuleLayer> parentLayers)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   678
    {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   679
        Objects.requireNonNull(cf);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   680
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   681
        List<Configuration> parentConfigurations = cf.parents();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   682
        if (parentLayers.size() != parentConfigurations.size())
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   683
            throw new IllegalArgumentException("wrong number of parents");
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   684
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   685
        int index = 0;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   686
        for (ModuleLayer parent : parentLayers) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   687
            if (parent.configuration() != parentConfigurations.get(index)) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   688
                throw new IllegalArgumentException(
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   689
                        "Parent of configuration != configuration of this Layer");
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   690
            }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   691
            index++;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   692
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   693
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   694
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   695
    private static void checkCreateClassLoaderPermission() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   696
        SecurityManager sm = System.getSecurityManager();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   697
        if (sm != null)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   698
            sm.checkPermission(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   699
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   700
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   701
    private static void checkGetClassLoaderPermission() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   702
        SecurityManager sm = System.getSecurityManager();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   703
        if (sm != null)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   704
            sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   705
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   706
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   707
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   708
     * Checks a configuration and the module-to-loader mapping to ensure that
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   709
     * no two modules mapped to the same class loader have the same package.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   710
     * It also checks that no two automatic modules have the same package.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   711
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   712
     * @throws LayerInstantiationException
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   713
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   714
    private static void checkForDuplicatePkgs(Configuration cf,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   715
                                              Function<String, ClassLoader> clf)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   716
    {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   717
        // HashMap allows null keys
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   718
        Map<ClassLoader, Set<String>> loaderToPackages = new HashMap<>();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   719
        for (ResolvedModule resolvedModule : cf.modules()) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   720
            ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   721
            ClassLoader loader = clf.apply(descriptor.name());
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   722
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   723
            Set<String> loaderPackages
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   724
                = loaderToPackages.computeIfAbsent(loader, k -> new HashSet<>());
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   725
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   726
            for (String pkg : descriptor.packages()) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   727
                boolean added = loaderPackages.add(pkg);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   728
                if (!added) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   729
                    throw fail("More than one module with package %s mapped" +
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   730
                               " to the same class loader", pkg);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   731
                }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   732
            }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   733
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   734
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   735
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   736
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   737
     * Creates a LayerInstantiationException with the a message formatted from
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   738
     * the given format string and arguments.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   739
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   740
    private static LayerInstantiationException fail(String fmt, Object ... args) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   741
        String msg = String.format(fmt, args);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   742
        return new LayerInstantiationException(msg);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   743
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   744
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   745
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   746
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   747
     * Returns the configuration for this layer.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   748
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   749
     * @return The configuration for this layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   750
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   751
    public Configuration configuration() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   752
        return cf;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   753
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   754
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   755
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   756
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   757
     * Returns the list of this layer's parents unless this is the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   758
     * {@linkplain #empty empty layer}, which has no parents and so an
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   759
     * empty list is returned.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   760
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   761
     * @return The list of this layer's parents
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   762
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   763
    public List<ModuleLayer> parents() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   764
        return parents;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   765
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   766
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   767
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   768
    /**
47866
39db80b32b69 8191632: Typos in comments due to duplicating words
igerasim
parents: 47216
diff changeset
   769
     * Returns an ordered stream of layers. The first element is this layer,
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   770
     * the remaining elements are the parent layers in DFS order.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   771
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   772
     * @implNote For now, the assumption is that the number of elements will
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   773
     * be very low and so this method does not use a specialized spliterator.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   774
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   775
    Stream<ModuleLayer> layers() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   776
        List<ModuleLayer> allLayers = this.allLayers;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   777
        if (allLayers != null)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   778
            return allLayers.stream();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   779
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   780
        allLayers = new ArrayList<>();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   781
        Set<ModuleLayer> visited = new HashSet<>();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   782
        Deque<ModuleLayer> stack = new ArrayDeque<>();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   783
        visited.add(this);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   784
        stack.push(this);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   785
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   786
        while (!stack.isEmpty()) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   787
            ModuleLayer layer = stack.pop();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   788
            allLayers.add(layer);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   789
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   790
            // push in reverse order
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   791
            for (int i = layer.parents.size() - 1; i >= 0; i--) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   792
                ModuleLayer parent = layer.parents.get(i);
51703
4ffb0a33f265 8210347: Combine subsequent calls to Set.contains() and Set.add()
igerasim
parents: 51327
diff changeset
   793
                if (visited.add(parent)) {
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   794
                    stack.push(parent);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   795
                }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   796
            }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   797
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   798
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   799
        this.allLayers = allLayers = Collections.unmodifiableList(allLayers);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   800
        return allLayers.stream();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   801
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   802
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   803
    private volatile List<ModuleLayer> allLayers;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   804
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   805
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   806
     * Returns the set of the modules in this layer.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   807
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   808
     * @return A possibly-empty unmodifiable set of the modules in this layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   809
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   810
    public Set<Module> modules() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   811
        Set<Module> modules = this.modules;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   812
        if (modules == null) {
51327
a19fda433921 8209003: Consolidate use of empty collections in java.lang.module
redestad
parents: 49528
diff changeset
   813
            this.modules = modules = Set.copyOf(nameToModule.values());
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   814
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   815
        return modules;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   816
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   817
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   818
    private volatile Set<Module> modules;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   819
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   820
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   821
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   822
     * Returns the module with the given name in this layer, or if not in this
47004
b7e72fc752c9 8186684: Fix broken links in java.base API docs
jjg
parents: 45652
diff changeset
   823
     * layer, the {@linkplain #parents() parent} layers. Finding a module in
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   824
     * parent layers is equivalent to invoking {@code findModule} on each
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   825
     * parent, in search order, until the module is found or all parents have
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   826
     * been searched. In a <em>tree of layers</em>  then this is equivalent to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   827
     * a depth-first search.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   828
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   829
     * @param  name
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   830
     *         The name of the module to find
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   831
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   832
     * @return The module with the given name or an empty {@code Optional}
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   833
     *         if there isn't a module with this name in this layer or any
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   834
     *         parent layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   835
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   836
    public Optional<Module> findModule(String name) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   837
        Objects.requireNonNull(name);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   838
        if (this == EMPTY_LAYER)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   839
            return Optional.empty();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   840
        Module m = nameToModule.get(name);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   841
        if (m != null)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   842
            return Optional.of(m);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   843
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   844
        return layers()
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   845
                .skip(1)  // skip this layer
48222
37d3e1a80c3b 8193256: Configuration and ModuleLayer findModule cleanup
alanb
parents: 48075
diff changeset
   846
                .map(l -> l.nameToModule.get(name))
37d3e1a80c3b 8193256: Configuration and ModuleLayer findModule cleanup
alanb
parents: 48075
diff changeset
   847
                .filter(Objects::nonNull)
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   848
                .findAny();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   849
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   850
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   851
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   852
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   853
     * Returns the {@code ClassLoader} for the module with the given name. If
47004
b7e72fc752c9 8186684: Fix broken links in java.base API docs
jjg
parents: 45652
diff changeset
   854
     * a module of the given name is not in this layer then the {@link #parents()
44545
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   855
     * parent} layers are searched in the manner specified by {@link
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   856
     * #findModule(String) findModule}.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   857
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   858
     * <p> If there is a security manager then its {@code checkPermission}
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   859
     * method is called with a {@code RuntimePermission("getClassLoader")}
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   860
     * permission to check that the caller is allowed to get access to the
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   861
     * class loader. </p>
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   862
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   863
     * @apiNote This method does not return an {@code Optional<ClassLoader>}
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   864
     * because `null` must be used to represent the bootstrap class loader.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   865
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   866
     * @param  name
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   867
     *         The name of the module to find
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   868
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   869
     * @return The ClassLoader that the module is defined to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   870
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   871
     * @throws IllegalArgumentException if a module of the given name is not
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   872
     *         defined in this layer or any parent of this layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   873
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   874
     * @throws SecurityException if denied by the security manager
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   875
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   876
    public ClassLoader findLoader(String name) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   877
        Optional<Module> om = findModule(name);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   878
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   879
        // can't use map(Module::getClassLoader) as class loader can be null
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   880
        if (om.isPresent()) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   881
            return om.get().getClassLoader();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   882
        } else {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   883
            throw new IllegalArgumentException("Module " + name
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   884
                                               + " not known to this layer");
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   885
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   886
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   887
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   888
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   889
     * Returns a string describing this module layer.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   890
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   891
     * @return A possibly empty string describing this module layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   892
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   893
    @Override
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   894
    public String toString() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   895
        return modules().stream()
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   896
                .map(Module::getName)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   897
                .collect(Collectors.joining(", "));
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   898
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   899
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   900
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   901
     * Returns the <em>empty</em> layer. There are no modules in the empty
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   902
     * layer. It has no parents.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   903
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   904
     * @return The empty layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   905
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   906
    public static ModuleLayer empty() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   907
        return EMPTY_LAYER;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   908
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   909
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   910
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   911
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   912
     * Returns the boot layer. The boot layer contains at least one module,
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   913
     * {@code java.base}. Its parent is the {@link #empty() empty} layer.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   914
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   915
     * @apiNote This method returns {@code null} during startup and before
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   916
     *          the boot layer is fully initialized.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   917
     *
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   918
     * @return The boot layer
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   919
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   920
    public static ModuleLayer boot() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   921
        return System.bootLayer;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   922
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   923
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   924
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   925
     * Returns the ServicesCatalog for this Layer, creating it if not
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   926
     * already created.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   927
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   928
    ServicesCatalog getServicesCatalog() {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   929
        ServicesCatalog servicesCatalog = this.servicesCatalog;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   930
        if (servicesCatalog != null)
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   931
            return servicesCatalog;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   932
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   933
        synchronized (this) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   934
            servicesCatalog = this.servicesCatalog;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   935
            if (servicesCatalog == null) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   936
                servicesCatalog = ServicesCatalog.create();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   937
                nameToModule.values().forEach(servicesCatalog::register);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   938
                this.servicesCatalog = servicesCatalog;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   939
            }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   940
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   941
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   942
        return servicesCatalog;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   943
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   944
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   945
    private volatile ServicesCatalog servicesCatalog;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   946
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   947
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   948
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   949
     * Record that this layer has at least one module defined to the given
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   950
     * class loader.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   951
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   952
    void bindToLoader(ClassLoader loader) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   953
        // CLV.computeIfAbsent(loader, (cl, clv) -> new CopyOnWriteArrayList<>())
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   954
        List<ModuleLayer> list = CLV.get(loader);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   955
        if (list == null) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   956
            list = new CopyOnWriteArrayList<>();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   957
            List<ModuleLayer> previous = CLV.putIfAbsent(loader, list);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   958
            if (previous != null) list = previous;
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   959
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   960
        list.add(this);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   961
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   962
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   963
    /**
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   964
     * Returns a stream of the layers that have at least one module defined to
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   965
     * the given class loader.
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   966
     */
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   967
    static Stream<ModuleLayer> layers(ClassLoader loader) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   968
        List<ModuleLayer> list = CLV.get(loader);
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   969
        if (list != null) {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   970
            return list.stream();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   971
        } else {
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   972
            return Stream.empty();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   973
        }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   974
    }
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   975
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   976
    // the list of layers with modules defined to a class loader
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   977
    private static final ClassLoaderValue<List<ModuleLayer>> CLV = new ClassLoaderValue<>();
83b611b88ac8 8177530: Module system implementation refresh (4/2017)
alanb
parents:
diff changeset
   978
}