Umod.java revision 11833:1cbffa2beba6
1/*
2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26/*
27 * @test
28 * @summary class p1.c1 defined in m1 tries to access p2.c2 defined in unnamed module.
29 * @library /test/lib
30 * @modules java.base/jdk.internal.misc
31 * @modules java.base/jdk.internal.module
32 * @compile myloaders/MySameClassLoader.java
33 * @compile p2/c2.java
34 * @compile p1/c1.java
35 * @compile p1/c1ReadEdge.java
36 * @compile p1/c1Loose.java
37 * @run main/othervm -Xbootclasspath/a:. Umod
38 */
39
40import static jdk.test.lib.Asserts.*;
41
42import java.lang.reflect.Layer;
43import java.lang.module.Configuration;
44import java.lang.module.ModuleDescriptor;
45import java.lang.module.ModuleFinder;
46import java.lang.reflect.Module;
47import java.util.HashMap;
48import java.util.Map;
49import java.util.Set;
50import myloaders.MySameClassLoader;
51
52//
53// ClassLoader1 --> defines m1 --> packages p1
54//                  package p1 in m1 is exported unqualifiedly
55//
56// class p1.c1 defined in m1 tries to access p2.c2 defined in
57// in unnamed module.
58//
59// Three access attempts occur in this test:
60//   1. The first access is not allowed because a strict module
61//      cannot read an unnamed module.
62//   2. In this scenario a strict module establishes readability
63//      to the particular unnamed module it is trying to access.
64//      Access is allowed.
65//   3. Module m1 in the test_looseModuleLayer() method
66//      is transitioned to a loose module, access
67//      to all unnamed modules is allowed.
68//
69public class Umod {
70
71 // Create Layers over the boot layer to test different
72 // accessing scenarios of a named module to an unnamed module.
73
74 // Module m1 is a strict module and has not established
75 // readability to an unnamed module that p2.c2 is defined in.
76 public void test_strictModuleLayer() throws Throwable {
77
78     // Define module:     m1
79     // Can read:          java.base
80     // Packages:          p1
81     // Packages exported: p1 is exported unqualifiedly
82     ModuleDescriptor descriptor_m1 =
83             new ModuleDescriptor.Builder("m1")
84                     .requires("java.base")
85                     .exports("p1")
86                     .build();
87
88     // Set up a ModuleFinder containing all modules for this layer.
89     ModuleFinder finder = ModuleLibrary.of(descriptor_m1);
90
91     // Resolves "m1"
92     Configuration cf = Layer.boot()
93             .configuration()
94             .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
95
96     // map module m1 to class loader.
97     // class c2 will be loaded in an unnamed module/loader.
98     MySameClassLoader loader = new MySameClassLoader();
99     Map<String, ClassLoader> map = new HashMap<>();
100     map.put("m1", loader);
101
102     // Create Layer that contains m1
103     Layer layer = Layer.boot().defineModules(cf, map::get);
104
105     assertTrue(layer.findLoader("m1") == loader);
106     assertTrue(layer.findLoader("java.base") == null);
107
108     // now use the same loader to load class p1.c1
109     Class p1_c1_class = loader.loadClass("p1.c1");
110
111     // Attempt access
112     try {
113         p1_c1_class.newInstance();
114         throw new RuntimeException("Test Failed, strict module m1, type p1.c1, should not be able " +
115                                    "to access public type p2.c2 defined in unnamed module");
116     } catch (IllegalAccessError e) {
117     }
118 }
119
120 // Module m1 is a strict module and has established
121 // readability to an unnamed module that p2.c2 is defined in.
122 public void test_strictModuleUnnamedReadableLayer() throws Throwable {
123
124     // Define module:     m1
125     // Can read:          java.base
126     // Packages:          p1
127     // Packages exported: p1 is exported unqualifiedly
128     ModuleDescriptor descriptor_m1 =
129             new ModuleDescriptor.Builder("m1")
130                     .requires("java.base")
131                     .exports("p1")
132                     .build();
133
134     // Set up a ModuleFinder containing all modules for this layer.
135     ModuleFinder finder = ModuleLibrary.of(descriptor_m1);
136
137     // Resolves "m1"
138     Configuration cf = Layer.boot()
139             .configuration()
140             .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
141
142     MySameClassLoader loader = new MySameClassLoader();
143     // map module m1 to class loader.
144     // class c2 will be loaded in an unnamed module/loader.
145     Map<String, ClassLoader> map = new HashMap<>();
146     map.put("m1", loader);
147
148     // Create Layer that contains m1
149     Layer layer = Layer.boot().defineModules(cf, map::get);
150
151     assertTrue(layer.findLoader("m1") == loader);
152     assertTrue(layer.findLoader("java.base") == null);
153
154     // now use the same loader to load class p1.c1ReadEdge
155     Class p1_c1_class = loader.loadClass("p1.c1ReadEdge");
156
157     try {
158       // Read edge between m1 and the unnamed module that loads p2.c2 is established in
159       // c1ReadEdge's ctor before attempting access.
160       p1_c1_class.newInstance();
161     } catch (IllegalAccessError e) {
162         throw new RuntimeException("Test Failed, strict module m1, type p1.c1ReadEdge, should be able to acccess public type " +
163                                    "p2.c2 defined in unnamed module: " + e.getMessage());
164     }
165}
166
167 // Module m1 is a loose module and thus can read all unnamed modules.
168 public void test_looseModuleLayer() throws Throwable {
169
170     // Define module:     m1
171     // Can read:          java.base
172     // Packages:          p1
173     // Packages exported: p1 is exported unqualifiedly
174     ModuleDescriptor descriptor_m1 =
175             new ModuleDescriptor.Builder("m1")
176                     .requires("java.base")
177                     .exports("p1")
178                     .build();
179
180     // Set up a ModuleFinder containing all modules for this layer.
181     ModuleFinder finder = ModuleLibrary.of(descriptor_m1);
182
183     // Resolves "m1"
184     Configuration cf = Layer.boot()
185             .configuration()
186             .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
187
188     MySameClassLoader loader = new MySameClassLoader();
189     // map module m1 to class loader.
190     // class c2 will be loaded in an unnamed module/loader.
191     Map<String, ClassLoader> map = new HashMap<>();
192     map.put("m1", loader);
193
194     // Create Layer that contains m1
195     Layer layer = Layer.boot().defineModules(cf, map::get);
196
197     assertTrue(layer.findLoader("m1") == loader);
198     assertTrue(layer.findLoader("java.base") == null);
199
200     // now use the same loader to load class p1.c1Loose
201     Class p1_c1_class = loader.loadClass("p1.c1Loose");
202
203     // change m1 to read all unnamed modules
204     Module m1 = layer.findModule("m1").get();
205     jdk.internal.module.Modules.addReadsAllUnnamed(m1);
206
207     try {
208         p1_c1_class.newInstance();
209     } catch (IllegalAccessError e) {
210         throw new RuntimeException("Test Failed, strict module m1, type p1.c1Loose, should be able to acccess public type " +
211                                    "p2.c2 defined in unnamed module: " + e.getMessage());
212     }
213 }
214
215 public static void main(String args[]) throws Throwable {
216   Umod test = new Umod();
217   test.test_strictModuleLayer();                // access denied
218   test.test_strictModuleUnnamedReadableLayer(); // access allowed
219   test.test_looseModuleLayer();                 // access allowed
220 }
221}
222