|
1 /* |
|
2 * Copyright (c) 2014, 2017, 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. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 */ |
|
23 |
|
24 /** |
|
25 * @test |
|
26 * @library /lib/testlibrary |
|
27 * @modules java.base/jdk.internal.misc |
|
28 * @build BasicLayerTest ModuleUtils |
|
29 * @compile layertest/Test.java |
|
30 * @run testng BasicLayerTest |
|
31 * @summary Basic tests for java.lang.ModuleLayer |
|
32 */ |
|
33 |
|
34 import java.lang.module.Configuration; |
|
35 import java.lang.module.ModuleDescriptor; |
|
36 import java.lang.module.ModuleDescriptor.Requires; |
|
37 import java.lang.module.ModuleFinder; |
|
38 import java.util.HashMap; |
|
39 import java.util.Map; |
|
40 import java.util.Optional; |
|
41 import java.util.Set; |
|
42 import java.util.stream.Collectors; |
|
43 |
|
44 import jdk.internal.misc.SharedSecrets; |
|
45 |
|
46 import org.testng.annotations.DataProvider; |
|
47 import org.testng.annotations.Test; |
|
48 import static org.testng.Assert.*; |
|
49 |
|
50 @Test |
|
51 public class BasicLayerTest { |
|
52 |
|
53 /** |
|
54 * Creates a "non-strict" builder for building a module. This allows the |
|
55 * test the create ModuleDescriptor objects that do not require java.base. |
|
56 */ |
|
57 private static ModuleDescriptor.Builder newBuilder(String mn) { |
|
58 return SharedSecrets.getJavaLangModuleAccess() |
|
59 .newModuleBuilder(mn, false, Set.of()); |
|
60 } |
|
61 |
|
62 /** |
|
63 * Exercise ModuleLayer.empty() |
|
64 */ |
|
65 public void testEmpty() { |
|
66 ModuleLayer emptyLayer = ModuleLayer.empty(); |
|
67 |
|
68 assertTrue(emptyLayer.parents().isEmpty()); |
|
69 |
|
70 assertTrue(emptyLayer.configuration() == Configuration.empty()); |
|
71 |
|
72 assertTrue(emptyLayer.modules().isEmpty()); |
|
73 |
|
74 assertFalse(emptyLayer.findModule("java.base").isPresent()); |
|
75 |
|
76 try { |
|
77 emptyLayer.findLoader("java.base"); |
|
78 assertTrue(false); |
|
79 } catch (IllegalArgumentException expected) { } |
|
80 } |
|
81 |
|
82 |
|
83 /** |
|
84 * Exercise ModuleLayer.boot() |
|
85 */ |
|
86 public void testBoot() { |
|
87 ModuleLayer bootLayer = ModuleLayer.boot(); |
|
88 |
|
89 // configuration |
|
90 Configuration cf = bootLayer.configuration(); |
|
91 assertTrue(cf.findModule("java.base").get() |
|
92 .reference() |
|
93 .descriptor() |
|
94 .exports() |
|
95 .stream().anyMatch(e -> (e.source().equals("java.lang") |
|
96 && !e.isQualified()))); |
|
97 |
|
98 // modules |
|
99 Set<Module> modules = bootLayer.modules(); |
|
100 assertTrue(modules.contains(Object.class.getModule())); |
|
101 int count = (int) modules.stream().map(Module::getName).count(); |
|
102 assertEquals(count, modules.size()); // module names are unique |
|
103 |
|
104 // findModule |
|
105 Module base = Object.class.getModule(); |
|
106 assertTrue(bootLayer.findModule("java.base").get() == base); |
|
107 assertTrue(base.getLayer() == bootLayer); |
|
108 |
|
109 // findLoader |
|
110 assertTrue(bootLayer.findLoader("java.base") == null); |
|
111 |
|
112 // parents |
|
113 assertTrue(bootLayer.parents().size() == 1); |
|
114 assertTrue(bootLayer.parents().get(0) == ModuleLayer.empty()); |
|
115 } |
|
116 |
|
117 |
|
118 /** |
|
119 * Exercise defineModules, created with empty layer as parent |
|
120 */ |
|
121 public void testLayerOnEmpty() { |
|
122 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
123 .requires("m2") |
|
124 .exports("p1") |
|
125 .build(); |
|
126 |
|
127 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
128 .requires("m3") |
|
129 .build(); |
|
130 |
|
131 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
132 .build(); |
|
133 |
|
134 ModuleFinder finder |
|
135 = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); |
|
136 |
|
137 Configuration cf = resolve(finder, "m1"); |
|
138 |
|
139 // map each module to its own class loader for this test |
|
140 ClassLoader loader1 = new ClassLoader() { }; |
|
141 ClassLoader loader2 = new ClassLoader() { }; |
|
142 ClassLoader loader3 = new ClassLoader() { }; |
|
143 Map<String, ClassLoader> map = new HashMap<>(); |
|
144 map.put("m1", loader1); |
|
145 map.put("m2", loader2); |
|
146 map.put("m3", loader3); |
|
147 |
|
148 ModuleLayer layer = ModuleLayer.empty().defineModules(cf, map::get); |
|
149 |
|
150 // configuration |
|
151 assertTrue(layer.configuration() == cf); |
|
152 assertTrue(layer.configuration().modules().size() == 3); |
|
153 |
|
154 // modules |
|
155 Set<Module> modules = layer.modules(); |
|
156 assertTrue(modules.size() == 3); |
|
157 Set<String> names = modules.stream() |
|
158 .map(Module::getName) |
|
159 .collect(Collectors.toSet()); |
|
160 assertTrue(names.contains("m1")); |
|
161 assertTrue(names.contains("m2")); |
|
162 assertTrue(names.contains("m3")); |
|
163 |
|
164 // findModule |
|
165 Module m1 = layer.findModule("m1").get(); |
|
166 Module m2 = layer.findModule("m2").get(); |
|
167 Module m3 = layer.findModule("m3").get(); |
|
168 assertEquals(m1.getName(), "m1"); |
|
169 assertEquals(m2.getName(), "m2"); |
|
170 assertEquals(m3.getName(), "m3"); |
|
171 assertTrue(m1.getDescriptor() == descriptor1); |
|
172 assertTrue(m2.getDescriptor() == descriptor2); |
|
173 assertTrue(m3.getDescriptor() == descriptor3); |
|
174 assertTrue(m1.getLayer() == layer); |
|
175 assertTrue(m2.getLayer() == layer); |
|
176 assertTrue(m3.getLayer() == layer); |
|
177 assertTrue(modules.contains(m1)); |
|
178 assertTrue(modules.contains(m2)); |
|
179 assertTrue(modules.contains(m3)); |
|
180 assertFalse(layer.findModule("godot").isPresent()); |
|
181 |
|
182 // findLoader |
|
183 assertTrue(layer.findLoader("m1") == loader1); |
|
184 assertTrue(layer.findLoader("m2") == loader2); |
|
185 assertTrue(layer.findLoader("m3") == loader3); |
|
186 try { |
|
187 ClassLoader loader = layer.findLoader("godot"); |
|
188 assertTrue(false); |
|
189 } catch (IllegalArgumentException ignore) { } |
|
190 |
|
191 // parents |
|
192 assertTrue(layer.parents().size() == 1); |
|
193 assertTrue(layer.parents().get(0) == ModuleLayer.empty()); |
|
194 } |
|
195 |
|
196 |
|
197 /** |
|
198 * Exercise defineModules, created with boot layer as parent |
|
199 */ |
|
200 public void testLayerOnBoot() { |
|
201 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
202 .requires("m2") |
|
203 .requires("java.base") |
|
204 .exports("p1") |
|
205 .build(); |
|
206 |
|
207 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
208 .requires("java.base") |
|
209 .build(); |
|
210 |
|
211 ModuleFinder finder |
|
212 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
213 |
|
214 Configuration parent = ModuleLayer.boot().configuration(); |
|
215 Configuration cf = resolve(parent, finder, "m1"); |
|
216 |
|
217 ClassLoader loader = new ClassLoader() { }; |
|
218 |
|
219 ModuleLayer layer = ModuleLayer.boot().defineModules(cf, mn -> loader); |
|
220 |
|
221 // configuration |
|
222 assertTrue(layer.configuration() == cf); |
|
223 assertTrue(layer.configuration().modules().size() == 2); |
|
224 |
|
225 // modules |
|
226 Set<Module> modules = layer.modules(); |
|
227 assertTrue(modules.size() == 2); |
|
228 Set<String> names = modules.stream() |
|
229 .map(Module::getName) |
|
230 .collect(Collectors.toSet()); |
|
231 assertTrue(names.contains("m1")); |
|
232 assertTrue(names.contains("m2")); |
|
233 |
|
234 // findModule |
|
235 Module m1 = layer.findModule("m1").get(); |
|
236 Module m2 = layer.findModule("m2").get(); |
|
237 assertEquals(m1.getName(), "m1"); |
|
238 assertEquals(m2.getName(), "m2"); |
|
239 assertTrue(m1.getDescriptor() == descriptor1); |
|
240 assertTrue(m2.getDescriptor() == descriptor2); |
|
241 assertTrue(m1.getLayer() == layer); |
|
242 assertTrue(m2.getLayer() == layer); |
|
243 assertTrue(modules.contains(m1)); |
|
244 assertTrue(modules.contains(m2)); |
|
245 assertTrue(layer.findModule("java.base").get() == Object.class.getModule()); |
|
246 assertFalse(layer.findModule("godot").isPresent()); |
|
247 |
|
248 // findLoader |
|
249 assertTrue(layer.findLoader("m1") == loader); |
|
250 assertTrue(layer.findLoader("m2") == loader); |
|
251 assertTrue(layer.findLoader("java.base") == null); |
|
252 |
|
253 // parents |
|
254 assertTrue(layer.parents().size() == 1); |
|
255 assertTrue(layer.parents().get(0) == ModuleLayer.boot()); |
|
256 } |
|
257 |
|
258 |
|
259 /** |
|
260 * Exercise defineModules with a configuration of two modules that |
|
261 * have the same module-private package. |
|
262 */ |
|
263 public void testPackageContainedInSelfAndOther() { |
|
264 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
265 .requires("m2") |
|
266 .packages(Set.of("p")) |
|
267 .build(); |
|
268 |
|
269 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
270 .packages(Set.of("p")) |
|
271 .build(); |
|
272 |
|
273 ModuleFinder finder |
|
274 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
275 |
|
276 Configuration cf = resolve(finder, "m1"); |
|
277 assertTrue(cf.modules().size() == 2); |
|
278 |
|
279 // one loader per module, should be okay |
|
280 ModuleLayer.empty().defineModules(cf, mn -> new ClassLoader() { }); |
|
281 |
|
282 // same class loader |
|
283 try { |
|
284 ClassLoader loader = new ClassLoader() { }; |
|
285 ModuleLayer.empty().defineModules(cf, mn -> loader); |
|
286 assertTrue(false); |
|
287 } catch (LayerInstantiationException expected) { } |
|
288 } |
|
289 |
|
290 |
|
291 /** |
|
292 * Exercise defineModules with a configuration that is a partitioned |
|
293 * graph. The same package is exported in both partitions. |
|
294 */ |
|
295 public void testSameExportInPartitionedGraph() { |
|
296 |
|
297 // m1 reads m2, m2 exports p to m1 |
|
298 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
299 .requires("m2") |
|
300 .build(); |
|
301 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
302 .exports("p", Set.of("m1")) |
|
303 .build(); |
|
304 |
|
305 // m3 reads m4, m4 exports p to m3 |
|
306 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
307 .requires("m4") |
|
308 .build(); |
|
309 ModuleDescriptor descriptor4 = newBuilder("m4") |
|
310 .exports("p", Set.of("m3")) |
|
311 .build(); |
|
312 |
|
313 ModuleFinder finder |
|
314 = ModuleUtils.finderOf(descriptor1, |
|
315 descriptor2, |
|
316 descriptor3, |
|
317 descriptor4); |
|
318 |
|
319 Configuration cf = resolve(finder, "m1", "m3"); |
|
320 assertTrue(cf.modules().size() == 4); |
|
321 |
|
322 // one loader per module |
|
323 ModuleLayer.empty().defineModules(cf, mn -> new ClassLoader() { }); |
|
324 |
|
325 // m1 & m2 in one loader, m3 & m4 in another loader |
|
326 ClassLoader loader1 = new ClassLoader() { }; |
|
327 ClassLoader loader2 = new ClassLoader() { }; |
|
328 Map<String, ClassLoader> map = new HashMap<>(); |
|
329 map.put("m1", loader1); |
|
330 map.put("m2", loader1); |
|
331 map.put("m3", loader2); |
|
332 map.put("m4", loader2); |
|
333 ModuleLayer.empty().defineModules(cf, map::get); |
|
334 |
|
335 // same loader |
|
336 try { |
|
337 ClassLoader loader = new ClassLoader() { }; |
|
338 ModuleLayer.empty().defineModules(cf, mn -> loader); |
|
339 assertTrue(false); |
|
340 } catch (LayerInstantiationException expected) { } |
|
341 } |
|
342 |
|
343 |
|
344 /** |
|
345 * Exercise defineModules with a configuration with a module that |
|
346 * contains a package that is the same name as a non-exported package in |
|
347 * a parent layer. |
|
348 */ |
|
349 public void testContainsSamePackageAsBootLayer() { |
|
350 |
|
351 // check assumption that java.base contains sun.launcher |
|
352 ModuleDescriptor base = Object.class.getModule().getDescriptor(); |
|
353 assertTrue(base.packages().contains("sun.launcher")); |
|
354 |
|
355 ModuleDescriptor descriptor = newBuilder("m1") |
|
356 .requires("java.base") |
|
357 .packages(Set.of("sun.launcher")) |
|
358 .build(); |
|
359 |
|
360 ModuleFinder finder = ModuleUtils.finderOf(descriptor); |
|
361 |
|
362 Configuration parent = ModuleLayer.boot().configuration(); |
|
363 Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1")); |
|
364 assertTrue(cf.modules().size() == 1); |
|
365 |
|
366 ClassLoader loader = new ClassLoader() { }; |
|
367 ModuleLayer layer = ModuleLayer.boot().defineModules(cf, mn -> loader); |
|
368 assertTrue(layer.modules().size() == 1); |
|
369 } |
|
370 |
|
371 |
|
372 /** |
|
373 * Test layers with implied readability. |
|
374 * |
|
375 * The test consists of three configurations: |
|
376 * - Configuration/layer1: m1, m2 requires transitive m1 |
|
377 * - Configuration/layer2: m3 requires m1 |
|
378 */ |
|
379 public void testImpliedReadabilityWithLayers1() { |
|
380 |
|
381 // cf1: m1 and m2, m2 requires transitive m1 |
|
382 |
|
383 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
384 .build(); |
|
385 |
|
386 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
387 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") |
|
388 .build(); |
|
389 |
|
390 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
391 |
|
392 Configuration cf1 = resolve(finder1, "m2"); |
|
393 |
|
394 ClassLoader cl1 = new ClassLoader() { }; |
|
395 ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1); |
|
396 |
|
397 |
|
398 // cf2: m3, m3 requires m2 |
|
399 |
|
400 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
401 .requires("m2") |
|
402 .build(); |
|
403 |
|
404 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3); |
|
405 |
|
406 Configuration cf2 = resolve(cf1, finder2, "m3"); |
|
407 |
|
408 ClassLoader cl2 = new ClassLoader() { }; |
|
409 ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
410 |
|
411 assertTrue(layer1.parents().size() == 1); |
|
412 assertTrue(layer1.parents().get(0) == ModuleLayer.empty()); |
|
413 |
|
414 assertTrue(layer2.parents().size() == 1); |
|
415 assertTrue(layer2.parents().get(0) == layer1); |
|
416 |
|
417 Module m1 = layer2.findModule("m1").get(); |
|
418 Module m2 = layer2.findModule("m2").get(); |
|
419 Module m3 = layer2.findModule("m3").get(); |
|
420 |
|
421 assertTrue(m1.getLayer() == layer1); |
|
422 assertTrue(m2.getLayer() == layer1); |
|
423 assertTrue(m3.getLayer() == layer2); |
|
424 |
|
425 assertTrue(m1.getClassLoader() == cl1); |
|
426 assertTrue(m2.getClassLoader() == cl1); |
|
427 assertTrue(m3.getClassLoader() == cl2); |
|
428 |
|
429 assertTrue(m1.canRead(m1)); |
|
430 assertFalse(m1.canRead(m2)); |
|
431 assertFalse(m1.canRead(m3)); |
|
432 |
|
433 assertTrue(m2.canRead(m1)); |
|
434 assertTrue(m2.canRead(m2)); |
|
435 assertFalse(m2.canRead(m3)); |
|
436 |
|
437 assertTrue(m3.canRead(m1)); |
|
438 assertTrue(m3.canRead(m2)); |
|
439 assertTrue(m3.canRead(m3)); |
|
440 } |
|
441 |
|
442 |
|
443 /** |
|
444 * Test layers with implied readability. |
|
445 * |
|
446 * The test consists of three configurations: |
|
447 * - Configuration/layer1: m1 |
|
448 * - Configuration/layer2: m2 requires transitive m3, m3 requires m2 |
|
449 */ |
|
450 public void testImpliedReadabilityWithLayers2() { |
|
451 |
|
452 // cf1: m1 |
|
453 |
|
454 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
455 |
|
456 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
457 |
|
458 Configuration cf1 = resolve(finder1, "m1"); |
|
459 |
|
460 ClassLoader cl1 = new ClassLoader() { }; |
|
461 ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1); |
|
462 |
|
463 |
|
464 // cf2: m2, m3: m2 requires transitive m1, m3 requires m2 |
|
465 |
|
466 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
467 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") |
|
468 .build(); |
|
469 |
|
470 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
471 .requires("m2") |
|
472 .build(); |
|
473 |
|
474 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3); |
|
475 |
|
476 Configuration cf2 = resolve(cf1, finder2, "m3"); |
|
477 |
|
478 ClassLoader cl2 = new ClassLoader() { }; |
|
479 ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
480 |
|
481 assertTrue(layer1.parents().size() == 1); |
|
482 assertTrue(layer1.parents().get(0) == ModuleLayer.empty()); |
|
483 |
|
484 assertTrue(layer2.parents().size() == 1); |
|
485 assertTrue(layer2.parents().get(0) == layer1); |
|
486 |
|
487 Module m1 = layer2.findModule("m1").get(); |
|
488 Module m2 = layer2.findModule("m2").get(); |
|
489 Module m3 = layer2.findModule("m3").get(); |
|
490 |
|
491 assertTrue(m1.getLayer() == layer1); |
|
492 assertTrue(m2.getLayer() == layer2); |
|
493 assertTrue(m3.getLayer() == layer2); |
|
494 |
|
495 assertTrue(m1.canRead(m1)); |
|
496 assertFalse(m1.canRead(m2)); |
|
497 assertFalse(m1.canRead(m3)); |
|
498 |
|
499 assertTrue(m2.canRead(m1)); |
|
500 assertTrue(m2.canRead(m2)); |
|
501 assertFalse(m2.canRead(m3)); |
|
502 |
|
503 assertTrue(m3.canRead(m1)); |
|
504 assertTrue(m3.canRead(m2)); |
|
505 assertTrue(m3.canRead(m3)); |
|
506 } |
|
507 |
|
508 |
|
509 /** |
|
510 * Test layers with implied readability. |
|
511 * |
|
512 * The test consists of three configurations: |
|
513 * - Configuration/layer1: m1 |
|
514 * - Configuration/layer2: m2 requires transitive m1 |
|
515 * - Configuration/layer3: m3 requires m1 |
|
516 */ |
|
517 public void testImpliedReadabilityWithLayers3() { |
|
518 |
|
519 // cf1: m1 |
|
520 |
|
521 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
522 |
|
523 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
524 |
|
525 Configuration cf1 = resolve(finder1, "m1"); |
|
526 |
|
527 ClassLoader cl1 = new ClassLoader() { }; |
|
528 ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1); |
|
529 |
|
530 |
|
531 // cf2: m2 requires transitive m1 |
|
532 |
|
533 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
534 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") |
|
535 .build(); |
|
536 |
|
537 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); |
|
538 |
|
539 Configuration cf2 = resolve(cf1, finder2, "m2"); |
|
540 |
|
541 ClassLoader cl2 = new ClassLoader() { }; |
|
542 ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
543 |
|
544 |
|
545 // cf3: m3 requires m2 |
|
546 |
|
547 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
548 .requires("m2") |
|
549 .build(); |
|
550 |
|
551 ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3); |
|
552 |
|
553 Configuration cf3 = resolve(cf2, finder3, "m3"); |
|
554 |
|
555 ClassLoader cl3 = new ClassLoader() { }; |
|
556 ModuleLayer layer3 = layer2.defineModules(cf3, mn -> cl3); |
|
557 |
|
558 assertTrue(layer1.parents().size() == 1); |
|
559 assertTrue(layer1.parents().get(0) == ModuleLayer.empty()); |
|
560 |
|
561 assertTrue(layer2.parents().size() == 1); |
|
562 assertTrue(layer2.parents().get(0) == layer1); |
|
563 |
|
564 assertTrue(layer3.parents().size() == 1); |
|
565 assertTrue(layer3.parents().get(0) == layer2); |
|
566 |
|
567 Module m1 = layer3.findModule("m1").get(); |
|
568 Module m2 = layer3.findModule("m2").get(); |
|
569 Module m3 = layer3.findModule("m3").get(); |
|
570 |
|
571 assertTrue(m1.getLayer() == layer1); |
|
572 assertTrue(m2.getLayer() == layer2); |
|
573 assertTrue(m3.getLayer() == layer3); |
|
574 |
|
575 assertTrue(m1.canRead(m1)); |
|
576 assertFalse(m1.canRead(m2)); |
|
577 assertFalse(m1.canRead(m3)); |
|
578 |
|
579 assertTrue(m2.canRead(m1)); |
|
580 assertTrue(m2.canRead(m2)); |
|
581 assertFalse(m2.canRead(m3)); |
|
582 |
|
583 assertTrue(m3.canRead(m1)); |
|
584 assertTrue(m3.canRead(m2)); |
|
585 assertTrue(m3.canRead(m3)); |
|
586 } |
|
587 |
|
588 |
|
589 /** |
|
590 * Test layers with implied readability. |
|
591 * |
|
592 * The test consists of two configurations: |
|
593 * - Configuration/layer1: m1, m2 requires transitive m1 |
|
594 * - Configuration/layer2: m3 requires transitive m2, m4 requires m3 |
|
595 */ |
|
596 public void testImpliedReadabilityWithLayers4() { |
|
597 |
|
598 // cf1: m1, m2 requires transitive m1 |
|
599 |
|
600 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
601 .build(); |
|
602 |
|
603 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
604 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") |
|
605 .build(); |
|
606 |
|
607 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
608 |
|
609 Configuration cf1 = resolve(finder1, "m2"); |
|
610 |
|
611 ClassLoader cl1 = new ClassLoader() { }; |
|
612 ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1); |
|
613 |
|
614 |
|
615 // cf2: m3 requires transitive m2, m4 requires m3 |
|
616 |
|
617 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
618 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m2") |
|
619 .build(); |
|
620 |
|
621 ModuleDescriptor descriptor4 = newBuilder("m4") |
|
622 .requires("m3") |
|
623 .build(); |
|
624 |
|
625 |
|
626 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4); |
|
627 |
|
628 Configuration cf2 = resolve(cf1, finder2, "m3", "m4"); |
|
629 |
|
630 ClassLoader cl2 = new ClassLoader() { }; |
|
631 ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
632 |
|
633 assertTrue(layer1.parents().size() == 1); |
|
634 assertTrue(layer1.parents().get(0) == ModuleLayer.empty()); |
|
635 |
|
636 assertTrue(layer2.parents().size() == 1); |
|
637 assertTrue(layer2.parents().get(0) == layer1); |
|
638 |
|
639 Module m1 = layer2.findModule("m1").get(); |
|
640 Module m2 = layer2.findModule("m2").get(); |
|
641 Module m3 = layer2.findModule("m3").get(); |
|
642 Module m4 = layer2.findModule("m4").get(); |
|
643 |
|
644 assertTrue(m1.getLayer() == layer1); |
|
645 assertTrue(m2.getLayer() == layer1); |
|
646 assertTrue(m3.getLayer() == layer2); |
|
647 assertTrue(m4.getLayer() == layer2); |
|
648 |
|
649 assertTrue(m1.canRead(m1)); |
|
650 assertFalse(m1.canRead(m2)); |
|
651 assertFalse(m1.canRead(m3)); |
|
652 assertFalse(m1.canRead(m4)); |
|
653 |
|
654 assertTrue(m2.canRead(m1)); |
|
655 assertTrue(m2.canRead(m2)); |
|
656 assertFalse(m1.canRead(m3)); |
|
657 assertFalse(m1.canRead(m4)); |
|
658 |
|
659 assertTrue(m3.canRead(m1)); |
|
660 assertTrue(m3.canRead(m2)); |
|
661 assertTrue(m3.canRead(m3)); |
|
662 assertFalse(m3.canRead(m4)); |
|
663 |
|
664 assertTrue(m4.canRead(m1)); |
|
665 assertTrue(m4.canRead(m2)); |
|
666 assertTrue(m4.canRead(m3)); |
|
667 assertTrue(m4.canRead(m4)); |
|
668 } |
|
669 |
|
670 |
|
671 /** |
|
672 * Test layers with a qualified export. The module exporting the package |
|
673 * does not read the target module. |
|
674 * |
|
675 * m1 { exports p to m2 } |
|
676 * m2 { } |
|
677 */ |
|
678 public void testQualifiedExports1() { |
|
679 ModuleDescriptor descriptor1 = newBuilder("m1"). |
|
680 exports("p", Set.of("m2")) |
|
681 .build(); |
|
682 |
|
683 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
684 .build(); |
|
685 |
|
686 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
687 |
|
688 Configuration cf = resolve(finder1, "m1", "m2"); |
|
689 |
|
690 ClassLoader cl = new ClassLoader() { }; |
|
691 ModuleLayer layer = ModuleLayer.empty().defineModules(cf, mn -> cl); |
|
692 assertTrue(layer.modules().size() == 2); |
|
693 |
|
694 Module m1 = layer.findModule("m1").get(); |
|
695 Module m2 = layer.findModule("m2").get(); |
|
696 |
|
697 // check m1 exports p to m2 |
|
698 assertFalse(m1.isExported("p")); |
|
699 assertTrue(m1.isExported("p", m2)); |
|
700 assertFalse(m1.isOpen("p", m2)); |
|
701 } |
|
702 |
|
703 |
|
704 /** |
|
705 * Test layers with a qualified export. The module exporting the package |
|
706 * reads the target module. |
|
707 * |
|
708 * m1 { exports p to m2; } |
|
709 * m2 { requires m1; } |
|
710 */ |
|
711 public void testQualifiedExports2() { |
|
712 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
713 .exports("p", Set.of("m2")) |
|
714 .build(); |
|
715 |
|
716 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
717 .requires("m1") |
|
718 .build(); |
|
719 |
|
720 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
721 |
|
722 Configuration cf = resolve(finder1, "m2"); |
|
723 ClassLoader cl = new ClassLoader() { }; |
|
724 ModuleLayer layer = ModuleLayer.empty().defineModules(cf, mn -> cl); |
|
725 assertTrue(layer.modules().size() == 2); |
|
726 |
|
727 Module m1 = layer.findModule("m1").get(); |
|
728 Module m2 = layer.findModule("m2").get(); |
|
729 |
|
730 // check m1 exports p to m2 |
|
731 assertFalse(m1.isExported("p")); |
|
732 assertTrue(m1.isExported("p", m2)); |
|
733 assertFalse(m1.isOpen("p", m2)); |
|
734 } |
|
735 |
|
736 |
|
737 /** |
|
738 * Test layers with a qualified export. The module exporting the package |
|
739 * does not read the target module in the parent layer. |
|
740 * |
|
741 * - Configuration/layer1: m1 { } |
|
742 * - Configuration/layer2: m2 { exports p to m1; } |
|
743 */ |
|
744 public void testQualifiedExports3() { |
|
745 // create layer1 with m1 |
|
746 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
747 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
748 Configuration cf1 = resolve(finder1, "m1"); |
|
749 ClassLoader cl1 = new ClassLoader() { }; |
|
750 ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1); |
|
751 assertTrue(layer1.modules().size() == 1); |
|
752 |
|
753 // create layer2 with m2 |
|
754 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
755 .exports("p", Set.of("m1")) |
|
756 .build(); |
|
757 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); |
|
758 Configuration cf2 = resolve(cf1, finder2, "m2"); |
|
759 ClassLoader cl2 = new ClassLoader() { }; |
|
760 ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
761 assertTrue(layer2.modules().size() == 1); |
|
762 |
|
763 Module m1 = layer1.findModule("m1").get(); |
|
764 Module m2 = layer2.findModule("m2").get(); |
|
765 |
|
766 // check m2 exports p to layer1/m1 |
|
767 assertFalse(m2.isExported("p")); |
|
768 assertTrue(m2.isExported("p", m1)); |
|
769 assertFalse(m2.isOpen("p", m1)); |
|
770 } |
|
771 |
|
772 |
|
773 /** |
|
774 * Test layers with a qualified export. The module exporting the package |
|
775 * reads the target module in the parent layer. |
|
776 * |
|
777 * - Configuration/layer1: m1 { } |
|
778 * - Configuration/layer2: m2 { requires m1; exports p to m1; } |
|
779 */ |
|
780 public void testQualifiedExports4() { |
|
781 // create layer1 with m1 |
|
782 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
783 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
784 Configuration cf1 = resolve(finder1, "m1"); |
|
785 ClassLoader cl1 = new ClassLoader() { }; |
|
786 ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1); |
|
787 assertTrue(layer1.modules().size() == 1); |
|
788 |
|
789 // create layer2 with m2 |
|
790 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
791 .requires("m1") |
|
792 .exports("p", Set.of("m1")) |
|
793 .build(); |
|
794 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); |
|
795 Configuration cf2 = resolve(cf1, finder2, "m2"); |
|
796 ClassLoader cl2 = new ClassLoader() { }; |
|
797 ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
798 assertTrue(layer2.modules().size() == 1); |
|
799 |
|
800 Module m1 = layer1.findModule("m1").get(); |
|
801 Module m2 = layer2.findModule("m2").get(); |
|
802 |
|
803 // check m2 exports p to layer1/m1 |
|
804 assertFalse(m2.isExported("p")); |
|
805 assertTrue(m2.isExported("p", m1)); |
|
806 assertFalse(m2.isOpen("p", m1)); |
|
807 } |
|
808 |
|
809 /** |
|
810 * Test layers with a qualified export. The module exporting the package |
|
811 * does not read the target module. |
|
812 * |
|
813 * - Configuration/layer1: m1 |
|
814 * - Configuration/layer2: m1, m2 { exports p to m1; } |
|
815 */ |
|
816 public void testQualifiedExports5() { |
|
817 // create layer1 with m1 |
|
818 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
819 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
820 Configuration cf1 = resolve(finder1, "m1"); |
|
821 ClassLoader cl1 = new ClassLoader() { }; |
|
822 ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1); |
|
823 assertTrue(layer1.modules().size() == 1); |
|
824 |
|
825 // create layer2 with m1 and m2 |
|
826 ModuleDescriptor descriptor2 = newBuilder("m2").exports("p", Set.of("m1")).build(); |
|
827 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
828 Configuration cf2 = resolve(cf1, finder2, "m1", "m2"); |
|
829 ClassLoader cl2 = new ClassLoader() { }; |
|
830 ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
831 assertTrue(layer2.modules().size() == 2); |
|
832 |
|
833 Module m1_v1 = layer1.findModule("m1").get(); |
|
834 Module m1_v2 = layer2.findModule("m1").get(); |
|
835 Module m2 = layer2.findModule("m2").get(); |
|
836 |
|
837 // check m2 exports p to layer2/m2 |
|
838 assertFalse(m2.isExported("p")); |
|
839 assertTrue(m2.isExported("p", m1_v2)); |
|
840 assertFalse(m2.isExported("p", m1_v1)); |
|
841 } |
|
842 |
|
843 |
|
844 /** |
|
845 * Test layers with a qualified export. The module exporting the package |
|
846 * reads the target module in the parent layer (due to requires transitive). |
|
847 * |
|
848 * - Configuration/layer1: m1, m2 { requires transitive m1; } |
|
849 * - Configuration/layer2: m1, m3 { requires m2; exports p to m1; } |
|
850 */ |
|
851 public void testQualifiedExports6() { |
|
852 // create layer1 with m1 and m2 |
|
853 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
854 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
855 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") |
|
856 .build(); |
|
857 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); |
|
858 Configuration cf1 = resolve(finder1, "m2"); |
|
859 ClassLoader loader1 = new ClassLoader() { }; |
|
860 ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> loader1); |
|
861 assertTrue(layer1.modules().size() == 2); |
|
862 |
|
863 // create layer2 with m1 and m3 |
|
864 ModuleDescriptor descriptor3 = newBuilder("m3") |
|
865 .requires("m2") |
|
866 .exports("p", Set.of("m1")) |
|
867 .build(); |
|
868 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3); |
|
869 Configuration cf2 = resolve(cf1, finder2, "m1", "m3"); |
|
870 ClassLoader loader2 = new ClassLoader() { }; |
|
871 ModuleLayer layer2 = layer1.defineModules(cf2, mn -> loader2); |
|
872 assertTrue(layer2.modules().size() == 2); |
|
873 |
|
874 Module m1_v1 = layer1.findModule("m1").get(); |
|
875 Module m2 = layer1.findModule("m2").get(); |
|
876 |
|
877 Module m1_v2 = layer2.findModule("m1").get(); |
|
878 Module m3 = layer2.findModule("m3").get(); |
|
879 |
|
880 assertTrue(m3.canRead(m1_v1)); |
|
881 assertFalse(m3.canRead(m1_v2)); |
|
882 |
|
883 assertFalse(m3.isExported("p")); |
|
884 assertTrue(m3.isExported("p", m1_v1)); |
|
885 assertFalse(m3.isExported("p", m1_v2)); |
|
886 assertFalse(m3.isExported("p", m2)); |
|
887 } |
|
888 |
|
889 |
|
890 /** |
|
891 * Test layers with a qualified export. The target module is not in any layer. |
|
892 * |
|
893 * - Configuration/layer1: m1 { } |
|
894 * - Configuration/layer2: m2 { exports p to m3; } |
|
895 */ |
|
896 public void testQualifiedExports7() { |
|
897 // create layer1 with m1 |
|
898 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
899 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); |
|
900 Configuration cf1 = resolve(finder1, "m1"); |
|
901 ClassLoader cl1 = new ClassLoader() { }; |
|
902 ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1); |
|
903 assertTrue(layer1.modules().size() == 1); |
|
904 |
|
905 // create layer2 with m2 |
|
906 ModuleDescriptor descriptor2 = newBuilder("m2") |
|
907 .exports("p", Set.of("m3")) |
|
908 .build(); |
|
909 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); |
|
910 Configuration cf2 = resolve(cf1, finder2, "m2"); |
|
911 ClassLoader cl2 = new ClassLoader() { }; |
|
912 ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2); |
|
913 assertTrue(layer2.modules().size() == 1); |
|
914 |
|
915 Module m1 = layer1.findModule("m1").get(); |
|
916 Module m2 = layer2.findModule("m2").get(); |
|
917 |
|
918 // check m2 does not export p to anyone |
|
919 assertFalse(m2.isExported("p")); |
|
920 assertFalse(m2.isExported("p", m1)); |
|
921 } |
|
922 |
|
923 /** |
|
924 * Attempt to use defineModules to create a layer with a module defined |
|
925 * to a class loader that already has a module of the same name defined |
|
926 * to the class loader. |
|
927 */ |
|
928 @Test(expectedExceptions = { LayerInstantiationException.class }) |
|
929 public void testModuleAlreadyDefinedToLoader() { |
|
930 |
|
931 ModuleDescriptor md = newBuilder("m") |
|
932 .requires("java.base") |
|
933 .build(); |
|
934 |
|
935 ModuleFinder finder = ModuleUtils.finderOf(md); |
|
936 |
|
937 Configuration parent = ModuleLayer.boot().configuration(); |
|
938 |
|
939 Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m")); |
|
940 |
|
941 ClassLoader loader = new ClassLoader() { }; |
|
942 |
|
943 ModuleLayer.boot().defineModules(cf, mn -> loader); |
|
944 |
|
945 // should throw LayerInstantiationException as m1 already defined to loader |
|
946 ModuleLayer.boot().defineModules(cf, mn -> loader); |
|
947 |
|
948 } |
|
949 |
|
950 |
|
951 /** |
|
952 * Attempt to use defineModules to create a layer with a module containing |
|
953 * package {@code p} where the class loader already has a module defined |
|
954 * to it containing package {@code p}. |
|
955 */ |
|
956 @Test(expectedExceptions = { LayerInstantiationException.class }) |
|
957 public void testPackageAlreadyInNamedModule() { |
|
958 |
|
959 ModuleDescriptor md1 = newBuilder("m1") |
|
960 .packages(Set.of("p")) |
|
961 .requires("java.base") |
|
962 .build(); |
|
963 |
|
964 ModuleDescriptor md2 = newBuilder("m2") |
|
965 .packages(Set.of("p")) |
|
966 .requires("java.base") |
|
967 .build(); |
|
968 |
|
969 ModuleFinder finder = ModuleUtils.finderOf(md1, md2); |
|
970 |
|
971 ClassLoader loader = new ClassLoader() { }; |
|
972 |
|
973 // define m1 containing package p to class loader |
|
974 |
|
975 Configuration parent = ModuleLayer.boot().configuration(); |
|
976 |
|
977 Configuration cf1 = parent.resolve(finder, ModuleFinder.of(), Set.of("m1")); |
|
978 |
|
979 ModuleLayer layer1 = ModuleLayer.boot().defineModules(cf1, mn -> loader); |
|
980 |
|
981 // attempt to define m2 containing package p to class loader |
|
982 |
|
983 Configuration cf2 = parent.resolve(finder, ModuleFinder.of(), Set.of("m2")); |
|
984 |
|
985 // should throw exception because p already in m1 |
|
986 ModuleLayer layer2 = ModuleLayer.boot().defineModules(cf2, mn -> loader); |
|
987 |
|
988 } |
|
989 |
|
990 |
|
991 /** |
|
992 * Attempt to use defineModules to create a layer with a module |
|
993 * containing a package in which a type is already loaded by the class |
|
994 * loader. |
|
995 */ |
|
996 @Test(expectedExceptions = { LayerInstantiationException.class }) |
|
997 public void testPackageAlreadyInUnnamedModule() throws Exception { |
|
998 |
|
999 Class<?> c = layertest.Test.class; |
|
1000 assertFalse(c.getModule().isNamed()); // in unnamed module |
|
1001 |
|
1002 ModuleDescriptor md = newBuilder("m") |
|
1003 .packages(Set.of(c.getPackageName())) |
|
1004 .requires("java.base") |
|
1005 .build(); |
|
1006 |
|
1007 ModuleFinder finder = ModuleUtils.finderOf(md); |
|
1008 |
|
1009 Configuration parent = ModuleLayer.boot().configuration(); |
|
1010 Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m")); |
|
1011 |
|
1012 ModuleLayer.boot().defineModules(cf, mn -> c.getClassLoader()); |
|
1013 } |
|
1014 |
|
1015 |
|
1016 /** |
|
1017 * Attempt to create a layer with a module named "java.base". |
|
1018 */ |
|
1019 public void testLayerWithJavaBase() { |
|
1020 ModuleDescriptor descriptor = newBuilder("java.base") |
|
1021 .exports("java.lang") |
|
1022 .build(); |
|
1023 |
|
1024 ModuleFinder finder = ModuleUtils.finderOf(descriptor); |
|
1025 |
|
1026 Configuration cf = ModuleLayer.boot() |
|
1027 .configuration() |
|
1028 .resolve(finder, ModuleFinder.of(), Set.of("java.base")); |
|
1029 assertTrue(cf.modules().size() == 1); |
|
1030 |
|
1031 ClassLoader scl = ClassLoader.getSystemClassLoader(); |
|
1032 |
|
1033 try { |
|
1034 ModuleLayer.boot().defineModules(cf, mn -> new ClassLoader() { }); |
|
1035 assertTrue(false); |
|
1036 } catch (LayerInstantiationException e) { } |
|
1037 |
|
1038 try { |
|
1039 ModuleLayer.boot().defineModulesWithOneLoader(cf, scl); |
|
1040 assertTrue(false); |
|
1041 } catch (LayerInstantiationException e) { } |
|
1042 |
|
1043 try { |
|
1044 ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl); |
|
1045 assertTrue(false); |
|
1046 } catch (LayerInstantiationException e) { } |
|
1047 } |
|
1048 |
|
1049 |
|
1050 @DataProvider(name = "javaPackages") |
|
1051 public Object[][] javaPackages() { |
|
1052 return new Object[][] { { "m1", "java" }, { "m2", "java.x" } }; |
|
1053 } |
|
1054 |
|
1055 /** |
|
1056 * Attempt to create a layer with a module containing a "java" package. |
|
1057 * This should only be allowed when the module is defined to the platform |
|
1058 * class loader. |
|
1059 */ |
|
1060 @Test(dataProvider = "javaPackages") |
|
1061 public void testLayerWithJavaPackage(String mn, String pn) { |
|
1062 ModuleDescriptor descriptor = newBuilder(mn).packages(Set.of(pn)).build(); |
|
1063 ModuleFinder finder = ModuleUtils.finderOf(descriptor); |
|
1064 |
|
1065 Configuration cf = ModuleLayer.boot() |
|
1066 .configuration() |
|
1067 .resolve(finder, ModuleFinder.of(), Set.of(mn)); |
|
1068 assertTrue(cf.modules().size() == 1); |
|
1069 |
|
1070 ClassLoader pcl = ClassLoader.getPlatformClassLoader(); |
|
1071 ClassLoader scl = ClassLoader.getSystemClassLoader(); |
|
1072 |
|
1073 try { |
|
1074 ModuleLayer.boot().defineModules(cf, _mn -> new ClassLoader() { }); |
|
1075 assertTrue(false); |
|
1076 } catch (LayerInstantiationException e) { } |
|
1077 |
|
1078 try { |
|
1079 ModuleLayer.boot().defineModulesWithOneLoader(cf, scl); |
|
1080 assertTrue(false); |
|
1081 } catch (LayerInstantiationException e) { } |
|
1082 |
|
1083 try { |
|
1084 ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl); |
|
1085 assertTrue(false); |
|
1086 } catch (LayerInstantiationException e) { } |
|
1087 |
|
1088 // create layer with module defined to platform class loader |
|
1089 ModuleLayer layer = ModuleLayer.boot().defineModules(cf, _mn -> pcl); |
|
1090 Optional<Module> om = layer.findModule(mn); |
|
1091 assertTrue(om.isPresent()); |
|
1092 Module foo = om.get(); |
|
1093 assertTrue(foo.getClassLoader() == pcl); |
|
1094 assertTrue(foo.getPackages().size() == 1); |
|
1095 assertTrue(foo.getPackages().iterator().next().equals(pn)); |
|
1096 } |
|
1097 |
|
1098 |
|
1099 /** |
|
1100 * Attempt to create a layer with a module defined to the boot loader |
|
1101 */ |
|
1102 @Test(expectedExceptions = { LayerInstantiationException.class }) |
|
1103 public void testLayerWithBootLoader() { |
|
1104 ModuleDescriptor descriptor = newBuilder("m1") |
|
1105 .build(); |
|
1106 |
|
1107 ModuleFinder finder = ModuleUtils.finderOf(descriptor); |
|
1108 |
|
1109 Configuration cf = ModuleLayer.boot() |
|
1110 .configuration() |
|
1111 .resolve(finder, ModuleFinder.of(), Set.of("m1")); |
|
1112 assertTrue(cf.modules().size() == 1); |
|
1113 |
|
1114 ModuleLayer.boot().defineModules(cf, mn -> null ); |
|
1115 } |
|
1116 |
|
1117 |
|
1118 /** |
|
1119 * Parent of configuration != configuration of parent layer |
|
1120 */ |
|
1121 @Test(expectedExceptions = { IllegalArgumentException.class }) |
|
1122 public void testIncorrectParent1() { |
|
1123 ModuleDescriptor descriptor1 = newBuilder("m1") |
|
1124 .requires("java.base") |
|
1125 .build(); |
|
1126 |
|
1127 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); |
|
1128 |
|
1129 Configuration parent = ModuleLayer.boot().configuration(); |
|
1130 Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1")); |
|
1131 |
|
1132 ClassLoader loader = new ClassLoader() { }; |
|
1133 ModuleLayer.empty().defineModules(cf, mn -> loader); |
|
1134 } |
|
1135 |
|
1136 |
|
1137 /** |
|
1138 * Parent of configuration != configuration of parent layer |
|
1139 */ |
|
1140 @Test(expectedExceptions = { IllegalArgumentException.class }) |
|
1141 public void testIncorrectParent2() { |
|
1142 ModuleDescriptor descriptor1 = newBuilder("m1").build(); |
|
1143 |
|
1144 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); |
|
1145 |
|
1146 Configuration cf = resolve(finder, "m1"); |
|
1147 |
|
1148 ClassLoader loader = new ClassLoader() { }; |
|
1149 ModuleLayer.boot().defineModules(cf, mn -> loader); |
|
1150 } |
|
1151 |
|
1152 |
|
1153 // null handling |
|
1154 |
|
1155 @Test(expectedExceptions = { NullPointerException.class }) |
|
1156 public void testCreateWithNull1() { |
|
1157 ClassLoader loader = new ClassLoader() { }; |
|
1158 ModuleLayer.empty().defineModules(null, mn -> loader); |
|
1159 } |
|
1160 |
|
1161 @Test(expectedExceptions = { NullPointerException.class }) |
|
1162 public void testCreateWithNull2() { |
|
1163 Configuration cf = resolve(ModuleLayer.boot().configuration(), ModuleFinder.of()); |
|
1164 ModuleLayer.boot().defineModules(cf, null); |
|
1165 } |
|
1166 |
|
1167 @Test(expectedExceptions = { NullPointerException.class }) |
|
1168 public void testCreateWithNull3() { |
|
1169 ClassLoader scl = ClassLoader.getSystemClassLoader(); |
|
1170 ModuleLayer.empty().defineModulesWithOneLoader(null, scl); |
|
1171 } |
|
1172 |
|
1173 @Test(expectedExceptions = { NullPointerException.class }) |
|
1174 public void testCreateWithNull4() { |
|
1175 ClassLoader scl = ClassLoader.getSystemClassLoader(); |
|
1176 ModuleLayer.empty().defineModulesWithManyLoaders(null, scl); |
|
1177 } |
|
1178 |
|
1179 @Test(expectedExceptions = { NullPointerException.class }) |
|
1180 public void testFindModuleWithNull() { |
|
1181 ModuleLayer.boot().findModule(null); |
|
1182 } |
|
1183 |
|
1184 @Test(expectedExceptions = { NullPointerException.class }) |
|
1185 public void testFindLoaderWithNull() { |
|
1186 ModuleLayer.boot().findLoader(null); |
|
1187 } |
|
1188 |
|
1189 |
|
1190 // immutable sets |
|
1191 |
|
1192 @Test(expectedExceptions = { UnsupportedOperationException.class }) |
|
1193 public void testImmutableSet() { |
|
1194 Module base = Object.class.getModule(); |
|
1195 ModuleLayer.boot().modules().add(base); |
|
1196 } |
|
1197 |
|
1198 |
|
1199 /** |
|
1200 * Resolve the given modules, by name, and returns the resulting |
|
1201 * Configuration. |
|
1202 */ |
|
1203 private static Configuration resolve(Configuration cf, |
|
1204 ModuleFinder finder, |
|
1205 String... roots) { |
|
1206 return cf.resolve(finder, ModuleFinder.of(), Set.of(roots)); |
|
1207 } |
|
1208 |
|
1209 private static Configuration resolve(ModuleFinder finder, |
|
1210 String... roots) { |
|
1211 return resolve(Configuration.empty(), finder, roots); |
|
1212 } |
|
1213 } |