Path: blob/master/test/jdk/java/lang/ModuleLayer/BasicLayerTest.java
41149 views
/*1* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @library /test/lib26* @modules java.base/jdk.internal.access27* @build BasicLayerTest28* jdk.test.lib.util.ModuleUtils29* @compile layertest/Test.java30* @run testng BasicLayerTest31* @summary Basic tests for java.lang.ModuleLayer32*/3334import java.lang.module.Configuration;35import java.lang.module.ModuleDescriptor;36import java.lang.module.ModuleDescriptor.Requires;37import java.lang.module.ModuleFinder;38import java.util.HashMap;39import java.util.Map;40import java.util.Set;41import java.util.stream.Collectors;4243import jdk.test.lib.util.ModuleUtils;4445import jdk.internal.access.SharedSecrets;4647import org.testng.annotations.DataProvider;48import org.testng.annotations.Test;49import static org.testng.Assert.*;5051@Test52public class BasicLayerTest {5354/**55* Creates a "non-strict" builder for building a module. This allows the56* test the create ModuleDescriptor objects that do not require java.base.57*/58private static ModuleDescriptor.Builder newBuilder(String mn) {59return SharedSecrets.getJavaLangModuleAccess()60.newModuleBuilder(mn, false, Set.of());61}6263/**64* Exercise ModuleLayer.empty()65*/66public void testEmpty() {67ModuleLayer emptyLayer = ModuleLayer.empty();6869assertTrue(emptyLayer.parents().isEmpty());7071assertTrue(emptyLayer.configuration() == Configuration.empty());7273assertTrue(emptyLayer.modules().isEmpty());7475assertFalse(emptyLayer.findModule("java.base").isPresent());7677try {78emptyLayer.findLoader("java.base");79assertTrue(false);80} catch (IllegalArgumentException expected) { }81}828384/**85* Exercise ModuleLayer.boot()86*/87public void testBoot() {88ModuleLayer bootLayer = ModuleLayer.boot();8990// configuration91Configuration cf = bootLayer.configuration();92assertTrue(cf.findModule("java.base").get()93.reference()94.descriptor()95.exports()96.stream().anyMatch(e -> (e.source().equals("java.lang")97&& !e.isQualified())));9899// modules100Set<Module> modules = bootLayer.modules();101assertTrue(modules.contains(Object.class.getModule()));102int count = (int) modules.stream().map(Module::getName).count();103assertEquals(count, modules.size()); // module names are unique104105// findModule106Module base = Object.class.getModule();107assertTrue(bootLayer.findModule("java.base").get() == base);108assertTrue(base.getLayer() == bootLayer);109110// findLoader111assertTrue(bootLayer.findLoader("java.base") == null);112113// parents114assertTrue(bootLayer.parents().size() == 1);115assertTrue(bootLayer.parents().get(0) == ModuleLayer.empty());116}117118119/**120* Exercise defineModules, created with empty layer as parent121*/122public void testLayerOnEmpty() {123ModuleDescriptor descriptor1 = newBuilder("m1")124.requires("m2")125.exports("p1")126.build();127128ModuleDescriptor descriptor2 = newBuilder("m2")129.requires("m3")130.build();131132ModuleDescriptor descriptor3 = newBuilder("m3")133.build();134135ModuleFinder finder136= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);137138Configuration cf = resolve(finder, "m1");139140// map each module to its own class loader for this test141ClassLoader loader1 = new ClassLoader() { };142ClassLoader loader2 = new ClassLoader() { };143ClassLoader loader3 = new ClassLoader() { };144Map<String, ClassLoader> map = new HashMap<>();145map.put("m1", loader1);146map.put("m2", loader2);147map.put("m3", loader3);148149ModuleLayer layer = ModuleLayer.empty().defineModules(cf, map::get);150151// configuration152assertTrue(layer.configuration() == cf);153assertTrue(layer.configuration().modules().size() == 3);154155// modules156Set<Module> modules = layer.modules();157assertTrue(modules.size() == 3);158Set<String> names = modules.stream()159.map(Module::getName)160.collect(Collectors.toSet());161assertTrue(names.contains("m1"));162assertTrue(names.contains("m2"));163assertTrue(names.contains("m3"));164165// findModule166Module m1 = layer.findModule("m1").get();167Module m2 = layer.findModule("m2").get();168Module m3 = layer.findModule("m3").get();169assertEquals(m1.getName(), "m1");170assertEquals(m2.getName(), "m2");171assertEquals(m3.getName(), "m3");172assertTrue(m1.getDescriptor() == descriptor1);173assertTrue(m2.getDescriptor() == descriptor2);174assertTrue(m3.getDescriptor() == descriptor3);175assertTrue(m1.getLayer() == layer);176assertTrue(m2.getLayer() == layer);177assertTrue(m3.getLayer() == layer);178assertTrue(modules.contains(m1));179assertTrue(modules.contains(m2));180assertTrue(modules.contains(m3));181assertFalse(layer.findModule("godot").isPresent());182183// findLoader184assertTrue(layer.findLoader("m1") == loader1);185assertTrue(layer.findLoader("m2") == loader2);186assertTrue(layer.findLoader("m3") == loader3);187try {188ClassLoader loader = layer.findLoader("godot");189assertTrue(false);190} catch (IllegalArgumentException ignore) { }191192// parents193assertTrue(layer.parents().size() == 1);194assertTrue(layer.parents().get(0) == ModuleLayer.empty());195}196197198/**199* Exercise defineModules, created with boot layer as parent200*/201public void testLayerOnBoot() {202ModuleDescriptor descriptor1 = newBuilder("m1")203.requires("m2")204.requires("java.base")205.exports("p1")206.build();207208ModuleDescriptor descriptor2 = newBuilder("m2")209.requires("java.base")210.build();211212ModuleFinder finder213= ModuleUtils.finderOf(descriptor1, descriptor2);214215Configuration parent = ModuleLayer.boot().configuration();216Configuration cf = resolve(parent, finder, "m1");217218ClassLoader loader = new ClassLoader() { };219220ModuleLayer layer = ModuleLayer.boot().defineModules(cf, mn -> loader);221222// configuration223assertTrue(layer.configuration() == cf);224assertTrue(layer.configuration().modules().size() == 2);225226// modules227Set<Module> modules = layer.modules();228assertTrue(modules.size() == 2);229Set<String> names = modules.stream()230.map(Module::getName)231.collect(Collectors.toSet());232assertTrue(names.contains("m1"));233assertTrue(names.contains("m2"));234235// findModule236Module m1 = layer.findModule("m1").get();237Module m2 = layer.findModule("m2").get();238assertEquals(m1.getName(), "m1");239assertEquals(m2.getName(), "m2");240assertTrue(m1.getDescriptor() == descriptor1);241assertTrue(m2.getDescriptor() == descriptor2);242assertTrue(m1.getLayer() == layer);243assertTrue(m2.getLayer() == layer);244assertTrue(modules.contains(m1));245assertTrue(modules.contains(m2));246assertTrue(layer.findModule("java.base").get() == Object.class.getModule());247assertFalse(layer.findModule("godot").isPresent());248249// findLoader250assertTrue(layer.findLoader("m1") == loader);251assertTrue(layer.findLoader("m2") == loader);252assertTrue(layer.findLoader("java.base") == null);253254// parents255assertTrue(layer.parents().size() == 1);256assertTrue(layer.parents().get(0) == ModuleLayer.boot());257}258259260/**261* Exercise defineModules with a configuration of two modules that262* have the same module-private package.263*/264public void testPackageContainedInSelfAndOther() {265ModuleDescriptor descriptor1 = newBuilder("m1")266.requires("m2")267.packages(Set.of("p"))268.build();269270ModuleDescriptor descriptor2 = newBuilder("m2")271.packages(Set.of("p"))272.build();273274ModuleFinder finder275= ModuleUtils.finderOf(descriptor1, descriptor2);276277Configuration cf = resolve(finder, "m1");278assertTrue(cf.modules().size() == 2);279280// one loader per module, should be okay281ModuleLayer.empty().defineModules(cf, mn -> new ClassLoader() { });282283// same class loader284try {285ClassLoader loader = new ClassLoader() { };286ModuleLayer.empty().defineModules(cf, mn -> loader);287assertTrue(false);288} catch (LayerInstantiationException expected) { }289}290291292/**293* Exercise defineModules with a configuration that is a partitioned294* graph. The same package is exported in both partitions.295*/296public void testSameExportInPartitionedGraph() {297298// m1 reads m2, m2 exports p to m1299ModuleDescriptor descriptor1 = newBuilder("m1")300.requires("m2")301.build();302ModuleDescriptor descriptor2 = newBuilder("m2")303.exports("p", Set.of("m1"))304.build();305306// m3 reads m4, m4 exports p to m3307ModuleDescriptor descriptor3 = newBuilder("m3")308.requires("m4")309.build();310ModuleDescriptor descriptor4 = newBuilder("m4")311.exports("p", Set.of("m3"))312.build();313314ModuleFinder finder315= ModuleUtils.finderOf(descriptor1,316descriptor2,317descriptor3,318descriptor4);319320Configuration cf = resolve(finder, "m1", "m3");321assertTrue(cf.modules().size() == 4);322323// one loader per module324ModuleLayer.empty().defineModules(cf, mn -> new ClassLoader() { });325326// m1 & m2 in one loader, m3 & m4 in another loader327ClassLoader loader1 = new ClassLoader() { };328ClassLoader loader2 = new ClassLoader() { };329Map<String, ClassLoader> map = new HashMap<>();330map.put("m1", loader1);331map.put("m2", loader1);332map.put("m3", loader2);333map.put("m4", loader2);334ModuleLayer.empty().defineModules(cf, map::get);335336// same loader337try {338ClassLoader loader = new ClassLoader() { };339ModuleLayer.empty().defineModules(cf, mn -> loader);340assertTrue(false);341} catch (LayerInstantiationException expected) { }342}343344345/**346* Exercise defineModules with a configuration with a module that347* contains a package that is the same name as a non-exported package in348* a parent layer.349*/350public void testContainsSamePackageAsBootLayer() {351352// check assumption that java.base contains sun.launcher353ModuleDescriptor base = Object.class.getModule().getDescriptor();354assertTrue(base.packages().contains("sun.launcher"));355356ModuleDescriptor descriptor = newBuilder("m1")357.requires("java.base")358.packages(Set.of("sun.launcher"))359.build();360361ModuleFinder finder = ModuleUtils.finderOf(descriptor);362363Configuration parent = ModuleLayer.boot().configuration();364Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));365assertTrue(cf.modules().size() == 1);366367ClassLoader loader = new ClassLoader() { };368ModuleLayer layer = ModuleLayer.boot().defineModules(cf, mn -> loader);369assertTrue(layer.modules().size() == 1);370}371372373/**374* Test layers with implied readability.375*376* The test consists of three configurations:377* - Configuration/layer1: m1, m2 requires transitive m1378* - Configuration/layer2: m3 requires m1379*/380public void testImpliedReadabilityWithLayers1() {381382// cf1: m1 and m2, m2 requires transitive m1383384ModuleDescriptor descriptor1 = newBuilder("m1")385.build();386387ModuleDescriptor descriptor2 = newBuilder("m2")388.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")389.build();390391ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);392393Configuration cf1 = resolve(finder1, "m2");394395ClassLoader cl1 = new ClassLoader() { };396ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1);397398399// cf2: m3, m3 requires m2400401ModuleDescriptor descriptor3 = newBuilder("m3")402.requires("m2")403.build();404405ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);406407Configuration cf2 = resolve(cf1, finder2, "m3");408409ClassLoader cl2 = new ClassLoader() { };410ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2);411412assertTrue(layer1.parents().size() == 1);413assertTrue(layer1.parents().get(0) == ModuleLayer.empty());414415assertTrue(layer2.parents().size() == 1);416assertTrue(layer2.parents().get(0) == layer1);417418Module m1 = layer2.findModule("m1").get();419Module m2 = layer2.findModule("m2").get();420Module m3 = layer2.findModule("m3").get();421422assertTrue(m1.getLayer() == layer1);423assertTrue(m2.getLayer() == layer1);424assertTrue(m3.getLayer() == layer2);425426assertTrue(m1.getClassLoader() == cl1);427assertTrue(m2.getClassLoader() == cl1);428assertTrue(m3.getClassLoader() == cl2);429430assertTrue(m1.canRead(m1));431assertFalse(m1.canRead(m2));432assertFalse(m1.canRead(m3));433434assertTrue(m2.canRead(m1));435assertTrue(m2.canRead(m2));436assertFalse(m2.canRead(m3));437438assertTrue(m3.canRead(m1));439assertTrue(m3.canRead(m2));440assertTrue(m3.canRead(m3));441}442443444/**445* Test layers with implied readability.446*447* The test consists of three configurations:448* - Configuration/layer1: m1449* - Configuration/layer2: m2 requires transitive m3, m3 requires m2450*/451public void testImpliedReadabilityWithLayers2() {452453// cf1: m1454455ModuleDescriptor descriptor1 = newBuilder("m1").build();456457ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);458459Configuration cf1 = resolve(finder1, "m1");460461ClassLoader cl1 = new ClassLoader() { };462ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1);463464465// cf2: m2, m3: m2 requires transitive m1, m3 requires m2466467ModuleDescriptor descriptor2 = newBuilder("m2")468.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")469.build();470471ModuleDescriptor descriptor3 = newBuilder("m3")472.requires("m2")473.build();474475ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3);476477Configuration cf2 = resolve(cf1, finder2, "m3");478479ClassLoader cl2 = new ClassLoader() { };480ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2);481482assertTrue(layer1.parents().size() == 1);483assertTrue(layer1.parents().get(0) == ModuleLayer.empty());484485assertTrue(layer2.parents().size() == 1);486assertTrue(layer2.parents().get(0) == layer1);487488Module m1 = layer2.findModule("m1").get();489Module m2 = layer2.findModule("m2").get();490Module m3 = layer2.findModule("m3").get();491492assertTrue(m1.getLayer() == layer1);493assertTrue(m2.getLayer() == layer2);494assertTrue(m3.getLayer() == layer2);495496assertTrue(m1.canRead(m1));497assertFalse(m1.canRead(m2));498assertFalse(m1.canRead(m3));499500assertTrue(m2.canRead(m1));501assertTrue(m2.canRead(m2));502assertFalse(m2.canRead(m3));503504assertTrue(m3.canRead(m1));505assertTrue(m3.canRead(m2));506assertTrue(m3.canRead(m3));507}508509510/**511* Test layers with implied readability.512*513* The test consists of three configurations:514* - Configuration/layer1: m1515* - Configuration/layer2: m2 requires transitive m1516* - Configuration/layer3: m3 requires m1517*/518public void testImpliedReadabilityWithLayers3() {519520// cf1: m1521522ModuleDescriptor descriptor1 = newBuilder("m1").build();523524ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);525526Configuration cf1 = resolve(finder1, "m1");527528ClassLoader cl1 = new ClassLoader() { };529ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1);530531532// cf2: m2 requires transitive m1533534ModuleDescriptor descriptor2 = newBuilder("m2")535.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")536.build();537538ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);539540Configuration cf2 = resolve(cf1, finder2, "m2");541542ClassLoader cl2 = new ClassLoader() { };543ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2);544545546// cf3: m3 requires m2547548ModuleDescriptor descriptor3 = newBuilder("m3")549.requires("m2")550.build();551552ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3);553554Configuration cf3 = resolve(cf2, finder3, "m3");555556ClassLoader cl3 = new ClassLoader() { };557ModuleLayer layer3 = layer2.defineModules(cf3, mn -> cl3);558559assertTrue(layer1.parents().size() == 1);560assertTrue(layer1.parents().get(0) == ModuleLayer.empty());561562assertTrue(layer2.parents().size() == 1);563assertTrue(layer2.parents().get(0) == layer1);564565assertTrue(layer3.parents().size() == 1);566assertTrue(layer3.parents().get(0) == layer2);567568Module m1 = layer3.findModule("m1").get();569Module m2 = layer3.findModule("m2").get();570Module m3 = layer3.findModule("m3").get();571572assertTrue(m1.getLayer() == layer1);573assertTrue(m2.getLayer() == layer2);574assertTrue(m3.getLayer() == layer3);575576assertTrue(m1.canRead(m1));577assertFalse(m1.canRead(m2));578assertFalse(m1.canRead(m3));579580assertTrue(m2.canRead(m1));581assertTrue(m2.canRead(m2));582assertFalse(m2.canRead(m3));583584assertTrue(m3.canRead(m1));585assertTrue(m3.canRead(m2));586assertTrue(m3.canRead(m3));587}588589590/**591* Test layers with implied readability.592*593* The test consists of two configurations:594* - Configuration/layer1: m1, m2 requires transitive m1595* - Configuration/layer2: m3 requires transitive m2, m4 requires m3596*/597public void testImpliedReadabilityWithLayers4() {598599// cf1: m1, m2 requires transitive m1600601ModuleDescriptor descriptor1 = newBuilder("m1")602.build();603604ModuleDescriptor descriptor2 = newBuilder("m2")605.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")606.build();607608ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);609610Configuration cf1 = resolve(finder1, "m2");611612ClassLoader cl1 = new ClassLoader() { };613ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1);614615616// cf2: m3 requires transitive m2, m4 requires m3617618ModuleDescriptor descriptor3 = newBuilder("m3")619.requires(Set.of(Requires.Modifier.TRANSITIVE), "m2")620.build();621622ModuleDescriptor descriptor4 = newBuilder("m4")623.requires("m3")624.build();625626627ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);628629Configuration cf2 = resolve(cf1, finder2, "m3", "m4");630631ClassLoader cl2 = new ClassLoader() { };632ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2);633634assertTrue(layer1.parents().size() == 1);635assertTrue(layer1.parents().get(0) == ModuleLayer.empty());636637assertTrue(layer2.parents().size() == 1);638assertTrue(layer2.parents().get(0) == layer1);639640Module m1 = layer2.findModule("m1").get();641Module m2 = layer2.findModule("m2").get();642Module m3 = layer2.findModule("m3").get();643Module m4 = layer2.findModule("m4").get();644645assertTrue(m1.getLayer() == layer1);646assertTrue(m2.getLayer() == layer1);647assertTrue(m3.getLayer() == layer2);648assertTrue(m4.getLayer() == layer2);649650assertTrue(m1.canRead(m1));651assertFalse(m1.canRead(m2));652assertFalse(m1.canRead(m3));653assertFalse(m1.canRead(m4));654655assertTrue(m2.canRead(m1));656assertTrue(m2.canRead(m2));657assertFalse(m1.canRead(m3));658assertFalse(m1.canRead(m4));659660assertTrue(m3.canRead(m1));661assertTrue(m3.canRead(m2));662assertTrue(m3.canRead(m3));663assertFalse(m3.canRead(m4));664665assertTrue(m4.canRead(m1));666assertTrue(m4.canRead(m2));667assertTrue(m4.canRead(m3));668assertTrue(m4.canRead(m4));669}670671672/**673* Test layers with a qualified export. The module exporting the package674* does not read the target module.675*676* m1 { exports p to m2 }677* m2 { }678*/679public void testQualifiedExports1() {680ModuleDescriptor descriptor1 = newBuilder("m1").681exports("p", Set.of("m2"))682.build();683684ModuleDescriptor descriptor2 = newBuilder("m2")685.build();686687ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);688689Configuration cf = resolve(finder1, "m1", "m2");690691ClassLoader cl = new ClassLoader() { };692ModuleLayer layer = ModuleLayer.empty().defineModules(cf, mn -> cl);693assertTrue(layer.modules().size() == 2);694695Module m1 = layer.findModule("m1").get();696Module m2 = layer.findModule("m2").get();697698// check m1 exports p to m2699assertFalse(m1.isExported("p"));700assertTrue(m1.isExported("p", m2));701assertFalse(m1.isOpen("p", m2));702}703704705/**706* Test layers with a qualified export. The module exporting the package707* reads the target module.708*709* m1 { exports p to m2; }710* m2 { requires m1; }711*/712public void testQualifiedExports2() {713ModuleDescriptor descriptor1 = newBuilder("m1")714.exports("p", Set.of("m2"))715.build();716717ModuleDescriptor descriptor2 = newBuilder("m2")718.requires("m1")719.build();720721ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);722723Configuration cf = resolve(finder1, "m2");724ClassLoader cl = new ClassLoader() { };725ModuleLayer layer = ModuleLayer.empty().defineModules(cf, mn -> cl);726assertTrue(layer.modules().size() == 2);727728Module m1 = layer.findModule("m1").get();729Module m2 = layer.findModule("m2").get();730731// check m1 exports p to m2732assertFalse(m1.isExported("p"));733assertTrue(m1.isExported("p", m2));734assertFalse(m1.isOpen("p", m2));735}736737738/**739* Test layers with a qualified export. The module exporting the package740* does not read the target module in the parent layer.741*742* - Configuration/layer1: m1 { }743* - Configuration/layer2: m2 { exports p to m1; }744*/745public void testQualifiedExports3() {746// create layer1 with m1747ModuleDescriptor descriptor1 = newBuilder("m1").build();748ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);749Configuration cf1 = resolve(finder1, "m1");750ClassLoader cl1 = new ClassLoader() { };751ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1);752assertTrue(layer1.modules().size() == 1);753754// create layer2 with m2755ModuleDescriptor descriptor2 = newBuilder("m2")756.exports("p", Set.of("m1"))757.build();758ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);759Configuration cf2 = resolve(cf1, finder2, "m2");760ClassLoader cl2 = new ClassLoader() { };761ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2);762assertTrue(layer2.modules().size() == 1);763764Module m1 = layer1.findModule("m1").get();765Module m2 = layer2.findModule("m2").get();766767// check m2 exports p to layer1/m1768assertFalse(m2.isExported("p"));769assertTrue(m2.isExported("p", m1));770assertFalse(m2.isOpen("p", m1));771}772773774/**775* Test layers with a qualified export. The module exporting the package776* reads the target module in the parent layer.777*778* - Configuration/layer1: m1 { }779* - Configuration/layer2: m2 { requires m1; exports p to m1; }780*/781public void testQualifiedExports4() {782// create layer1 with m1783ModuleDescriptor descriptor1 = newBuilder("m1").build();784ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);785Configuration cf1 = resolve(finder1, "m1");786ClassLoader cl1 = new ClassLoader() { };787ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1);788assertTrue(layer1.modules().size() == 1);789790// create layer2 with m2791ModuleDescriptor descriptor2 = newBuilder("m2")792.requires("m1")793.exports("p", Set.of("m1"))794.build();795ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);796Configuration cf2 = resolve(cf1, finder2, "m2");797ClassLoader cl2 = new ClassLoader() { };798ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2);799assertTrue(layer2.modules().size() == 1);800801Module m1 = layer1.findModule("m1").get();802Module m2 = layer2.findModule("m2").get();803804// check m2 exports p to layer1/m1805assertFalse(m2.isExported("p"));806assertTrue(m2.isExported("p", m1));807assertFalse(m2.isOpen("p", m1));808}809810/**811* Test layers with a qualified export. The module exporting the package812* does not read the target module.813*814* - Configuration/layer1: m1815* - Configuration/layer2: m1, m2 { exports p to m1; }816*/817public void testQualifiedExports5() {818// create layer1 with m1819ModuleDescriptor descriptor1 = newBuilder("m1").build();820ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);821Configuration cf1 = resolve(finder1, "m1");822ClassLoader cl1 = new ClassLoader() { };823ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1);824assertTrue(layer1.modules().size() == 1);825826// create layer2 with m1 and m2827ModuleDescriptor descriptor2 = newBuilder("m2").exports("p", Set.of("m1")).build();828ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor2);829Configuration cf2 = resolve(cf1, finder2, "m1", "m2");830ClassLoader cl2 = new ClassLoader() { };831ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2);832assertTrue(layer2.modules().size() == 2);833834Module m1_v1 = layer1.findModule("m1").get();835Module m1_v2 = layer2.findModule("m1").get();836Module m2 = layer2.findModule("m2").get();837838// check m2 exports p to layer2/m2839assertFalse(m2.isExported("p"));840assertTrue(m2.isExported("p", m1_v2));841assertFalse(m2.isExported("p", m1_v1));842}843844845/**846* Test layers with a qualified export. The module exporting the package847* reads the target module in the parent layer (due to requires transitive).848*849* - Configuration/layer1: m1, m2 { requires transitive m1; }850* - Configuration/layer2: m1, m3 { requires m2; exports p to m1; }851*/852public void testQualifiedExports6() {853// create layer1 with m1 and m2854ModuleDescriptor descriptor1 = newBuilder("m1").build();855ModuleDescriptor descriptor2 = newBuilder("m2")856.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")857.build();858ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);859Configuration cf1 = resolve(finder1, "m2");860ClassLoader loader1 = new ClassLoader() { };861ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> loader1);862assertTrue(layer1.modules().size() == 2);863864// create layer2 with m1 and m3865ModuleDescriptor descriptor3 = newBuilder("m3")866.requires("m2")867.exports("p", Set.of("m1"))868.build();869ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);870Configuration cf2 = resolve(cf1, finder2, "m1", "m3");871ClassLoader loader2 = new ClassLoader() { };872ModuleLayer layer2 = layer1.defineModules(cf2, mn -> loader2);873assertTrue(layer2.modules().size() == 2);874875Module m1_v1 = layer1.findModule("m1").get();876Module m2 = layer1.findModule("m2").get();877878Module m1_v2 = layer2.findModule("m1").get();879Module m3 = layer2.findModule("m3").get();880881assertTrue(m3.canRead(m1_v1));882assertFalse(m3.canRead(m1_v2));883884assertFalse(m3.isExported("p"));885assertTrue(m3.isExported("p", m1_v1));886assertFalse(m3.isExported("p", m1_v2));887assertFalse(m3.isExported("p", m2));888}889890891/**892* Test layers with a qualified export. The target module is not in any layer.893*894* - Configuration/layer1: m1 { }895* - Configuration/layer2: m2 { exports p to m3; }896*/897public void testQualifiedExports7() {898// create layer1 with m1899ModuleDescriptor descriptor1 = newBuilder("m1").build();900ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);901Configuration cf1 = resolve(finder1, "m1");902ClassLoader cl1 = new ClassLoader() { };903ModuleLayer layer1 = ModuleLayer.empty().defineModules(cf1, mn -> cl1);904assertTrue(layer1.modules().size() == 1);905906// create layer2 with m2907ModuleDescriptor descriptor2 = newBuilder("m2")908.exports("p", Set.of("m3"))909.build();910ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);911Configuration cf2 = resolve(cf1, finder2, "m2");912ClassLoader cl2 = new ClassLoader() { };913ModuleLayer layer2 = layer1.defineModules(cf2, mn -> cl2);914assertTrue(layer2.modules().size() == 1);915916Module m1 = layer1.findModule("m1").get();917Module m2 = layer2.findModule("m2").get();918919// check m2 does not export p to anyone920assertFalse(m2.isExported("p"));921assertFalse(m2.isExported("p", m1));922}923924/**925* Attempt to use defineModules to create a layer with a module defined926* to a class loader that already has a module of the same name defined927* to the class loader.928*/929@Test(expectedExceptions = { LayerInstantiationException.class })930public void testModuleAlreadyDefinedToLoader() {931932ModuleDescriptor md = newBuilder("m")933.requires("java.base")934.build();935936ModuleFinder finder = ModuleUtils.finderOf(md);937938Configuration parent = ModuleLayer.boot().configuration();939940Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m"));941942ClassLoader loader = new ClassLoader() { };943944ModuleLayer.boot().defineModules(cf, mn -> loader);945946// should throw LayerInstantiationException as m1 already defined to loader947ModuleLayer.boot().defineModules(cf, mn -> loader);948949}950951952/**953* Attempt to use defineModules to create a layer with a module containing954* package {@code p} where the class loader already has a module defined955* to it containing package {@code p}.956*/957@Test(expectedExceptions = { LayerInstantiationException.class })958public void testPackageAlreadyInNamedModule() {959960ModuleDescriptor md1 = newBuilder("m1")961.packages(Set.of("p"))962.requires("java.base")963.build();964965ModuleDescriptor md2 = newBuilder("m2")966.packages(Set.of("p"))967.requires("java.base")968.build();969970ModuleFinder finder = ModuleUtils.finderOf(md1, md2);971972ClassLoader loader = new ClassLoader() { };973974// define m1 containing package p to class loader975976Configuration parent = ModuleLayer.boot().configuration();977978Configuration cf1 = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));979980ModuleLayer layer1 = ModuleLayer.boot().defineModules(cf1, mn -> loader);981982// attempt to define m2 containing package p to class loader983984Configuration cf2 = parent.resolve(finder, ModuleFinder.of(), Set.of("m2"));985986// should throw exception because p already in m1987ModuleLayer layer2 = ModuleLayer.boot().defineModules(cf2, mn -> loader);988989}990991992/**993* Attempt to use defineModules to create a layer with a module994* containing a package in which a type is already loaded by the class995* loader.996*/997@Test(expectedExceptions = { LayerInstantiationException.class })998public void testPackageAlreadyInUnnamedModule() throws Exception {9991000Class<?> c = layertest.Test.class;1001assertFalse(c.getModule().isNamed()); // in unnamed module10021003ModuleDescriptor md = newBuilder("m")1004.packages(Set.of(c.getPackageName()))1005.requires("java.base")1006.build();10071008ModuleFinder finder = ModuleUtils.finderOf(md);10091010Configuration parent = ModuleLayer.boot().configuration();1011Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m"));10121013ModuleLayer.boot().defineModules(cf, mn -> c.getClassLoader());1014}101510161017/**1018* Attempt to create a layer with a module named "java.base".1019*/1020public void testLayerWithJavaBase() {1021ModuleDescriptor descriptor = newBuilder("java.base")1022.exports("java.lang")1023.build();10241025ModuleFinder finder = ModuleUtils.finderOf(descriptor);10261027Configuration cf = ModuleLayer.boot()1028.configuration()1029.resolve(finder, ModuleFinder.of(), Set.of("java.base"));1030assertTrue(cf.modules().size() == 1);10311032ClassLoader scl = ClassLoader.getSystemClassLoader();10331034try {1035ModuleLayer.boot().defineModules(cf, mn -> new ClassLoader() { });1036assertTrue(false);1037} catch (LayerInstantiationException e) { }10381039try {1040ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);1041assertTrue(false);1042} catch (LayerInstantiationException e) { }10431044try {1045ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);1046assertTrue(false);1047} catch (LayerInstantiationException e) { }1048}104910501051@DataProvider(name = "javaPackages")1052public Object[][] javaPackages() {1053return new Object[][] { { "m1", "java" }, { "m2", "java.x" } };1054}10551056/**1057* Attempt to create a layer with a module containing a "java" package.1058*/1059@Test(dataProvider = "javaPackages")1060public void testLayerWithJavaPackage(String mn, String pn) {1061ModuleDescriptor descriptor = newBuilder(mn).packages(Set.of(pn)).build();1062ModuleFinder finder = ModuleUtils.finderOf(descriptor);10631064Configuration cf = ModuleLayer.boot()1065.configuration()1066.resolve(finder, ModuleFinder.of(), Set.of(mn));1067assertTrue(cf.modules().size() == 1);10681069ClassLoader scl = ClassLoader.getSystemClassLoader();10701071try {1072ModuleLayer.boot().defineModules(cf, _mn -> new ClassLoader() { });1073assertTrue(false);1074} catch (LayerInstantiationException e) { }10751076try {1077ModuleLayer.boot().defineModulesWithOneLoader(cf, scl);1078assertTrue(false);1079} catch (LayerInstantiationException e) { }10801081try {1082ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);1083assertTrue(false);1084} catch (LayerInstantiationException e) { }1085}108610871088/**1089* Attempt to create a layer with a module defined to the boot loader1090*/1091@Test(expectedExceptions = { LayerInstantiationException.class })1092public void testLayerWithBootLoader() {1093ModuleDescriptor descriptor = newBuilder("m1").build();10941095ModuleFinder finder = ModuleUtils.finderOf(descriptor);10961097Configuration cf = ModuleLayer.boot()1098.configuration()1099.resolve(finder, ModuleFinder.of(), Set.of("m1"));1100assertTrue(cf.modules().size() == 1);11011102ModuleLayer.boot().defineModules(cf, mn -> null );1103}110411051106/**1107* Attempt to create a layer with a module defined to the platform loader1108*/1109@Test(expectedExceptions = { LayerInstantiationException.class })1110public void testLayerWithPlatformLoader() {1111ModuleDescriptor descriptor = newBuilder("m1").build();11121113ModuleFinder finder = ModuleUtils.finderOf(descriptor);11141115Configuration cf = ModuleLayer.boot()1116.configuration()1117.resolve(finder, ModuleFinder.of(), Set.of("m1"));1118assertTrue(cf.modules().size() == 1);11191120ClassLoader cl = ClassLoader.getPlatformClassLoader();1121ModuleLayer.boot().defineModules(cf, mn -> cl );1122}112311241125/**1126* Parent of configuration != configuration of parent layer1127*/1128@Test(expectedExceptions = { IllegalArgumentException.class })1129public void testIncorrectParent1() {1130ModuleDescriptor descriptor1 = newBuilder("m1")1131.requires("java.base")1132.build();11331134ModuleFinder finder = ModuleUtils.finderOf(descriptor1);11351136Configuration parent = ModuleLayer.boot().configuration();1137Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));11381139ClassLoader loader = new ClassLoader() { };1140ModuleLayer.empty().defineModules(cf, mn -> loader);1141}114211431144/**1145* Parent of configuration != configuration of parent layer1146*/1147@Test(expectedExceptions = { IllegalArgumentException.class })1148public void testIncorrectParent2() {1149ModuleDescriptor descriptor1 = newBuilder("m1").build();11501151ModuleFinder finder = ModuleUtils.finderOf(descriptor1);11521153Configuration cf = resolve(finder, "m1");11541155ClassLoader loader = new ClassLoader() { };1156ModuleLayer.boot().defineModules(cf, mn -> loader);1157}115811591160// null handling11611162@Test(expectedExceptions = { NullPointerException.class })1163public void testCreateWithNull1() {1164ClassLoader loader = new ClassLoader() { };1165ModuleLayer.empty().defineModules(null, mn -> loader);1166}11671168@Test(expectedExceptions = { NullPointerException.class })1169public void testCreateWithNull2() {1170Configuration cf = resolve(ModuleLayer.boot().configuration(), ModuleFinder.of());1171ModuleLayer.boot().defineModules(cf, null);1172}11731174@Test(expectedExceptions = { NullPointerException.class })1175public void testCreateWithNull3() {1176ClassLoader scl = ClassLoader.getSystemClassLoader();1177ModuleLayer.empty().defineModulesWithOneLoader(null, scl);1178}11791180@Test(expectedExceptions = { NullPointerException.class })1181public void testCreateWithNull4() {1182ClassLoader scl = ClassLoader.getSystemClassLoader();1183ModuleLayer.empty().defineModulesWithManyLoaders(null, scl);1184}11851186@Test(expectedExceptions = { NullPointerException.class })1187public void testFindModuleWithNull() {1188ModuleLayer.boot().findModule(null);1189}11901191@Test(expectedExceptions = { NullPointerException.class })1192public void testFindLoaderWithNull() {1193ModuleLayer.boot().findLoader(null);1194}119511961197// unmodifiable collections11981199@DataProvider(name = "layers")1200public Object[][] layers() {1201Configuration cf = resolve(ModuleFinder.of());1202ModuleLayer layer1 = ModuleLayer.empty().defineModulesWithOneLoader(cf, null);1203ModuleLayer layer2 = ModuleLayer.empty().defineModulesWithManyLoaders(cf, null);1204ModuleLayer layer3 = ModuleLayer.empty().defineModules(cf, mn -> null);12051206// empty, boot, and custom layers1207return new Object[][] {1208{ ModuleLayer.empty(), null },1209{ ModuleLayer.boot(), null },1210{ layer1, null },1211{ layer2, null },1212{ layer3, null },1213};1214}12151216@Test(dataProvider = "layers",1217expectedExceptions = { UnsupportedOperationException.class })1218public void testUnmodifiableParents1(ModuleLayer layer, Object ignore) {1219layer.parents().add(ModuleLayer.empty());1220}12211222@Test(dataProvider = "layers",1223expectedExceptions = { UnsupportedOperationException.class })1224public void testUnmodifiableParents2(ModuleLayer layer, Object ignore) {1225layer.parents().remove(ModuleLayer.empty());1226}12271228@Test(dataProvider = "layers",1229expectedExceptions = { UnsupportedOperationException.class })1230public void testUnmodifiableModules1(ModuleLayer layer, Object ignore) {1231layer.modules().add(Object.class.getModule());1232}12331234@Test(dataProvider = "layers",1235expectedExceptions = { UnsupportedOperationException.class })1236public void testUnmodifiableModules2(ModuleLayer layer, Object ignore) {1237layer.modules().remove(Object.class.getModule());1238}12391240/**1241* Resolve the given modules, by name, and returns the resulting1242* Configuration.1243*/1244private static Configuration resolve(Configuration cf,1245ModuleFinder finder,1246String... roots) {1247return cf.resolve(finder, ModuleFinder.of(), Set.of(roots));1248}12491250private static Configuration resolve(ModuleFinder finder,1251String... roots) {1252return resolve(Configuration.empty(), finder, roots);1253}1254}125512561257