jdk/src/java.base/share/classes/java/lang/reflect/Module.java
author alanb
Fri, 16 Dec 2016 06:19:16 +0000
changeset 42703 20c39ea4a507
parent 42338 a60f280f803c
child 43532 5028c6b02af5
permissions -rw-r--r--
8170987: Module system implementation refresh (12/2016) 8170859: Run time and tool support for ModuleResolution Reviewed-by: redestad, mchung, alanb Contributed-by: alan.bateman@oracle.com, mandy.chung@oracle.com, chris.hegarty@oracle.com, mark.reinhold@oracle.com, john.r.rose@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     1
/*
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     2
 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     4
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    10
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    15
 * accompanied this code).
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    16
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    20
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    23
 * questions.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    24
 */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    25
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    26
package java.lang.reflect;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    27
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    28
import java.io.IOException;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    29
import java.io.InputStream;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    30
import java.lang.annotation.Annotation;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    31
import java.lang.module.Configuration;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    32
import java.lang.module.ModuleReference;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    33
import java.lang.module.ModuleDescriptor;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    34
import java.lang.module.ModuleDescriptor.Exports;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    35
import java.lang.module.ModuleDescriptor.Opens;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    36
import java.lang.module.ModuleDescriptor.Version;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    37
import java.lang.module.ResolvedModule;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    38
import java.net.URI;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    39
import java.net.URL;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    40
import java.security.AccessController;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    41
import java.security.PrivilegedAction;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    42
import java.util.Collections;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    43
import java.util.HashMap;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    44
import java.util.HashSet;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    45
import java.util.Map;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    46
import java.util.Objects;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    47
import java.util.Optional;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    48
import java.util.Set;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    49
import java.util.concurrent.ConcurrentHashMap;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    50
import java.util.function.Function;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    51
import java.util.stream.Stream;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    52
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    53
import jdk.internal.loader.BuiltinClassLoader;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    54
import jdk.internal.loader.BootLoader;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    55
import jdk.internal.loader.ResourceHelper;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    56
import jdk.internal.misc.JavaLangAccess;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    57
import jdk.internal.misc.JavaLangReflectModuleAccess;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    58
import jdk.internal.misc.SharedSecrets;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    59
import jdk.internal.module.ServicesCatalog;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    60
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    61
import jdk.internal.org.objectweb.asm.Attribute;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    62
import jdk.internal.org.objectweb.asm.ClassReader;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    63
import jdk.internal.org.objectweb.asm.ClassVisitor;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    64
import jdk.internal.org.objectweb.asm.ClassWriter;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    65
import jdk.internal.org.objectweb.asm.Opcodes;
37363
329dba26ffd2 8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents: 36511
diff changeset
    66
import jdk.internal.reflect.CallerSensitive;
329dba26ffd2 8137058: Clear out all non-Critical APIs from sun.reflect
chegar
parents: 36511
diff changeset
    67
import jdk.internal.reflect.Reflection;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    68
import sun.security.util.SecurityConstants;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    69
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    70
/**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    71
 * Represents a run-time module, either {@link #isNamed() named} or unnamed.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    72
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    73
 * <p> Named modules have a {@link #getName() name} and are constructed by the
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    74
 * Java Virtual Machine when a graph of modules is defined to the Java virtual
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    75
 * machine to create a module {@link Layer Layer}. </p>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    76
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    77
 * <p> An unnamed module does not have a name. There is an unnamed module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    78
 * per {@link ClassLoader ClassLoader} that is obtained by invoking the class
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    79
 * loader's {@link ClassLoader#getUnnamedModule() getUnnamedModule} method. The
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    80
 * {@link Class#getModule() getModule} method of all types defined by a class
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    81
 * loader that are not in a named module return the class loader's unnamed
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    82
 * module. </p>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    83
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    84
 * <p> The package names that are parameters or returned by methods defined in
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    85
 * this class are the fully-qualified names of the packages as defined in
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    86
 * section 6.5.3 of <cite>The Java&trade; Language Specification </cite>, for
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    87
 * example, {@code "java.lang"}. </p>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    88
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    89
 * <p> Unless otherwise specified, passing a {@code null} argument to a method
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    90
 * in this class causes a {@link NullPointerException NullPointerException} to
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    91
 * be thrown. </p>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    92
 *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    93
 * @since 9
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    94
 * @see java.lang.Class#getModule
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    95
 */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    96
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
    97
public final class Module implements AnnotatedElement {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    98
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
    99
    // the layer that contains this module, can be null
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   100
    private final Layer layer;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   101
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   102
    // module name and loader, these fields are read by VM
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   103
    private final String name;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   104
    private final ClassLoader loader;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   105
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   106
    // the module descriptor
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   107
    private final ModuleDescriptor descriptor;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   108
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   109
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   110
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   111
     * Creates a new named Module. The resulting Module will be defined to the
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   112
     * VM but will not read any other modules, will not have any exports setup
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   113
     * and will not be registered in the service catalog.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   114
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   115
    private Module(Layer layer,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   116
                   ClassLoader loader,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   117
                   ModuleDescriptor descriptor,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   118
                   URI uri)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   119
    {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   120
        this.layer = layer;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   121
        this.name = descriptor.name();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   122
        this.loader = loader;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   123
        this.descriptor = descriptor;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   124
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   125
        // define module to VM
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   126
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   127
        boolean isOpen = descriptor.isOpen();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   128
        Version version = descriptor.version().orElse(null);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   129
        String vs = Objects.toString(version, null);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   130
        String loc = Objects.toString(uri, null);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   131
        Set<String> packages = descriptor.packages();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   132
        int n = packages.size();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   133
        String[] array = new String[n];
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   134
        int i = 0;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   135
        for (String pn : packages) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   136
            array[i++] = pn.replace('.', '/');
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   137
        }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   138
        defineModule0(this, isOpen, vs, loc, array);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   139
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   140
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   141
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   142
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   143
     * Create the unnamed Module for the given ClassLoader.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   144
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   145
     * @see ClassLoader#getUnnamedModule
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   146
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   147
    private Module(ClassLoader loader) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   148
        this.layer = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   149
        this.name = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   150
        this.loader = loader;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   151
        this.descriptor = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   152
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   153
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   154
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   155
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   156
     * Creates a named module but without defining the module to the VM.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   157
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   158
     * @apiNote This constructor is for VM white-box testing.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   159
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   160
    Module(ClassLoader loader, ModuleDescriptor descriptor) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   161
        this.layer = null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   162
        this.name = descriptor.name();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   163
        this.loader = loader;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   164
        this.descriptor = descriptor;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   165
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   166
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   167
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   168
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   169
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   170
     * Returns {@code true} if this module is a named module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   171
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   172
     * @return {@code true} if this is a named module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   173
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   174
     * @see ClassLoader#getUnnamedModule()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   175
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   176
    public boolean isNamed() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   177
        return name != null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   178
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   179
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   180
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   181
     * Returns the module name or {@code null} if this module is an unnamed
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   182
     * module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   183
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   184
     * @return The module name
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   185
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   186
    public String getName() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   187
        return name;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   188
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   189
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   190
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   191
     * Returns the {@code ClassLoader} for this module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   192
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   193
     * <p> If there is a security manager then its {@code checkPermission}
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   194
     * method if first called with a {@code RuntimePermission("getClassLoader")}
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   195
     * permission to check that the caller is allowed to get access to the
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   196
     * class loader. </p>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   197
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   198
     * @return The class loader for this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   199
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   200
     * @throws SecurityException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   201
     *         If denied by the security manager
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   202
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   203
    public ClassLoader getClassLoader() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   204
        SecurityManager sm = System.getSecurityManager();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   205
        if (sm != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   206
            sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   207
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   208
        return loader;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   209
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   210
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   211
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   212
     * Returns the module descriptor for this module or {@code null} if this
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   213
     * module is an unnamed module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   214
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   215
     * @return The module descriptor for this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   216
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   217
    public ModuleDescriptor getDescriptor() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   218
        return descriptor;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   219
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   220
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   221
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   222
     * Returns the layer that contains this module or {@code null} if this
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   223
     * module is not in a layer.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   224
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   225
     * A module {@code Layer} contains named modules and therefore this
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   226
     * method always returns {@code null} when invoked on an unnamed module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   227
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   228
     * <p> <a href="Proxy.html#dynamicmodule">Dynamic modules</a> are named
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   229
     * modules that are generated at runtime. A dynamic module may or may
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   230
     * not be in a module Layer. </p>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   231
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   232
     * @return The layer that contains this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   233
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   234
     * @see Proxy
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   235
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   236
    public Layer getLayer() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   237
        if (isNamed()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   238
            Layer layer = this.layer;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   239
            if (layer != null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   240
                return layer;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   241
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   242
            // special-case java.base as it is created before the boot Layer
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   243
            if (loader == null && name.equals("java.base")) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   244
                return SharedSecrets.getJavaLangAccess().getBootLayer();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   245
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   246
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   247
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   248
        return null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   249
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   250
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   251
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   252
    // --
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   253
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   254
    // special Module to mean "all unnamed modules"
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   255
    private static final Module ALL_UNNAMED_MODULE = new Module(null);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   256
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   257
    // special Module to mean "everyone"
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   258
    private static final Module EVERYONE_MODULE = new Module(null);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   259
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   260
    // set contains EVERYONE_MODULE, used when a package is opened or
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   261
    // exported unconditionally
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   262
    private static final Set<Module> EVERYONE_SET = Set.of(EVERYONE_MODULE);
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   263
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   264
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   265
    // -- readability --
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   266
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   267
    // the modules that this module reads
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   268
    private volatile Set<Module> reads;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   269
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   270
    // additional module (2nd key) that some module (1st key) reflectively reads
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   271
    private static final WeakPairMap<Module, Module, Boolean> reflectivelyReads
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   272
        = new WeakPairMap<>();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   273
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   274
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   275
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   276
     * Indicates if this module reads the given module. This method returns
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   277
     * {@code true} if invoked to test if this module reads itself. It also
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   278
     * returns {@code true} if invoked on an unnamed module (as unnamed
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   279
     * modules read all modules).
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   280
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   281
     * @param  other
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   282
     *         The other module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   283
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   284
     * @return {@code true} if this module reads {@code other}
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   285
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   286
     * @see #addReads(Module)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   287
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   288
    public boolean canRead(Module other) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   289
        Objects.requireNonNull(other);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   290
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   291
        // an unnamed module reads all modules
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   292
        if (!this.isNamed())
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   293
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   294
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   295
        // all modules read themselves
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   296
        if (other == this)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   297
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   298
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   299
        // check if this module reads other
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   300
        if (other.isNamed()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   301
            Set<Module> reads = this.reads; // volatile read
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   302
            if (reads != null && reads.contains(other))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   303
                return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   304
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   305
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   306
        // check if this module reads the other module reflectively
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   307
        if (reflectivelyReads.containsKeyPair(this, other))
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   308
            return true;
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   309
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   310
        // if other is an unnamed module then check if this module reads
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   311
        // all unnamed modules
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   312
        if (!other.isNamed()
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   313
            && reflectivelyReads.containsKeyPair(this, ALL_UNNAMED_MODULE))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   314
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   315
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   316
        return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   317
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   318
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   319
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   320
     * If the caller's module is this module then update this module to read
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   321
     * the given module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   322
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   323
     * This method is a no-op if {@code other} is this module (all modules read
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   324
     * themselves), this module is an unnamed module (as unnamed modules read
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   325
     * all modules), or this module already reads {@code other}.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   326
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   327
     * @implNote <em>Read edges</em> added by this method are <em>weak</em> and
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   328
     * do not prevent {@code other} from being GC'ed when this module is
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   329
     * strongly reachable.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   330
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   331
     * @param  other
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   332
     *         The other module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   333
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   334
     * @return this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   335
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   336
     * @throws IllegalStateException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   337
     *         If this is a named module and the caller is not this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   338
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   339
     * @see #canRead
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   340
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   341
    @CallerSensitive
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   342
    public Module addReads(Module other) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   343
        Objects.requireNonNull(other);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   344
        if (this.isNamed()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   345
            Module caller = Reflection.getCallerClass().getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   346
            if (caller != this) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   347
                throw new IllegalStateException(caller + " != " + this);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   348
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   349
            implAddReads(other, true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   350
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   351
        return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   352
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   353
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   354
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   355
     * Updates this module to read another module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   356
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   357
     * @apiNote This method is for Proxy use and white-box testing.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   358
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   359
    void implAddReads(Module other) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   360
        implAddReads(other, true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   361
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   362
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   363
    /**
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   364
     * Updates this module to read another module without notifying the VM.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   365
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   366
     * @apiNote This method is for VM white-box testing.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   367
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   368
    void implAddReadsNoSync(Module other) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   369
        implAddReads(other, false);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   370
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   371
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   372
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   373
     * Makes the given {@code Module} readable to this module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   374
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   375
     * If {@code syncVM} is {@code true} then the VM is notified.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   376
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   377
    private void implAddReads(Module other, boolean syncVM) {
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   378
        Objects.requireNonNull(other);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   379
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   380
        // nothing to do
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   381
        if (other == this || !this.isNamed())
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   382
            return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   383
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   384
        // check if we already read this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   385
        Set<Module> reads = this.reads;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   386
        if (reads != null && reads.contains(other))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   387
            return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   388
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   389
        // update VM first, just in case it fails
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   390
        if (syncVM) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   391
            if (other == ALL_UNNAMED_MODULE) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   392
                addReads0(this, null);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   393
            } else {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   394
                addReads0(this, other);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   395
            }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   396
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   397
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   398
        // add reflective read
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   399
        reflectivelyReads.putIfAbsent(this, other, Boolean.TRUE);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   400
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   401
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   402
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   403
    // -- exported and open packages --
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   404
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   405
    // the packages are open to other modules, can be null
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   406
    // if the value contains EVERYONE_MODULE then the package is open to all
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   407
    private volatile Map<String, Set<Module>> openPackages;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   408
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   409
    // the packages that are exported, can be null
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   410
    // if the value contains EVERYONE_MODULE then the package is exported to all
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   411
    private volatile Map<String, Set<Module>> exportedPackages;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   412
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   413
    // additional exports or opens added at run-time
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   414
    // this module (1st key), other module (2nd key)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   415
    // (package name, open?) (value)
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   416
    private static final WeakPairMap<Module, Module, Map<String, Boolean>>
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   417
        reflectivelyExports = new WeakPairMap<>();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   418
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   419
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   420
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   421
     * Returns {@code true} if this module exports the given package to at
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   422
     * least the given module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   423
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   424
     * <p> This method returns {@code true} if invoked to test if a package in
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   425
     * this module is exported to itself. It always returns {@code true} when
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   426
     * invoked on an unnamed module. A package that is {@link #isOpen open} to
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   427
     * the given module is considered exported to that module at run-time and
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   428
     * so this method returns {@code true} if the package is open to the given
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   429
     * module. </p>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   430
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   431
     * <p> This method does not check if the given module reads this module. </p>
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   432
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   433
     * @param  pn
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   434
     *         The package name
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   435
     * @param  other
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   436
     *         The other module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   437
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   438
     * @return {@code true} if this module exports the package to at least the
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   439
     *         given module
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   440
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   441
     * @see ModuleDescriptor#exports()
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   442
     * @see #addExports(String,Module)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   443
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   444
    public boolean isExported(String pn, Module other) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   445
        Objects.requireNonNull(pn);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   446
        Objects.requireNonNull(other);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   447
        return implIsExportedOrOpen(pn, other, /*open*/false);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   448
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   449
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   450
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   451
     * Returns {@code true} if this module has <em>opened</em> a package to at
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   452
     * least the given module.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   453
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   454
     * <p> This method returns {@code true} if invoked to test if a package in
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   455
     * this module is open to itself. It returns {@code true} when invoked on an
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   456
     * {@link ModuleDescriptor#isOpen open} module with a package in the module.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   457
     * It always returns {@code true} when invoked on an unnamed module. </p>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   458
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   459
     * <p> This method does not check if the given module reads this module. </p>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   460
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   461
     * @param  pn
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   462
     *         The package name
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   463
     * @param  other
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   464
     *         The other module
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   465
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   466
     * @return {@code true} if this module has <em>opened</em> the package
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   467
     *         to at least the given module
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   468
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   469
     * @see ModuleDescriptor#opens()
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   470
     * @see #addOpens(String,Module)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   471
     * @see AccessibleObject#setAccessible(boolean)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   472
     * @see java.lang.invoke.MethodHandles#privateLookupIn
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   473
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   474
    public boolean isOpen(String pn, Module other) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   475
        Objects.requireNonNull(pn);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   476
        Objects.requireNonNull(other);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   477
        return implIsExportedOrOpen(pn, other, /*open*/true);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   478
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   479
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   480
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   481
     * Returns {@code true} if this module exports the given package
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   482
     * unconditionally.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   483
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   484
     * <p> This method always returns {@code true} when invoked on an unnamed
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   485
     * module. A package that is {@link #isOpen(String) opened} unconditionally
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   486
     * is considered exported unconditionally at run-time and so this method
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   487
     * returns {@code true} if the package is opened unconditionally. </p>
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   488
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   489
     * <p> This method does not check if the given module reads this module. </p>
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   490
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   491
     * @param  pn
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   492
     *         The package name
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   493
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   494
     * @return {@code true} if this module exports the package unconditionally
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   495
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   496
     * @see ModuleDescriptor#exports()
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   497
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   498
    public boolean isExported(String pn) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   499
        Objects.requireNonNull(pn);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   500
        return implIsExportedOrOpen(pn, EVERYONE_MODULE, /*open*/false);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   501
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   502
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   503
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   504
     * Returns {@code true} if this module has <em>opened</em> a package
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   505
     * unconditionally.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   506
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   507
     * <p> This method always returns {@code true} when invoked on an unnamed
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   508
     * module. Additionally, it always returns {@code true} when invoked on an
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   509
     * {@link ModuleDescriptor#isOpen open} module with a package in the
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   510
     * module. </p>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   511
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   512
     * <p> This method does not check if the given module reads this module. </p>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   513
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   514
     * @param  pn
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   515
     *         The package name
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   516
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   517
     * @return {@code true} if this module has <em>opened</em> the package
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   518
     *         unconditionally
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   519
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   520
     * @see ModuleDescriptor#opens()
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   521
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   522
    public boolean isOpen(String pn) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   523
        Objects.requireNonNull(pn);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   524
        return implIsExportedOrOpen(pn, EVERYONE_MODULE, /*open*/true);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   525
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   526
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   527
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   528
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   529
     * Returns {@code true} if this module exports or opens the given package
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   530
     * to the given module. If the other module is {@code EVERYONE_MODULE} then
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   531
     * this method tests if the package is exported or opened unconditionally.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   532
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   533
    private boolean implIsExportedOrOpen(String pn, Module other, boolean open) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   534
        // all packages in unnamed modules are open
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   535
        if (!isNamed())
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   536
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   537
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   538
        // all packages are exported/open to self
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   539
        if (other == this && containsPackage(pn))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   540
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   541
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   542
        // all packages in open modules are open
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   543
        if (descriptor.isOpen())
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   544
            return containsPackage(pn);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   545
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   546
        // exported/opened via module declaration/descriptor
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   547
        if (isStaticallyExportedOrOpen(pn, other, open))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   548
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   549
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   550
        // exported via addExports/addOpens
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   551
        if (isReflectivelyExportedOrOpen(pn, other, open))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   552
            return true;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   553
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   554
        // not exported or open to other
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   555
        return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   556
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   557
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   558
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   559
     * Returns {@code true} if this module exports or opens a package to
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   560
     * the given module via its module declaration.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   561
     */
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   562
    boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   563
        // package is open to everyone or <other>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   564
        Map<String, Set<Module>> openPackages = this.openPackages;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   565
        if (openPackages != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   566
            Set<Module> targets = openPackages.get(pn);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   567
            if (targets != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   568
                if (targets.contains(EVERYONE_MODULE))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   569
                    return true;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   570
                if (other != EVERYONE_MODULE && targets.contains(other))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   571
                    return true;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   572
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   573
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   574
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   575
        if (!open) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   576
            // package is exported to everyone or <other>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   577
            Map<String, Set<Module>> exportedPackages = this.exportedPackages;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   578
            if (exportedPackages != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   579
                Set<Module> targets = exportedPackages.get(pn);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   580
                if (targets != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   581
                    if (targets.contains(EVERYONE_MODULE))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   582
                        return true;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   583
                    if (other != EVERYONE_MODULE && targets.contains(other))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   584
                        return true;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   585
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   586
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   587
        }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   588
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   589
        return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   590
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   591
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   592
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   593
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   594
     * Returns {@code true} if this module reflectively exports or opens given
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   595
     * package package to the given module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   596
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   597
    private boolean isReflectivelyExportedOrOpen(String pn, Module other, boolean open) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   598
        // exported or open to all modules
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   599
        Map<String, Boolean> exports = reflectivelyExports.get(this, EVERYONE_MODULE);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   600
        if (exports != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   601
            Boolean b = exports.get(pn);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   602
            if (b != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   603
                boolean isOpen = b.booleanValue();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   604
                if (!open || isOpen) return true;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   605
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   606
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   607
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   608
        if (other != EVERYONE_MODULE) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   609
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   610
            // exported or open to other
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   611
            exports = reflectivelyExports.get(this, other);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   612
            if (exports != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   613
                Boolean b = exports.get(pn);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   614
                if (b != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   615
                    boolean isOpen = b.booleanValue();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   616
                    if (!open || isOpen) return true;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   617
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   618
            }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   619
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   620
            // other is an unnamed module && exported or open to all unnamed
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   621
            if (!other.isNamed()) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   622
                exports = reflectivelyExports.get(this, ALL_UNNAMED_MODULE);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   623
                if (exports != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   624
                    Boolean b = exports.get(pn);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   625
                    if (b != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   626
                        boolean isOpen = b.booleanValue();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   627
                        if (!open || isOpen) return true;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   628
                    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   629
                }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   630
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   631
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   632
        }
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   633
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   634
        return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   635
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   636
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   637
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   638
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   639
     * If the caller's module is this module then update this module to export
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   640
     * the given package to the given module.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   641
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   642
     * <p> This method has no effect if the package is already exported (or
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   643
     * <em>open</em>) to the given module. It also has no effect if
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   644
     * invoked on an {@link ModuleDescriptor#isOpen open} module. </p>
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   645
     *
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   646
     * @apiNote As specified in section 5.4.3 of the <cite>The Java&trade;
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   647
     * Virtual Machine Specification </cite>, if an attempt to resolve a
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   648
     * symbolic reference fails because of a linkage error, then subsequent
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   649
     * attempts to resolve the reference always fail with the same error that
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   650
     * was thrown as a result of the initial resolution attempt.
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   651
     *
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   652
     * @param  pn
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   653
     *         The package name
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   654
     * @param  other
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   655
     *         The module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   656
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   657
     * @return this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   658
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   659
     * @throws IllegalArgumentException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   660
     *         If {@code pn} is {@code null}, or this is a named module and the
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   661
     *         package {@code pn} is not a package in this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   662
     * @throws IllegalStateException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   663
     *         If this is a named module and the caller is not this module
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   664
     *
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   665
     * @jvms 5.4.3 Resolution
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   666
     * @see #isExported(String,Module)
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   667
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   668
    @CallerSensitive
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   669
    public Module addExports(String pn, Module other) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   670
        if (pn == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   671
            throw new IllegalArgumentException("package is null");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   672
        Objects.requireNonNull(other);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   673
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   674
        if (isNamed() && !descriptor.isOpen()) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   675
            Module caller = Reflection.getCallerClass().getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   676
            if (caller != this) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   677
                throw new IllegalStateException(caller + " != " + this);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   678
            }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   679
            implAddExportsOrOpens(pn, other, /*open*/false, /*syncVM*/true);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   680
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   681
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   682
        return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   683
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   684
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   685
    /**
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   686
     * If this module has <em>opened</em> a package to at least the caller
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   687
     * module then update this module to open the package to the given module.
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   688
     * Opening a package with this method allows all types in the package,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   689
     * and all their members, not just public types and their public members,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   690
     * to be reflected on by the given module when using APIs that support
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   691
     * private access or a way to bypass or suppress default Java language
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   692
     * access control checks.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   693
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   694
     * <p> This method has no effect if the package is already <em>open</em>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   695
     * to the given module. It also has no effect if invoked on an {@link
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   696
     * ModuleDescriptor#isOpen open} module. </p>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   697
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   698
     * @param  pn
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   699
     *         The package name
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   700
     * @param  other
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   701
     *         The module
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   702
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   703
     * @return this module
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   704
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   705
     * @throws IllegalArgumentException
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   706
     *         If {@code pn} is {@code null}, or this is a named module and the
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   707
     *         package {@code pn} is not a package in this module
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   708
     * @throws IllegalStateException
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   709
     *         If this is a named module and this module has not opened the
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   710
     *         package to at least the caller
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   711
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   712
     * @see #isOpen(String,Module)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   713
     * @see AccessibleObject#setAccessible(boolean)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   714
     * @see java.lang.invoke.MethodHandles#privateLookupIn
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   715
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   716
    @CallerSensitive
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   717
    public Module addOpens(String pn, Module other) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   718
        if (pn == null)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   719
            throw new IllegalArgumentException("package is null");
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   720
        Objects.requireNonNull(other);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   721
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   722
        if (isNamed() && !descriptor.isOpen()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   723
            Module caller = Reflection.getCallerClass().getModule();
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   724
            if (caller != this && !isOpen(pn, caller))
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
   725
                throw new IllegalStateException(pn + " is not open to " + caller);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   726
            implAddExportsOrOpens(pn, other, /*open*/true, /*syncVM*/true);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   727
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   728
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   729
        return this;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   730
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   731
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   732
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   733
    /**
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   734
     * Updates the exports so that package {@code pn} is exported to module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   735
     * {@code other} but without notifying the VM.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   736
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   737
     * @apiNote This method is for VM white-box testing.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   738
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   739
    void implAddExportsNoSync(String pn, Module other) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   740
        if (other == null)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   741
            other = EVERYONE_MODULE;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   742
        implAddExportsOrOpens(pn.replace('/', '.'), other, false, false);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   743
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   744
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   745
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   746
     * Updates the exports so that package {@code pn} is exported to module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   747
     * {@code other}.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   748
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   749
     * @apiNote This method is for white-box testing.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   750
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   751
    void implAddExports(String pn, Module other) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   752
        implAddExportsOrOpens(pn, other, false, true);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   753
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   754
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   755
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   756
     * Updates the module to open package {@code pn} to module {@code other}.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   757
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   758
     * @apiNote This method is for white-box tests and jtreg
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   759
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   760
    void implAddOpens(String pn, Module other) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   761
        implAddExportsOrOpens(pn, other, true, true);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   762
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   763
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   764
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   765
     * Updates a module to export or open a module to another module.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   766
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   767
     * If {@code syncVM} is {@code true} then the VM is notified.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   768
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   769
    private void implAddExportsOrOpens(String pn,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   770
                                       Module other,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   771
                                       boolean open,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   772
                                       boolean syncVM) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   773
        Objects.requireNonNull(other);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   774
        Objects.requireNonNull(pn);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   775
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   776
        // all packages are open in unnamed and open modules
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   777
        if (!isNamed() || descriptor.isOpen())
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   778
            return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   779
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   780
        // nothing to do if already exported/open to other
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   781
        if (implIsExportedOrOpen(pn, other, open))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   782
            return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   783
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   784
        // can only export a package in the module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   785
        if (!containsPackage(pn)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   786
            throw new IllegalArgumentException("package " + pn
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   787
                                               + " not in contents");
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   788
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   789
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   790
        // update VM first, just in case it fails
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   791
        if (syncVM) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   792
            String pkgInternalForm = pn.replace('.', '/');
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   793
            if (other == EVERYONE_MODULE) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   794
                addExportsToAll0(this, pkgInternalForm);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   795
            } else if (other == ALL_UNNAMED_MODULE) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   796
                addExportsToAllUnnamed0(this, pkgInternalForm);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   797
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   798
                addExports0(this, pkgInternalForm, other);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   799
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   800
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   801
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   802
        // add package name to reflectivelyExports if absent
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   803
        Map<String, Boolean> map = reflectivelyExports
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   804
            .computeIfAbsent(this, other,
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   805
                             (m1, m2) -> new ConcurrentHashMap<>());
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   806
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   807
        if (open) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   808
            map.put(pn, Boolean.TRUE);  // may need to promote from FALSE to TRUE
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   809
        } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   810
            map.putIfAbsent(pn, Boolean.FALSE);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   811
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   812
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   813
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   814
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   815
    // -- services --
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   816
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   817
    // additional service type (2nd key) that some module (1st key) uses
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   818
    private static final WeakPairMap<Module, Class<?>, Boolean> reflectivelyUses
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
   819
        = new WeakPairMap<>();
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   820
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   821
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   822
     * If the caller's module is this module then update this module to add a
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   823
     * service dependence on the given service type. This method is intended
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   824
     * for use by frameworks that invoke {@link java.util.ServiceLoader
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   825
     * ServiceLoader} on behalf of other modules or where the framework is
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   826
     * passed a reference to the service type by other code. This method is
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   827
     * a no-op when invoked on an unnamed module or an automatic module.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   828
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   829
     * <p> This method does not cause {@link
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   830
     * Configuration#resolveRequiresAndUses resolveRequiresAndUses} to be
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   831
     * re-run. </p>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   832
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   833
     * @param  service
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   834
     *         The service type
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   835
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   836
     * @return this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   837
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   838
     * @throws IllegalStateException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   839
     *         If this is a named module and the caller is not this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   840
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   841
     * @see #canUse(Class)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   842
     * @see ModuleDescriptor#uses()
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   843
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   844
    @CallerSensitive
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   845
    public Module addUses(Class<?> service) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   846
        Objects.requireNonNull(service);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   847
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   848
        if (isNamed() && !descriptor.isAutomatic()) {
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   849
            Module caller = Reflection.getCallerClass().getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   850
            if (caller != this) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   851
                throw new IllegalStateException(caller + " != " + this);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   852
            }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   853
            implAddUses(service);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   854
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   855
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   856
        return this;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   857
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   858
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   859
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   860
     * Update this module to add a service dependence on the given service
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   861
     * type.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   862
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   863
    void implAddUses(Class<?> service) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   864
        if (!canUse(service)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   865
            reflectivelyUses.putIfAbsent(this, service, Boolean.TRUE);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   866
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   867
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   868
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   869
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   870
    /**
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   871
     * Indicates if this module has a service dependence on the given service
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   872
     * type. This method always returns {@code true} when invoked on an unnamed
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   873
     * module or an automatic module.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   874
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   875
     * @param  service
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   876
     *         The service type
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   877
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   878
     * @return {@code true} if this module uses service type {@code st}
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   879
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   880
     * @see #addUses(Class)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   881
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   882
    public boolean canUse(Class<?> service) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   883
        Objects.requireNonNull(service);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   884
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   885
        if (!isNamed())
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   886
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   887
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   888
        if (descriptor.isAutomatic())
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   889
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   890
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   891
        // uses was declared
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   892
        if (descriptor.uses().contains(service.getName()))
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   893
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   894
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   895
        // uses added via addUses
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   896
        return reflectivelyUses.containsKeyPair(this, service);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   897
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   898
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   899
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   900
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   901
    // -- packages --
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   902
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   903
    // Additional packages that are added to the module at run-time.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   904
    // The field is volatile as it may be replaced at run-time
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   905
    private volatile Set<String> extraPackages;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   906
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   907
    private boolean containsPackage(String pn) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   908
        if (descriptor.packages().contains(pn))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   909
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   910
        Set<String> extraPackages = this.extraPackages;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   911
        if (extraPackages != null && extraPackages.contains(pn))
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   912
            return true;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   913
        return false;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   914
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   915
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   916
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   917
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   918
     * Returns an array of the package names of the packages in this module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   919
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   920
     * <p> For named modules, the returned array contains an element for each
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   921
     * package in the module. It may contain elements corresponding to packages
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   922
     * added to the module, <a href="Proxy.html#dynamicmodule">dynamic modules</a>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   923
     * for example, after it was loaded.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   924
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   925
     * <p> For unnamed modules, this method is the equivalent of invoking the
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   926
     * {@link ClassLoader#getDefinedPackages() getDefinedPackages} method of
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   927
     * this module's class loader and returning the array of package names. </p>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   928
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   929
     * <p> A package name appears at most once in the returned array. </p>
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   930
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   931
     * @apiNote This method returns an array rather than a {@code Set} for
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   932
     * consistency with other {@code java.lang.reflect} types.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   933
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   934
     * @return an array of the package names of the packages in this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   935
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   936
    public String[] getPackages() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   937
        if (isNamed()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   938
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   939
            Set<String> packages = descriptor.packages();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   940
            Set<String> extraPackages = this.extraPackages;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   941
            if (extraPackages == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   942
                return packages.toArray(new String[0]);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   943
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   944
                return Stream.concat(packages.stream(),
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   945
                                     extraPackages.stream())
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   946
                        .toArray(String[]::new);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   947
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   948
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   949
        } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   950
            // unnamed module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   951
            Stream<Package> packages;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   952
            if (loader == null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   953
                packages = BootLoader.packages();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   954
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   955
                packages = SharedSecrets.getJavaLangAccess().packages(loader);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   956
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   957
            return packages.map(Package::getName).toArray(String[]::new);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   958
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   959
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   960
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   961
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   962
     * Add a package to this module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   963
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   964
     * @apiNote This method is for Proxy use.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   965
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   966
     * @apiNote This is an expensive operation, not expected to be used often.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   967
     * At this time then it does not validate that the package name is a
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   968
     * valid java identifier.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   969
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   970
    void addPackage(String pn) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   971
        implAddPackage(pn, true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   972
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   973
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   974
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   975
     * Add a package to this module without notifying the VM.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   976
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   977
     * @apiNote This method is VM white-box testing.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   978
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   979
    void implAddPackageNoSync(String pn) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   980
        implAddPackage(pn.replace('/', '.'), false);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   981
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   982
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   983
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   984
     * Add a package to this module.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   985
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   986
     * If {@code syncVM} is {@code true} then the VM is notified.
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   987
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   988
    private void implAddPackage(String pn, boolean syncVM) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   989
        if (!isNamed())
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   990
            throw new InternalError("adding package to unnamed module?");
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   991
        if (descriptor.isOpen())
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   992
            throw new InternalError("adding package to open module?");
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   993
        if (pn.isEmpty())
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
   994
            throw new InternalError("adding <unnamed> package to module?");
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   995
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   996
        if (descriptor.packages().contains(pn)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   997
            // already in module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   998
            return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
   999
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1000
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1001
        Set<String> extraPackages = this.extraPackages;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1002
        if (extraPackages != null && extraPackages.contains(pn)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1003
            // already added
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1004
            return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1005
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1006
        synchronized (this) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1007
            // recheck under lock
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1008
            extraPackages = this.extraPackages;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1009
            if (extraPackages != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1010
                if (extraPackages.contains(pn)) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1011
                    // already added
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1012
                    return;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1013
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1014
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1015
                // copy the set
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1016
                extraPackages = new HashSet<>(extraPackages);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1017
                extraPackages.add(pn);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1018
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1019
                extraPackages = Collections.singleton(pn);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1020
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1021
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1022
            // update VM first, just in case it fails
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1023
            if (syncVM)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1024
                addPackage0(this, pn.replace('.', '/'));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1025
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1026
            // replace with new set
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1027
            this.extraPackages = extraPackages; // volatile write
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1028
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1029
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1030
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1031
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1032
    // -- creating Module objects --
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1033
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1034
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1035
     * Defines all module in a configuration to the runtime.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1036
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1037
     * @return a map of module name to runtime {@code Module}
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1038
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1039
     * @throws IllegalArgumentException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1040
     *         If defining any of the modules to the VM fails
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1041
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1042
    static Map<String, Module> defineModules(Configuration cf,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1043
                                             Function<String, ClassLoader> clf,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1044
                                             Layer layer)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1045
    {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1046
        Map<String, Module> nameToModule = new HashMap<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1047
        Map<String, ClassLoader> moduleToLoader = new HashMap<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1048
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1049
        boolean isBootLayer = (Layer.boot() == null);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1050
        Set<ClassLoader> loaders = new HashSet<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1051
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1052
        // map each module to a class loader
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1053
        for (ResolvedModule resolvedModule : cf.modules()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1054
            String name = resolvedModule.name();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1055
            ClassLoader loader = clf.apply(name);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1056
            if (loader != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1057
                moduleToLoader.put(name, loader);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1058
                loaders.add(loader);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1059
            } else if (!isBootLayer) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1060
                throw new IllegalArgumentException("loader can't be 'null'");
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1061
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1062
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1063
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1064
        // define each module in the configuration to the VM
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1065
        for (ResolvedModule resolvedModule : cf.modules()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1066
            ModuleReference mref = resolvedModule.reference();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1067
            ModuleDescriptor descriptor = mref.descriptor();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1068
            String name = descriptor.name();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1069
            URI uri = mref.location().orElse(null);
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1070
            ClassLoader loader = moduleToLoader.get(resolvedModule.name());
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1071
            Module m;
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1072
            if (loader == null && isBootLayer && name.equals("java.base")) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1073
                // java.base is already defined to the VM
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1074
                m = Object.class.getModule();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1075
            } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1076
                m = new Module(layer, loader, descriptor, uri);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1077
            }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1078
            nameToModule.put(name, m);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1079
            moduleToLoader.put(name, loader);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1080
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1081
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1082
        // setup readability and exports
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1083
        for (ResolvedModule resolvedModule : cf.modules()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1084
            ModuleReference mref = resolvedModule.reference();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1085
            ModuleDescriptor descriptor = mref.descriptor();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1086
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1087
            String mn = descriptor.name();
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1088
            Module m = nameToModule.get(mn);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1089
            assert m != null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1090
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1091
            // reads
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1092
            Set<Module> reads = new HashSet<>();
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1093
            for (ResolvedModule other : resolvedModule.reads()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1094
                Module m2 = null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1095
                if (other.configuration() == cf) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1096
                    String dn = other.reference().descriptor().name();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1097
                    m2 = nameToModule.get(dn);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1098
                } else {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1099
                    for (Layer parent: layer.parents()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1100
                        m2 = findModule(parent, other);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1101
                        if (m2 != null)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1102
                            break;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1103
                    }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1104
                }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1105
                assert m2 != null;
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1106
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1107
                reads.add(m2);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1108
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1109
                // update VM view
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1110
                addReads0(m, m2);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1111
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1112
            m.reads = reads;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1113
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1114
            // automatic modules read all unnamed modules
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1115
            if (descriptor.isAutomatic()) {
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
  1116
                m.implAddReads(ALL_UNNAMED_MODULE, true);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1117
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1118
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1119
            // exports and opens
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1120
            initExportsAndOpens(descriptor, nameToModule, m);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1121
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1122
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1123
        // register the modules in the boot layer
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1124
        if (isBootLayer) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1125
            for (ResolvedModule resolvedModule : cf.modules()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1126
                ModuleReference mref = resolvedModule.reference();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1127
                ModuleDescriptor descriptor = mref.descriptor();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1128
                if (!descriptor.provides().isEmpty()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1129
                    String name = descriptor.name();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1130
                    Module m = nameToModule.get(name);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1131
                    ClassLoader loader = moduleToLoader.get(name);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1132
                    ServicesCatalog catalog;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1133
                    if (loader == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1134
                        catalog = BootLoader.getServicesCatalog();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1135
                    } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1136
                        catalog = ServicesCatalog.getServicesCatalog(loader);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1137
                    }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1138
                    catalog.register(m);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1139
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1140
            }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1141
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1142
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1143
        // record that there is a layer with modules defined to the class loader
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1144
        for (ClassLoader loader : loaders) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1145
            layer.bindToLoader(loader);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1146
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1147
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1148
        return nameToModule;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1149
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1150
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1151
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1152
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1153
     * Find the runtime Module corresponding to the given ResolvedModule
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1154
     * in the given parent layer (or its parents).
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1155
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1156
    private static Module findModule(Layer parent, ResolvedModule resolvedModule) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1157
        Configuration cf = resolvedModule.configuration();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1158
        String dn = resolvedModule.name();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1159
        return parent.layers()
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1160
                .filter(l -> l.configuration() == cf)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1161
                .findAny()
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1162
                .map(layer -> {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1163
                    Optional<Module> om = layer.findModule(dn);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1164
                    assert om.isPresent() : dn + " not found in layer";
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1165
                    Module m = om.get();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1166
                    assert m.getLayer() == layer : m + " not in expected layer";
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1167
                    return m;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1168
                })
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1169
                .orElse(null);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1170
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1171
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1172
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1173
     * Initialize the maps of exported and open packages for module m.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1174
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1175
    private static void initExportsAndOpens(ModuleDescriptor descriptor,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1176
                                            Map<String, Module> nameToModule,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1177
                                            Module m)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1178
    {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1179
        // The VM doesn't know about open modules so need to export all packages
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1180
        if (descriptor.isOpen()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1181
            assert descriptor.opens().isEmpty();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1182
            for (String source : descriptor.packages()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1183
                String sourceInternalForm = source.replace('.', '/');
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1184
                addExportsToAll0(m, sourceInternalForm);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1185
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1186
            return;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1187
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1188
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1189
        Map<String, Set<Module>> openPackages = new HashMap<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1190
        Map<String, Set<Module>> exportedPackages = new HashMap<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1191
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1192
        // process the open packages first
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1193
        for (Opens opens : descriptor.opens()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1194
            String source = opens.source();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1195
            String sourceInternalForm = source.replace('.', '/');
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1196
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1197
            if (opens.isQualified()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1198
                // qualified opens
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1199
                Set<Module> targets = new HashSet<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1200
                for (String target : opens.targets()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1201
                    // only open to modules that are in this configuration
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1202
                    Module m2 = nameToModule.get(target);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1203
                    if (m2 != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1204
                        addExports0(m, sourceInternalForm, m2);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1205
                        targets.add(m2);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1206
                    }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1207
                }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1208
                if (!targets.isEmpty()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1209
                    openPackages.put(source, targets);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1210
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1211
            } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1212
                // unqualified opens
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1213
                addExportsToAll0(m, sourceInternalForm);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1214
                openPackages.put(source, EVERYONE_SET);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1215
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1216
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1217
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1218
        // next the exports, skipping exports when the package is open
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1219
        for (Exports exports : descriptor.exports()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1220
            String source = exports.source();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1221
            String sourceInternalForm = source.replace('.', '/');
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1222
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1223
            // skip export if package is already open to everyone
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1224
            Set<Module> openToTargets = openPackages.get(source);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1225
            if (openToTargets != null && openToTargets.contains(EVERYONE_MODULE))
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1226
                continue;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1227
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1228
            if (exports.isQualified()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1229
                // qualified exports
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1230
                Set<Module> targets = new HashSet<>();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1231
                for (String target : exports.targets()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1232
                    // only export to modules that are in this configuration
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1233
                    Module m2 = nameToModule.get(target);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1234
                    if (m2 != null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1235
                        // skip qualified export if already open to m2
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1236
                        if (openToTargets == null || !openToTargets.contains(m2)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1237
                            addExports0(m, sourceInternalForm, m2);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1238
                            targets.add(m2);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1239
                        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1240
                    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1241
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1242
                if (!targets.isEmpty()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1243
                    exportedPackages.put(source, targets);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1244
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1245
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1246
            } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1247
                // unqualified exports
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1248
                addExportsToAll0(m, sourceInternalForm);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1249
                exportedPackages.put(source, EVERYONE_SET);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1250
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1251
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1252
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1253
        if (!openPackages.isEmpty())
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1254
            m.openPackages = openPackages;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1255
        if (!exportedPackages.isEmpty())
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1256
            m.exportedPackages = exportedPackages;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1257
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1258
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1259
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1260
    // -- annotations --
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1261
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1262
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1263
     * {@inheritDoc}
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1264
     * This method returns {@code null} when invoked on an unnamed module.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1265
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1266
    @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1267
    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1268
        return moduleInfoClass().getDeclaredAnnotation(annotationClass);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1269
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1270
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1271
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1272
     * {@inheritDoc}
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1273
     * This method returns an empty array when invoked on an unnamed module.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1274
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1275
    @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1276
    public Annotation[] getAnnotations() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1277
        return moduleInfoClass().getAnnotations();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1278
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1279
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1280
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1281
     * {@inheritDoc}
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1282
     * This method returns an empty array when invoked on an unnamed module.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1283
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1284
    @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1285
    public Annotation[] getDeclaredAnnotations() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1286
        return moduleInfoClass().getDeclaredAnnotations();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1287
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1288
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1289
    // cached class file with annotations
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1290
    private volatile Class<?> moduleInfoClass;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1291
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1292
    private Class<?> moduleInfoClass() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1293
        Class<?> clazz = this.moduleInfoClass;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1294
        if (clazz != null)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1295
            return clazz;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1296
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1297
        synchronized (this) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1298
            clazz = this.moduleInfoClass;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1299
            if (clazz == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1300
                if (isNamed()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1301
                    PrivilegedAction<Class<?>> pa = this::loadModuleInfoClass;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1302
                    clazz = AccessController.doPrivileged(pa);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1303
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1304
                if (clazz == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1305
                    class DummyModuleInfo { }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1306
                    clazz = DummyModuleInfo.class;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1307
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1308
                this.moduleInfoClass = clazz;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1309
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1310
            return clazz;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1311
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1312
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1313
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1314
    private Class<?> loadModuleInfoClass() {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1315
        Class<?> clazz = null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1316
        try (InputStream in = getResourceAsStream("module-info.class")) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1317
            if (in != null)
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1318
                clazz = loadModuleInfoClass(in);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1319
        } catch (Exception ignore) { }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1320
        return clazz;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1321
    }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1322
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1323
    /**
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1324
     * Loads module-info.class as a package-private interface in a class loader
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1325
     * that is a child of this module's class loader.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1326
     */
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1327
    private Class<?> loadModuleInfoClass(InputStream in) throws IOException {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1328
        final String MODULE_INFO = "module-info";
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1329
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1330
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1331
                                         + ClassWriter.COMPUTE_FRAMES);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1332
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1333
        ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1334
            @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1335
            public void visit(int version,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1336
                              int access,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1337
                              String name,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1338
                              String signature,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1339
                              String superName,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1340
                              String[] interfaces) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1341
                cw.visit(version,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1342
                        Opcodes.ACC_INTERFACE
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1343
                            + Opcodes.ACC_ABSTRACT
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1344
                            + Opcodes.ACC_SYNTHETIC,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1345
                        MODULE_INFO,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1346
                        null,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1347
                        "java/lang/Object",
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1348
                        null);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1349
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1350
            @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1351
            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1352
                // keep annotations
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1353
                return super.visitAnnotation(desc, visible);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1354
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1355
            @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1356
            public void visitAttribute(Attribute attr) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1357
                // drop non-annotation attributes
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1358
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1359
        };
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1360
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1361
        ClassReader cr = new ClassReader(in);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1362
        cr.accept(cv, 0);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1363
        byte[] bytes = cw.toByteArray();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1364
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1365
        ClassLoader cl = new ClassLoader(loader) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1366
            @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1367
            protected Class<?> findClass(String cn)throws ClassNotFoundException {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1368
                if (cn.equals(MODULE_INFO)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1369
                    return super.defineClass(cn, bytes, 0, bytes.length);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1370
                } else {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1371
                    throw new ClassNotFoundException(cn);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1372
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1373
            }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1374
        };
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1375
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1376
        try {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1377
            return cl.loadClass(MODULE_INFO);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1378
        } catch (ClassNotFoundException e) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1379
            throw new InternalError(e);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1380
        }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1381
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1382
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1383
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1384
    // -- misc --
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1385
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1386
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1387
    /**
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1388
     * Returns an input stream for reading a resource in this module. The
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1389
     * {@code name} parameter is a {@code '/'}-separated path name that
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1390
     * identifies the resource.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1391
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1392
     * <p> A resource in a named modules may be <em>encapsulated</em> so that
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1393
     * it cannot be located by code in other modules. Whether a resource can be
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1394
     * located or not is determined as follows:
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1395
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1396
     * <ul>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1397
     *     <li> The <em>package name</em> of the resource is derived from the
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1398
     *     subsequence of characters that precedes the last {@code '/'} and then
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1399
     *     replacing each {@code '/'} character in the subsequence with
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1400
     *     {@code '.'}. For example, the package name derived for a resource
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1401
     *     named "{@code a/b/c/foo.properties}" is "{@code a.b.c}". </li>
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1402
     *
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1403
     *     <li> If the package name is a package in the module then the package
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1404
     *     must be {@link #isOpen open} the module of the caller of this method.
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1405
     *     If the package is not in the module then the resource is not
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1406
     *     encapsulated. Resources in the unnamed package or "{@code META-INF}",
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1407
     *     for example, are never encapsulated because they can never be
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1408
     *     packages in a named module. </li>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1409
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1410
     *     <li> As a special case, resources ending with "{@code .class}" are
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1411
     *     never encapsulated. </li>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1412
     * </ul>
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1413
     *
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1414
     * <p> This method returns {@code null} if the resource is not in this
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1415
     * module, the resource is encapsulated and cannot be located by the caller,
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1416
     * or access to the resource is denied by the security manager.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1417
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1418
     * @param  name
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1419
     *         The resource name
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1420
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1421
     * @return An input stream for reading the resource or {@code null}
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1422
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1423
     * @throws IOException
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1424
     *         If an I/O error occurs
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1425
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1426
     * @see java.lang.module.ModuleReader#open(String)
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1427
     */
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1428
    @CallerSensitive
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1429
    public InputStream getResourceAsStream(String name) throws IOException {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1430
        Objects.requireNonNull(name);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1431
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1432
        if (isNamed() && !ResourceHelper.isSimpleResource(name)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1433
            Module caller = Reflection.getCallerClass().getModule();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1434
            if (caller != this && caller != Object.class.getModule()) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1435
                // ignore packages added for proxies via addPackage
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1436
                Set<String> packages = getDescriptor().packages();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1437
                String pn = ResourceHelper.getPackageName(name);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1438
                if (packages.contains(pn) && !isOpen(pn, caller)) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1439
                    // resource is in package not open to caller
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1440
                    return null;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1441
                }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1442
            }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1443
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1444
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1445
        String mn = this.name;
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1446
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1447
        // special-case built-in class loaders to avoid URL connection
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1448
        if (loader == null) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1449
            return BootLoader.findResourceAsStream(mn, name);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1450
        } else if (loader instanceof BuiltinClassLoader) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1451
            return ((BuiltinClassLoader) loader).findResourceAsStream(mn, name);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1452
        }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1453
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1454
        // locate resource in module
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1455
        JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1456
        URL url = jla.findResource(loader, mn, name);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1457
        if (url != null) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1458
            try {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1459
                return url.openStream();
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1460
            } catch (SecurityException e) { }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1461
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1462
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1463
        return null;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1464
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1465
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1466
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1467
     * Returns the string representation of this module. For a named module,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1468
     * the representation is the string {@code "module"}, followed by a space,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1469
     * and then the module name. For an unnamed module, the representation is
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1470
     * the string {@code "unnamed module"}, followed by a space, and then an
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
  1471
     * implementation specific string that identifies the unnamed module.
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1472
     *
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1473
     * @return The string representation of this module
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1474
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1475
    @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1476
    public String toString() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1477
        if (isNamed()) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1478
            return "module " + name;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1479
        } else {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1480
            String id = Integer.toHexString(System.identityHashCode(this));
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1481
            return "unnamed module @" + id;
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1482
        }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1483
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1484
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1485
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1486
    // -- native methods --
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1487
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1488
    // JVM_DefineModule
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1489
    private static native void defineModule0(Module module,
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1490
                                             boolean isOpen,
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1491
                                             String version,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1492
                                             String location,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1493
                                             String[] pns);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1494
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1495
    // JVM_AddReadsModule
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1496
    private static native void addReads0(Module from, Module to);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1497
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1498
    // JVM_AddModuleExports
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1499
    private static native void addExports0(Module from, String pn, Module to);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1500
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1501
    // JVM_AddModuleExportsToAll
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1502
    private static native void addExportsToAll0(Module from, String pn);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1503
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1504
    // JVM_AddModuleExportsToAllUnnamed
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1505
    private static native void addExportsToAllUnnamed0(Module from, String pn);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1506
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1507
    // JVM_AddModulePackage
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1508
    private static native void addPackage0(Module m, String pn);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1509
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1510
    /**
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1511
     * Register shared secret to provide access to package-private methods
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1512
     */
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1513
    static {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1514
        SharedSecrets.setJavaLangReflectModuleAccess(
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1515
            new JavaLangReflectModuleAccess() {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1516
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1517
                public Module defineUnnamedModule(ClassLoader loader) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1518
                    return new Module(loader);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1519
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1520
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1521
                public Module defineModule(ClassLoader loader,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1522
                                           ModuleDescriptor descriptor,
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1523
                                           URI uri) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1524
                   return new Module(null, loader, descriptor, uri);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1525
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1526
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1527
                public void addReads(Module m1, Module m2) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1528
                    m1.implAddReads(m2, true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1529
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1530
                @Override
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
  1531
                public void addReadsAllUnnamed(Module m) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
  1532
                    m.implAddReads(Module.ALL_UNNAMED_MODULE);
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
  1533
                }
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
  1534
                @Override
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1535
                public void addExports(Module m, String pn, Module other) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1536
                    m.implAddExportsOrOpens(pn, other, false, true);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1537
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1538
                @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1539
                public void addOpens(Module m, String pn, Module other) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1540
                    m.implAddExportsOrOpens(pn, other, true, true);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1541
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1542
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1543
                public void addExportsToAll(Module m, String pn) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1544
                    m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1545
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1546
                @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1547
                public void addOpensToAll(Module m, String pn) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1548
                    m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1549
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1550
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1551
                public void addExportsToAllUnnamed(Module m, String pn) {
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1552
                    m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1553
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1554
                @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1555
                public void addOpensToAllUnnamed(Module m, String pn) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1556
                    m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1557
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1558
                @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1559
                public void addUses(Module m, Class<?> service) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1560
                    m.implAddUses(service);
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1561
                }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1562
                @Override
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1563
                public void addPackage(Module m, String pn) {
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1564
                    m.implAddPackage(pn, true);
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1565
                }
37779
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
  1566
                @Override
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
  1567
                public ServicesCatalog getServicesCatalog(Layer layer) {
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
  1568
                    return layer.getServicesCatalog();
7c84df693837 8154956: Module system implementation refresh (4/2016)
alanb
parents: 37363
diff changeset
  1569
                }
42338
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1570
                @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1571
                public Stream<Layer> layers(Layer layer) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1572
                    return layer.layers();
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1573
                }
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1574
                @Override
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1575
                public Stream<Layer> layers(ClassLoader loader) {
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1576
                    return Layer.layers(loader);
a60f280f803c 8169069: Module system implementation refresh (11/2016)
alanb
parents: 38564
diff changeset
  1577
                }
42703
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
  1578
                @Override
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
  1579
                public boolean isStaticallyExported(Module module, String pn, Module other) {
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
  1580
                    return module.isStaticallyExportedOrOpen(pn, other, false);
20c39ea4a507 8170987: Module system implementation refresh (12/2016)
alanb
parents: 42338
diff changeset
  1581
                }
36511
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1582
            });
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1583
    }
9d0388c6b336 8142968: Module System implementation
alanb
parents:
diff changeset
  1584
}