Path: blob/master/test/jdk/java/lang/module/ConfigurationTest.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* java.base/jdk.internal.module28* @build ConfigurationTest29* jdk.test.lib.util.ModuleUtils30* @run testng ConfigurationTest31* @summary Basic tests for java.lang.module.Configuration32*/3334import java.io.IOException;35import java.io.OutputStream;36import java.lang.module.Configuration;37import java.lang.module.FindException;38import java.lang.module.ModuleDescriptor;39import java.lang.module.ModuleDescriptor.Requires;40import java.lang.module.ModuleFinder;41import java.lang.module.ResolutionException;42import java.lang.module.ResolvedModule;43import java.nio.file.Files;44import java.nio.file.Path;45import java.nio.file.Paths;46import java.util.List;47import java.util.Set;4849import jdk.test.lib.util.ModuleUtils;5051import jdk.internal.access.SharedSecrets;52import jdk.internal.module.ModuleInfoWriter;53import jdk.internal.module.ModuleTarget;54import org.testng.annotations.DataProvider;55import org.testng.annotations.Test;56import static org.testng.Assert.*;5758@Test59public class ConfigurationTest {6061/**62* Creates a "non-strict" builder for building a module. This allows the63* test the create ModuleDescriptor objects that do not require java.base.64*/65private static ModuleDescriptor.Builder newBuilder(String mn) {66return SharedSecrets.getJavaLangModuleAccess()67.newModuleBuilder(mn, false, Set.of());68}6970/**71* Basic test of resolver72* m1 requires m2, m2 requires m373*/74public void testBasic() {75ModuleDescriptor descriptor1 = newBuilder("m1")76.requires("m2")77.build();7879ModuleDescriptor descriptor2 = newBuilder("m2")80.requires("m3")81.build();8283ModuleDescriptor descriptor3 = newBuilder("m3")84.build();8586ModuleFinder finder87= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);8889Configuration cf = resolve(finder, "m1");9091assertTrue(cf.modules().size() == 3);9293assertTrue(cf.findModule("m1").isPresent());94assertTrue(cf.findModule("m2").isPresent());95assertTrue(cf.findModule("m3").isPresent());9697assertTrue(cf.parents().size() == 1);98assertTrue(cf.parents().get(0) == Configuration.empty());99100ResolvedModule m1 = cf.findModule("m1").get();101ResolvedModule m2 = cf.findModule("m2").get();102ResolvedModule m3 = cf.findModule("m3").get();103104// m1 reads m2105assertTrue(m1.reads().size() == 1);106assertTrue(m1.reads().contains(m2));107108// m2 reads m3109assertTrue(m2.reads().size() == 1);110assertTrue(m2.reads().contains(m3));111112// m3 reads nothing113assertTrue(m3.reads().size() == 0);114115// toString116assertTrue(cf.toString().contains("m1"));117assertTrue(cf.toString().contains("m2"));118assertTrue(cf.toString().contains("m3"));119}120121122/**123* Basic test of "requires transitive":124* m1 requires m2, m2 requires transitive m3125*/126public void testRequiresTransitive1() {127// m1 requires m2, m2 requires transitive m3128ModuleDescriptor descriptor1 = newBuilder("m1")129.requires("m2")130.build();131132ModuleDescriptor descriptor2 = newBuilder("m2")133.requires(Set.of(Requires.Modifier.TRANSITIVE), "m3")134.build();135136ModuleDescriptor descriptor3 = newBuilder("m3")137.build();138139ModuleFinder finder140= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);141142Configuration cf = resolve(finder, "m1");143144assertTrue(cf.modules().size() == 3);145146assertTrue(cf.findModule("m1").isPresent());147assertTrue(cf.findModule("m2").isPresent());148assertTrue(cf.findModule("m3").isPresent());149150assertTrue(cf.parents().size() == 1);151assertTrue(cf.parents().get(0) == Configuration.empty());152153ResolvedModule m1 = cf.findModule("m1").get();154ResolvedModule m2 = cf.findModule("m2").get();155ResolvedModule m3 = cf.findModule("m3").get();156157// m1 reads m2 and m3158assertTrue(m1.reads().size() == 2);159assertTrue(m1.reads().contains(m2));160assertTrue(m1.reads().contains(m3));161162// m2 reads m3163assertTrue(m2.reads().size() == 1);164assertTrue(m2.reads().contains(m3));165166// m3 reads nothing167assertTrue(m3.reads().size() == 0);168}169170171/**172* Basic test of "requires transitive" with configurations.173*174* The test consists of three configurations:175* - Configuration cf1: m1, m2 requires transitive m1176* - Configuration cf2: m3 requires m2177*/178public void testRequiresTransitive2() {179180// cf1: m1 and m2, m2 requires transitive m1181182ModuleDescriptor descriptor1 = newBuilder("m1")183.build();184185ModuleDescriptor descriptor2 = newBuilder("m2")186.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")187.build();188189ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);190191Configuration cf1 = resolve(finder1, "m2");192193assertTrue(cf1.modules().size() == 2);194assertTrue(cf1.findModule("m1").isPresent());195assertTrue(cf1.findModule("m2").isPresent());196assertTrue(cf1.parents().size() == 1);197assertTrue(cf1.parents().get(0) == Configuration.empty());198199ResolvedModule m1 = cf1.findModule("m1").get();200ResolvedModule m2 = cf1.findModule("m2").get();201202assertTrue(m1.reads().size() == 0);203assertTrue(m2.reads().size() == 1);204assertTrue(m2.reads().contains(m1));205206207// cf2: m3, m3 requires m2208209ModuleDescriptor descriptor3 = newBuilder("m3")210.requires("m2")211.build();212213ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);214215Configuration cf2 = resolve(cf1, finder2, "m3");216217assertTrue(cf2.modules().size() == 1);218assertTrue(cf2.findModule("m1").isPresent()); // in parent219assertTrue(cf2.findModule("m2").isPresent()); // in parent220assertTrue(cf2.findModule("m3").isPresent());221assertTrue(cf2.parents().size() == 1);222assertTrue(cf2.parents().get(0) == cf1);223224ResolvedModule m3 = cf2.findModule("m3").get();225assertTrue(m3.configuration() == cf2);226assertTrue(m3.reads().size() == 2);227assertTrue(m3.reads().contains(m1));228assertTrue(m3.reads().contains(m2));229}230231232/**233* Basic test of "requires transitive" with configurations.234*235* The test consists of three configurations:236* - Configuration cf1: m1237* - Configuration cf2: m2 requires transitive m1, m3 requires m2238*/239public void testRequiresTransitive3() {240241// cf1: m1242243ModuleDescriptor descriptor1 = newBuilder("m1").build();244245ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);246247Configuration cf1 = resolve(finder1, "m1");248249assertTrue(cf1.modules().size() == 1);250assertTrue(cf1.findModule("m1").isPresent());251assertTrue(cf1.parents().size() == 1);252assertTrue(cf1.parents().get(0) == Configuration.empty());253254ResolvedModule m1 = cf1.findModule("m1").get();255assertTrue(m1.reads().size() == 0);256257258// cf2: m2, m3: m2 requires transitive m1, m3 requires m2259260ModuleDescriptor descriptor2 = newBuilder("m2")261.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")262.build();263264ModuleDescriptor descriptor3 = newBuilder("m3")265.requires("m2")266.build();267268ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3);269270Configuration cf2 = resolve(cf1, finder2, "m3");271272assertTrue(cf2.modules().size() == 2);273assertTrue(cf2.findModule("m1").isPresent()); // in parent274assertTrue(cf2.findModule("m2").isPresent());275assertTrue(cf2.findModule("m3").isPresent());276assertTrue(cf2.parents().size() == 1);277assertTrue(cf2.parents().get(0) == cf1);278279ResolvedModule m2 = cf2.findModule("m2").get();280ResolvedModule m3 = cf2.findModule("m3").get();281282assertTrue(m2.configuration() == cf2);283assertTrue(m2.reads().size() == 1);284assertTrue(m2.reads().contains(m1));285286assertTrue(m3.configuration() == cf2);287assertTrue(m3.reads().size() == 2);288assertTrue(m3.reads().contains(m1));289assertTrue(m3.reads().contains(m2));290}291292293/**294* Basic test of "requires transitive" with configurations.295*296* The test consists of three configurations:297* - Configuration cf1: m1298* - Configuration cf2: m2 requires transitive m1299* - Configuraiton cf3: m3 requires m2300*/301public void testRequiresTransitive4() {302303// cf1: m1304305ModuleDescriptor descriptor1 = newBuilder("m1").build();306307ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);308309Configuration cf1 = resolve(finder1, "m1");310311assertTrue(cf1.modules().size() == 1);312assertTrue(cf1.findModule("m1").isPresent());313assertTrue(cf1.parents().size() == 1);314assertTrue(cf1.parents().get(0) == Configuration.empty());315316ResolvedModule m1 = cf1.findModule("m1").get();317assertTrue(m1.reads().size() == 0);318319320// cf2: m2 requires transitive m1321322ModuleDescriptor descriptor2 = newBuilder("m2")323.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")324.build();325326ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);327328Configuration cf2 = resolve(cf1, finder2, "m2");329330assertTrue(cf2.modules().size() == 1);331assertTrue(cf2.findModule("m1").isPresent()); // in parent332assertTrue(cf2.findModule("m2").isPresent());333assertTrue(cf2.parents().size() == 1);334assertTrue(cf2.parents().get(0) == cf1);335336ResolvedModule m2 = cf2.findModule("m2").get();337338assertTrue(m2.configuration() == cf2);339assertTrue(m2.reads().size() == 1);340assertTrue(m2.reads().contains(m1));341342343// cf3: m3 requires m2344345ModuleDescriptor descriptor3 = newBuilder("m3")346.requires("m2")347.build();348349ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3);350351Configuration cf3 = resolve(cf2, finder3, "m3");352353assertTrue(cf3.modules().size() == 1);354assertTrue(cf3.findModule("m1").isPresent()); // in parent355assertTrue(cf3.findModule("m2").isPresent()); // in parent356assertTrue(cf3.findModule("m3").isPresent());357assertTrue(cf3.parents().size() == 1);358assertTrue(cf3.parents().get(0) == cf2);359360ResolvedModule m3 = cf3.findModule("m3").get();361362assertTrue(m3.configuration() == cf3);363assertTrue(m3.reads().size() == 2);364assertTrue(m3.reads().contains(m1));365assertTrue(m3.reads().contains(m2));366}367368369/**370* Basic test of "requires transitive" with configurations.371*372* The test consists of two configurations:373* - Configuration cf1: m1, m2 requires transitive m1374* - Configuration cf2: m3 requires transitive m2, m4 requires m3375*/376public void testRequiresTransitive5() {377378// cf1: m1, m2 requires transitive m1379380ModuleDescriptor descriptor1 = newBuilder("m1")381.build();382383ModuleDescriptor descriptor2 = newBuilder("m2")384.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")385.build();386387ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);388389Configuration cf1 = resolve(finder1, "m2");390391assertTrue(cf1.modules().size() == 2);392assertTrue(cf1.findModule("m1").isPresent());393assertTrue(cf1.findModule("m2").isPresent());394assertTrue(cf1.parents().size() == 1);395assertTrue(cf1.parents().get(0) == Configuration.empty());396397ResolvedModule m1 = cf1.findModule("m1").get();398ResolvedModule m2 = cf1.findModule("m2").get();399400assertTrue(m1.configuration() == cf1);401assertTrue(m1.reads().size() == 0);402403assertTrue(m2.configuration() == cf1);404assertTrue(m2.reads().size() == 1);405assertTrue(m2.reads().contains(m1));406407408// cf2: m3 requires transitive m2, m4 requires m3409410ModuleDescriptor descriptor3 = newBuilder("m3")411.requires(Set.of(Requires.Modifier.TRANSITIVE), "m2")412.build();413414ModuleDescriptor descriptor4 = newBuilder("m4")415.requires("m3")416.build();417418419ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);420421Configuration cf2 = resolve(cf1, finder2, "m3", "m4");422423assertTrue(cf2.modules().size() == 2);424assertTrue(cf2.findModule("m1").isPresent()); // in parent425assertTrue(cf2.findModule("m2").isPresent()); // in parent426assertTrue(cf2.findModule("m3").isPresent());427assertTrue(cf2.findModule("m4").isPresent());428assertTrue(cf2.parents().size() == 1);429assertTrue(cf2.parents().get(0) == cf1);430431ResolvedModule m3 = cf2.findModule("m3").get();432ResolvedModule m4 = cf2.findModule("m4").get();433434assertTrue(m3.configuration() == cf2);435assertTrue(m3.reads().size() == 2);436assertTrue(m3.reads().contains(m1));437assertTrue(m3.reads().contains(m2));438439assertTrue(m4.configuration() == cf2);440assertTrue(m4.reads().size() == 3);441assertTrue(m4.reads().contains(m1));442assertTrue(m4.reads().contains(m2));443assertTrue(m4.reads().contains(m3));444}445446447/**448* Basic test of "requires static":449* m1 requires static m2450* m2 is not observable451* resolve m1452*/453public void testRequiresStatic1() {454ModuleDescriptor descriptor1 = newBuilder("m1")455.requires(Set.of(Requires.Modifier.STATIC), "m2")456.build();457458ModuleFinder finder = ModuleUtils.finderOf(descriptor1);459460Configuration cf = resolve(finder, "m1");461462assertTrue(cf.modules().size() == 1);463464ResolvedModule m1 = cf.findModule("m1").get();465assertTrue(m1.reads().size() == 0);466}467468469/**470* Basic test of "requires static":471* m1 requires static m2472* m2473* resolve m1474*/475public void testRequiresStatic2() {476ModuleDescriptor descriptor1 = newBuilder("m1")477.requires(Set.of(Requires.Modifier.STATIC), "m2")478.build();479480ModuleDescriptor descriptor2 = newBuilder("m2")481.build();482483ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);484485Configuration cf = resolve(finder, "m1");486487assertTrue(cf.modules().size() == 1);488489ResolvedModule m1 = cf.findModule("m1").get();490assertTrue(m1.reads().size() == 0);491}492493494/**495* Basic test of "requires static":496* m1 requires static m2497* m2498* resolve m1, m2499*/500public void testRequiresStatic3() {501ModuleDescriptor descriptor1 = newBuilder("m1")502.requires(Set.of(Requires.Modifier.STATIC), "m2")503.build();504505ModuleDescriptor descriptor2 = newBuilder("m2")506.build();507508ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);509510Configuration cf = resolve(finder, "m1", "m2");511512assertTrue(cf.modules().size() == 2);513514ResolvedModule m1 = cf.findModule("m1").get();515ResolvedModule m2 = cf.findModule("m2").get();516517assertTrue(m1.reads().size() == 1);518assertTrue(m1.reads().contains(m2));519520assertTrue(m2.reads().size() == 0);521}522523524/**525* Basic test of "requires static":526* m1 requires m2, m3527* m2 requires static m2528* m3529*/530public void testRequiresStatic4() {531ModuleDescriptor descriptor1 = newBuilder("m1")532.requires("m2")533.requires("m3")534.build();535536ModuleDescriptor descriptor2 = newBuilder("m2")537.requires(Set.of(Requires.Modifier.STATIC), "m3")538.build();539540ModuleDescriptor descriptor3 = newBuilder("m3")541.build();542543ModuleFinder finder544= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);545546Configuration cf = resolve(finder, "m1");547548assertTrue(cf.modules().size() == 3);549550ResolvedModule m1 = cf.findModule("m1").get();551ResolvedModule m2 = cf.findModule("m2").get();552ResolvedModule m3 = cf.findModule("m3").get();553554assertTrue(m1.reads().size() == 2);555assertTrue(m1.reads().contains(m2));556assertTrue(m1.reads().contains(m3));557558assertTrue(m2.reads().size() == 1);559assertTrue(m2.reads().contains(m3));560561assertTrue(m3.reads().size() == 0);562}563564565/**566* Basic test of "requires static":567* The test consists of three configurations:568* - Configuration cf1: m1, m2569* - Configuration cf2: m3 requires m1, requires static m2570*/571public void testRequiresStatic5() {572ModuleDescriptor descriptor1 = newBuilder("m1")573.build();574575ModuleDescriptor descriptor2 = newBuilder("m2")576.build();577578ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);579580Configuration cf1 = resolve(finder1, "m1", "m2");581582assertTrue(cf1.modules().size() == 2);583assertTrue(cf1.findModule("m1").isPresent());584assertTrue(cf1.findModule("m2").isPresent());585586ModuleDescriptor descriptor3 = newBuilder("m3")587.requires("m1")588.requires(Set.of(Requires.Modifier.STATIC), "m2")589.build();590591ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);592593Configuration cf2 = resolve(cf1, finder2, "m3");594595assertTrue(cf2.modules().size() == 1);596assertTrue(cf2.findModule("m3").isPresent());597598ResolvedModule m1 = cf1.findModule("m1").get();599ResolvedModule m2 = cf1.findModule("m2").get();600ResolvedModule m3 = cf2.findModule("m3").get();601602assertTrue(m3.reads().size() == 2);603assertTrue(m3.reads().contains(m1));604assertTrue(m3.reads().contains(m2));605}606607608/**609* Basic test of "requires static":610* The test consists of three configurations:611* - Configuration cf1: m1612* - Configuration cf2: m3 requires m1, requires static m2613*/614public void testRequiresStatic6() {615ModuleDescriptor descriptor1 = newBuilder("m1")616.build();617618ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);619620Configuration cf1 = resolve(finder1, "m1");621622assertTrue(cf1.modules().size() == 1);623assertTrue(cf1.findModule("m1").isPresent());624625ModuleDescriptor descriptor3 = newBuilder("m3")626.requires("m1")627.requires(Set.of(Requires.Modifier.STATIC), "m2")628.build();629630ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);631632Configuration cf2 = resolve(cf1, finder2, "m3");633634assertTrue(cf2.modules().size() == 1);635assertTrue(cf2.findModule("m3").isPresent());636637ResolvedModule m1 = cf1.findModule("m1").get();638ResolvedModule m3 = cf2.findModule("m3").get();639640assertTrue(m3.reads().size() == 1);641assertTrue(m3.reads().contains(m1));642}643644645/**646* Basic test of "requires static":647* (m1 not observable)648* m2 requires transitive static m1649* m3 requires m2650*/651public void testRequiresStatic7() {652ModuleDescriptor descriptor1 = null; // not observable653654ModuleDescriptor descriptor2 = newBuilder("m2")655.requires(Set.of(Requires.Modifier.TRANSITIVE,656Requires.Modifier.STATIC),657"m1")658.build();659660ModuleDescriptor descriptor3 = newBuilder("m3")661.requires("m2")662.build();663664ModuleFinder finder = ModuleUtils.finderOf(descriptor2, descriptor3);665666Configuration cf = resolve(finder, "m3");667668assertTrue(cf.modules().size() == 2);669assertTrue(cf.findModule("m2").isPresent());670assertTrue(cf.findModule("m3").isPresent());671ResolvedModule m2 = cf.findModule("m2").get();672ResolvedModule m3 = cf.findModule("m3").get();673assertTrue(m2.reads().isEmpty());674assertTrue(m3.reads().size() == 1);675assertTrue(m3.reads().contains(m2));676}677678679/**680* Basic test of "requires static":681* - Configuration cf1: m2 requires transitive static m1682* - Configuration cf2: m3 requires m2683*/684public void testRequiresStatic8() {685ModuleDescriptor descriptor1 = null; // not observable686687ModuleDescriptor descriptor2 = newBuilder("m2")688.requires(Set.of(Requires.Modifier.TRANSITIVE,689Requires.Modifier.STATIC),690"m1")691.build();692693ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2);694695Configuration cf1 = resolve(finder1, "m2");696697assertTrue(cf1.modules().size() == 1);698assertTrue(cf1.findModule("m2").isPresent());699ResolvedModule m2 = cf1.findModule("m2").get();700assertTrue(m2.reads().isEmpty());701702ModuleDescriptor descriptor3 = newBuilder("m3")703.requires("m2")704.build();705706ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);707708Configuration cf2 = resolve(cf1, finder2, "m3");709710assertTrue(cf2.modules().size() == 1);711assertTrue(cf2.findModule("m3").isPresent());712ResolvedModule m3 = cf2.findModule("m3").get();713assertTrue(m3.reads().size() == 1);714assertTrue(m3.reads().contains(m2));715}716717718/**719* Basic test of binding services720* m1 uses p.S721* m2 provides p.S722*/723public void testServiceBinding1() {724725ModuleDescriptor descriptor1 = newBuilder("m1")726.exports("p")727.uses("p.S")728.build();729730ModuleDescriptor descriptor2 = newBuilder("m2")731.requires("m1")732.provides("p.S", List.of("q.T"))733.build();734735ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);736737Configuration cf = resolveAndBind(finder, "m1");738739assertTrue(cf.modules().size() == 2);740assertTrue(cf.findModule("m1").isPresent());741assertTrue(cf.findModule("m2").isPresent());742assertTrue(cf.parents().size() == 1);743assertTrue(cf.parents().get(0) == Configuration.empty());744745ResolvedModule m1 = cf.findModule("m1").get();746ResolvedModule m2 = cf.findModule("m2").get();747748assertTrue(m1.configuration() == cf);749assertTrue(m1.reads().size() == 0);750751assertTrue(m2.configuration() == cf);752assertTrue(m2.reads().size() == 1);753assertTrue(m2.reads().contains(m1));754}755756757/**758* Basic test of binding services759* m1 uses p.S1760* m2 provides p.S1, m2 uses p.S2761* m3 provides p.S2762*/763public void testServiceBinding2() {764765ModuleDescriptor descriptor1 = newBuilder("m1")766.exports("p")767.uses("p.S1")768.build();769770ModuleDescriptor descriptor2 = newBuilder("m2")771.requires("m1")772.uses("p.S2")773.provides("p.S1", List.of("q.Service1Impl"))774.build();775776ModuleDescriptor descriptor3 = newBuilder("m3")777.requires("m1")778.provides("p.S2", List.of("q.Service2Impl"))779.build();780781ModuleFinder finder782= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);783784Configuration cf = resolveAndBind(finder, "m1");785786assertTrue(cf.modules().size() == 3);787assertTrue(cf.findModule("m1").isPresent());788assertTrue(cf.findModule("m2").isPresent());789assertTrue(cf.findModule("m3").isPresent());790assertTrue(cf.parents().size() == 1);791assertTrue(cf.parents().get(0) == Configuration.empty());792793ResolvedModule m1 = cf.findModule("m1").get();794ResolvedModule m2 = cf.findModule("m2").get();795ResolvedModule m3 = cf.findModule("m3").get();796797assertTrue(m1.configuration() == cf);798assertTrue(m1.reads().size() == 0);799800assertTrue(m2.configuration() == cf);801assertTrue(m2.reads().size() == 1);802assertTrue(m2.reads().contains(m1));803804assertTrue(m3.configuration() == cf);805assertTrue(m3.reads().size() == 1);806assertTrue(m3.reads().contains(m1));807}808809810/**811* Basic test of binding services with configurations.812*813* The test consists of two configurations:814* - Configuration cf1: m1 uses p.S815* - Configuration cf2: m2 provides p.S816*/817public void testServiceBindingWithConfigurations1() {818819ModuleDescriptor descriptor1 = newBuilder("m1")820.exports("p")821.uses("p.S")822.build();823824ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);825826Configuration cf1 = resolve(finder1, "m1");827828assertTrue(cf1.modules().size() == 1);829assertTrue(cf1.findModule("m1").isPresent());830831ModuleDescriptor descriptor2 = newBuilder("m2")832.requires("m1")833.provides("p.S", List.of("q.T"))834.build();835836ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);837838Configuration cf2 = resolveAndBind(cf1, finder2); // no roots839840assertTrue(cf2.parents().size() == 1);841assertTrue(cf2.parents().get(0) == cf1);842843assertTrue(cf2.modules().size() == 1);844assertTrue(cf2.findModule("m2").isPresent());845846ResolvedModule m1 = cf1.findModule("m1").get();847ResolvedModule m2 = cf2.findModule("m2").get();848849assertTrue(m2.reads().size() == 1);850assertTrue(m2.reads().contains(m1));851}852853854/**855* Basic test of binding services with configurations.856*857* The test consists of two configurations:858* - Configuration cf1: m1 uses p.S && provides p.S,859* m2 provides p.S860* - Configuration cf2: m3 provides p.S861* m4 provides p.S862*/863public void testServiceBindingWithConfigurations2() {864865ModuleDescriptor descriptor1 = newBuilder("m1")866.exports("p")867.uses("p.S")868.provides("p.S", List.of("p1.ServiceImpl"))869.build();870871ModuleDescriptor descriptor2 = newBuilder("m2")872.requires("m1")873.provides("p.S", List.of("p2.ServiceImpl"))874.build();875876ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);877878Configuration cf1 = resolveAndBind(finder1, "m1");879880assertTrue(cf1.modules().size() == 2);881assertTrue(cf1.findModule("m1").isPresent());882assertTrue(cf1.findModule("m2").isPresent());883884885ModuleDescriptor descriptor3 = newBuilder("m3")886.requires("m1")887.provides("p.S", List.of("p3.ServiceImpl"))888.build();889890ModuleDescriptor descriptor4 = newBuilder("m4")891.requires("m1")892.provides("p.S", List.of("p4.ServiceImpl"))893.build();894895ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);896897Configuration cf2 = resolveAndBind(cf1, finder2); // no roots898899assertTrue(cf2.parents().size() == 1);900assertTrue(cf2.parents().get(0) == cf1);901902assertTrue(cf2.modules().size() == 2);903assertTrue(cf2.findModule("m3").isPresent());904assertTrue(cf2.findModule("m4").isPresent());905906ResolvedModule m1 = cf2.findModule("m1").get(); // should find in parent907ResolvedModule m2 = cf2.findModule("m2").get();908ResolvedModule m3 = cf2.findModule("m3").get();909ResolvedModule m4 = cf2.findModule("m4").get();910911assertTrue(m1.reads().size() == 0);912913assertTrue(m2.reads().size() == 1);914assertTrue(m2.reads().contains(m1));915916assertTrue(m3.reads().size() == 1);917assertTrue(m3.reads().contains(m1));918919assertTrue(m4.reads().size() == 1);920assertTrue(m4.reads().contains(m1));921}922923924/**925* Basic test of binding services with configurations.926*927* Configuration cf1: [email protected] provides p.S928* Test configuration cf2: m1 uses p.S, [email protected] provides p.S929* Test configuration cf2: m1 uses p.S930*/931public void testServiceBindingWithConfigurations3() {932933ModuleDescriptor service = newBuilder("s")934.exports("p")935.build();936937ModuleDescriptor provider_v1 = newBuilder("p")938.version("1.0")939.requires("s")940.provides("p.S", List.of("q.T"))941.build();942943ModuleFinder finder1 = ModuleUtils.finderOf(service, provider_v1);944945Configuration cf1 = resolve(finder1, "p");946947assertTrue(cf1.modules().size() == 2);948assertTrue(cf1.findModule("s").isPresent());949assertTrue(cf1.findModule("p").isPresent());950951// [email protected] in cf1952ResolvedModule p = cf1.findModule("p").get();953assertEquals(p.reference().descriptor(), provider_v1);954955956ModuleDescriptor descriptor1 = newBuilder("m1")957.requires("s")958.uses("p.S")959.build();960961ModuleDescriptor provider_v2 = newBuilder("p")962.version("2.0")963.requires("s")964.provides("p.S", List.of("q.T"))965.build();966967ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, provider_v2);968969970// finder2 is the before ModuleFinder and so [email protected] should be located971972Configuration cf2 = resolveAndBind(cf1, finder2, "m1");973974assertTrue(cf2.parents().size() == 1);975assertTrue(cf2.parents().get(0) == cf1);976assertTrue(cf2.modules().size() == 2);977978// p should be found in cf2979p = cf2.findModule("p").get();980assertTrue(p.configuration() == cf2);981assertEquals(p.reference().descriptor(), provider_v2);982983984// finder2 is the after ModuleFinder and so [email protected] should not be located985// as module p is in parent configuration.986987cf2 = resolveAndBind(cf1, ModuleFinder.of(), finder2, "m1");988989assertTrue(cf2.parents().size() == 1);990assertTrue(cf2.parents().get(0) == cf1);991assertTrue(cf2.modules().size() == 1);992993// p should be found in cf1994p = cf2.findModule("p").get();995assertTrue(p.configuration() == cf1);996assertEquals(p.reference().descriptor(), provider_v1);997}9989991000/**1001* Basic test with two module finders.1002*1003* Module m2 can be found by both the before and after finders.1004*/1005public void testWithTwoFinders1() {10061007ModuleDescriptor descriptor1 = newBuilder("m1")1008.requires("m2")1009.build();10101011ModuleDescriptor descriptor2_v1 = newBuilder("m2")1012.version("1.0")1013.build();10141015ModuleDescriptor descriptor2_v2 = newBuilder("m2")1016.version("2.0")1017.build();10181019ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2_v1);1020ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor2_v2);10211022Configuration cf = resolve(finder1, finder2, "m1");10231024assertTrue(cf.modules().size() == 2);1025assertTrue(cf.findModule("m1").isPresent());1026assertTrue(cf.findModule("m2").isPresent());10271028ResolvedModule m1 = cf.findModule("m1").get();1029ResolvedModule m2 = cf.findModule("m2").get();10301031assertEquals(m1.reference().descriptor(), descriptor1);1032assertEquals(m2.reference().descriptor(), descriptor2_v1);1033}103410351036/**1037* Basic test with two modules finders and service binding.1038*1039* The before and after ModuleFinders both locate a service provider module1040* named "m2" that provide implementations of the same service type.1041*/1042public void testWithTwoFinders2() {10431044ModuleDescriptor descriptor1 = newBuilder("m1")1045.exports("p")1046.uses("p.S")1047.build();10481049ModuleDescriptor descriptor2_v1 = newBuilder("m2")1050.requires("m1")1051.provides("p.S", List.of("q.T"))1052.build();10531054ModuleDescriptor descriptor2_v2 = newBuilder("m2")1055.requires("m1")1056.provides("p.S", List.of("q.T"))1057.build();10581059ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2_v1);1060ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2_v2);10611062Configuration cf = resolveAndBind(finder1, finder2, "m1");10631064assertTrue(cf.modules().size() == 2);1065assertTrue(cf.findModule("m1").isPresent());1066assertTrue(cf.findModule("m2").isPresent());10671068ResolvedModule m1 = cf.findModule("m1").get();1069ResolvedModule m2 = cf.findModule("m2").get();10701071assertEquals(m1.reference().descriptor(), descriptor1);1072assertEquals(m2.reference().descriptor(), descriptor2_v1);1073}107410751076/**1077* Basic test for resolving a module that is located in the parent1078* configuration.1079*/1080public void testResolvedInParent1() {10811082ModuleDescriptor descriptor1 = newBuilder("m1")1083.build();10841085ModuleFinder finder = ModuleUtils.finderOf(descriptor1);10861087Configuration cf1 = resolve(finder, "m1");10881089assertTrue(cf1.modules().size() == 1);1090assertTrue(cf1.findModule("m1").isPresent());10911092Configuration cf2 = resolve(cf1, finder, "m1");10931094assertTrue(cf2.modules().size() == 1);1095}109610971098/**1099* Basic test for resolving a module that has a dependency on a module1100* in the parent configuration.1101*/1102public void testResolvedInParent2() {11031104ModuleDescriptor descriptor1 = newBuilder("m1").build();11051106ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);11071108Configuration cf1 = resolve(finder1, "m1");11091110assertTrue(cf1.modules().size() == 1);1111assertTrue(cf1.findModule("m1").isPresent());111211131114ModuleDescriptor descriptor2 = newBuilder("m2")1115.requires("m1")1116.build();11171118ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);11191120Configuration cf2 = resolve(cf1, ModuleFinder.of(), finder2, "m2");11211122assertTrue(cf2.modules().size() == 1);1123assertTrue(cf2.findModule("m2").isPresent());11241125ResolvedModule m1 = cf2.findModule("m1").get(); // find in parent1126ResolvedModule m2 = cf2.findModule("m2").get();11271128assertTrue(m1.reads().size() == 0);1129assertTrue(m2.reads().size() == 1);1130assertTrue(m2.reads().contains(m1));1131}113211331134/**1135* Basic test of resolving a module that depends on modules in two parent1136* configurations.1137*1138* The test consists of three configurations:1139* - Configuration cf1: m11140* - Configuration cf2: m21141* - Configuration cf3(cf1,cf2): m3 requires m1, m21142*/1143public void testResolvedInMultipleParents1() {11441145// Configuration cf1: m11146ModuleDescriptor descriptor1 = newBuilder("m1").build();1147Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");1148assertEquals(cf1.parents(), List.of(Configuration.empty()));1149assertTrue(cf1.findModule("m1").isPresent());1150ResolvedModule m1 = cf1.findModule("m1").get();1151assertTrue(m1.configuration() == cf1);11521153// Configuration cf2: m21154ModuleDescriptor descriptor2 = newBuilder("m2").build();1155Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2");1156assertEquals(cf2.parents(), List.of(Configuration.empty()));1157assertTrue(cf2.findModule("m2").isPresent());1158ResolvedModule m2 = cf2.findModule("m2").get();1159assertTrue(m2.configuration() == cf2);11601161// Configuration cf3(cf1,cf2): m3 requires m1 and m21162ModuleDescriptor descriptor3 = newBuilder("m3")1163.requires("m1")1164.requires("m2")1165.build();1166ModuleFinder finder = ModuleUtils.finderOf(descriptor3);1167Configuration cf3 = Configuration.resolve(1168finder,1169List.of(cf1, cf2), // parents1170ModuleFinder.of(),1171Set.of("m3"));1172assertEquals(cf3.parents(), List.of(cf1, cf2));1173assertTrue(cf3.findModule("m3").isPresent());1174ResolvedModule m3 = cf3.findModule("m3").get();1175assertTrue(m3.configuration() == cf3);11761177// check readability1178assertTrue(m1.reads().isEmpty());1179assertTrue(m2.reads().isEmpty());1180assertEquals(m3.reads(), Set.of(m1, m2));1181}118211831184/**1185* Basic test of resolving a module that depends on modules in three parent1186* configurations arranged in a diamond (two direct parents).1187*1188* The test consists of four configurations:1189* - Configuration cf1: m11190* - Configuration cf2(cf1): m2 requires m11191* - Configuration cf3(cf3): m3 requires m11192* - Configuration cf4(cf2,cf3): m4 requires m1,m2,m31193*/1194public void testResolvedInMultipleParents2() {1195// Configuration cf1: m11196ModuleDescriptor descriptor1 = newBuilder("m1").build();1197Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");1198assertEquals(cf1.parents(), List.of(Configuration.empty()));1199assertTrue(cf1.findModule("m1").isPresent());1200ResolvedModule m1 = cf1.findModule("m1").get();1201assertTrue(m1.configuration() == cf1);12021203// Configuration cf2(cf1): m2 requires m11204ModuleDescriptor descriptor2 = newBuilder("m2")1205.requires("m1")1206.build();1207Configuration cf2 = Configuration.resolve(1208ModuleUtils.finderOf(descriptor2),1209List.of(cf1), // parents1210ModuleFinder.of(),1211Set.of("m2"));1212assertEquals(cf2.parents(), List.of(cf1));1213assertTrue(cf2.findModule("m2").isPresent());1214ResolvedModule m2 = cf2.findModule("m2").get();1215assertTrue(m2.configuration() == cf2);12161217// Configuration cf3(cf1): m3 requires m11218ModuleDescriptor descriptor3 = newBuilder("m3")1219.requires("m1")1220.build();1221Configuration cf3 = Configuration.resolve(1222ModuleUtils.finderOf(descriptor3),1223List.of(cf1), // parents1224ModuleFinder.of(),1225Set.of("m3"));1226assertEquals(cf3.parents(), List.of(cf1));1227assertTrue(cf3.findModule("m3").isPresent());1228ResolvedModule m3 = cf3.findModule("m3").get();1229assertTrue(m3.configuration() == cf3);12301231// Configuration cf4(cf2,cf3): m4 requires m1,m2,m31232ModuleDescriptor descriptor4 = newBuilder("m4")1233.requires("m1")1234.requires("m2")1235.requires("m3")1236.build();1237Configuration cf4 = Configuration.resolve(1238ModuleUtils.finderOf(descriptor4),1239List.of(cf2, cf3), // parents1240ModuleFinder.of(),1241Set.of("m4"));1242assertEquals(cf4.parents(), List.of(cf2, cf3));1243assertTrue(cf4.findModule("m4").isPresent());1244ResolvedModule m4 = cf4.findModule("m4").get();1245assertTrue(m4.configuration() == cf4);12461247// check readability1248assertTrue(m1.reads().isEmpty());1249assertEquals(m2.reads(), Set.of(m1));1250assertEquals(m3.reads(), Set.of(m1));1251assertEquals(m4.reads(), Set.of(m1, m2, m3));1252}125312541255/**1256* Basic test of resolving a module that depends on modules in three parent1257* configurations arranged in a diamond (two direct parents).1258*1259* The test consists of four configurations:1260* - Configuration cf1: m1@11261* - Configuration cf2: m1@2, m2@21262* - Configuration cf3: m1@3, m2@3, m3@31263* - Configuration cf4(cf1,cf2,cf3): m4 requires m1,m2,m31264*/1265public void testResolvedInMultipleParents3() {1266ModuleDescriptor descriptor1, descriptor2, descriptor3;12671268// Configuration cf1: m1@11269descriptor1 = newBuilder("m1").version("1").build();1270Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");1271assertEquals(cf1.parents(), List.of(Configuration.empty()));12721273// Configuration cf2: m1@2, m2@21274descriptor1 = newBuilder("m1").version("2").build();1275descriptor2 = newBuilder("m2").version("2").build();1276Configuration cf2 = resolve(1277ModuleUtils.finderOf(descriptor1, descriptor2),1278"m1", "m2");1279assertEquals(cf2.parents(), List.of(Configuration.empty()));12801281// Configuration cf3: m1@3, m2@3, m3@31282descriptor1 = newBuilder("m1").version("3").build();1283descriptor2 = newBuilder("m2").version("3").build();1284descriptor3 = newBuilder("m3").version("3").build();1285Configuration cf3 = resolve(1286ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3),1287"m1", "m2", "m3");1288assertEquals(cf3.parents(), List.of(Configuration.empty()));12891290// Configuration cf4(cf1,cf2,cf3): m4 requires m1,m2,m31291ModuleDescriptor descriptor4 = newBuilder("m4")1292.requires("m1")1293.requires("m2")1294.requires("m3")1295.build();1296Configuration cf4 = Configuration.resolve(1297ModuleUtils.finderOf(descriptor4),1298List.of(cf1, cf2, cf3), // parents1299ModuleFinder.of(),1300Set.of("m4"));1301assertEquals(cf4.parents(), List.of(cf1, cf2, cf3));13021303assertTrue(cf1.findModule("m1").isPresent());1304assertTrue(cf2.findModule("m1").isPresent());1305assertTrue(cf2.findModule("m2").isPresent());1306assertTrue(cf3.findModule("m1").isPresent());1307assertTrue(cf3.findModule("m2").isPresent());1308assertTrue(cf3.findModule("m3").isPresent());1309assertTrue(cf4.findModule("m4").isPresent());13101311ResolvedModule m1_1 = cf1.findModule("m1").get();1312ResolvedModule m1_2 = cf2.findModule("m1").get();1313ResolvedModule m2_2 = cf2.findModule("m2").get();1314ResolvedModule m1_3 = cf3.findModule("m1").get();1315ResolvedModule m2_3 = cf3.findModule("m2").get();1316ResolvedModule m3_3 = cf3.findModule("m3").get();1317ResolvedModule m4 = cf4.findModule("m4").get();13181319assertTrue(m1_1.configuration() == cf1);1320assertTrue(m1_2.configuration() == cf2);1321assertTrue(m2_2.configuration() == cf2);1322assertTrue(m1_3.configuration() == cf3);1323assertTrue(m2_3.configuration() == cf3);1324assertTrue(m3_3.configuration() == cf3);1325assertTrue(m4.configuration() == cf4);13261327// check readability1328assertTrue(m1_1.reads().isEmpty());1329assertTrue(m1_2.reads().isEmpty());1330assertTrue(m2_2.reads().isEmpty());1331assertTrue(m1_3.reads().isEmpty());1332assertTrue(m2_3.reads().isEmpty());1333assertTrue(m3_3.reads().isEmpty());1334assertEquals(m4.reads(), Set.of(m1_1, m2_2, m3_3));1335}133613371338/**1339* Basic test of using the beforeFinder to override a module in a parent1340* configuration.1341*/1342public void testOverriding1() {1343ModuleDescriptor descriptor1 = newBuilder("m1").build();13441345ModuleFinder finder = ModuleUtils.finderOf(descriptor1);13461347Configuration cf1 = resolve(finder, "m1");1348assertTrue(cf1.modules().size() == 1);1349assertTrue(cf1.findModule("m1").isPresent());13501351Configuration cf2 = resolve(cf1, finder, "m1");1352assertTrue(cf2.modules().size() == 1);1353assertTrue(cf2.findModule("m1").isPresent());1354}13551356/**1357* Basic test of using the beforeFinder to override a module in a parent1358* configuration.1359*/1360public void testOverriding2() {1361ModuleDescriptor descriptor1 = newBuilder("m1").build();1362Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");1363assertTrue(cf1.modules().size() == 1);1364assertTrue(cf1.findModule("m1").isPresent());13651366ModuleDescriptor descriptor2 = newBuilder("m2").build();1367Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2");1368assertTrue(cf2.modules().size() == 1);1369assertTrue(cf2.findModule("m2").isPresent());13701371ModuleDescriptor descriptor3 = newBuilder("m3").build();1372Configuration cf3 = resolve(ModuleUtils.finderOf(descriptor3), "m3");1373assertTrue(cf3.modules().size() == 1);1374assertTrue(cf3.findModule("m3").isPresent());13751376// override m2, m1 and m3 should be found in parent configurations1377ModuleFinder finder = ModuleUtils.finderOf(descriptor2);1378Configuration cf4 = Configuration.resolve(1379finder,1380List.of(cf1, cf2, cf3),1381ModuleFinder.of(),1382Set.of("m1", "m2", "m3"));1383assertTrue(cf4.modules().size() == 1);1384assertTrue(cf4.findModule("m2").isPresent());1385ResolvedModule m2 = cf4.findModule("m2").get();1386assertTrue(m2.configuration() == cf4);1387}138813891390/**1391* Basic test of using the beforeFinder to override a module in the parent1392* configuration but where implied readability in the picture so that the1393* module in the parent is read.1394*1395* The test consists of two configurations:1396* - Configuration cf1: m1, m2 requires transitive m11397* - Configuration cf2: m1, m3 requires m21398*/1399public void testOverriding3() {14001401ModuleDescriptor descriptor1 = newBuilder("m1")1402.build();14031404ModuleDescriptor descriptor2 = newBuilder("m2")1405.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")1406.build();14071408ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);14091410Configuration cf1 = resolve(finder1, "m2");14111412assertTrue(cf1.modules().size() == 2);1413assertTrue(cf1.findModule("m1").isPresent());1414assertTrue(cf1.findModule("m2").isPresent());14151416// cf2: m3 requires m2, m114171418ModuleDescriptor descriptor3 = newBuilder("m3")1419.requires("m2")1420.build();14211422ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);14231424Configuration cf2 = resolve(cf1, finder2, "m1", "m3");14251426assertTrue(cf2.parents().size() == 1);1427assertTrue(cf2.parents().get(0) == cf1);14281429assertTrue(cf2.modules().size() == 2);1430assertTrue(cf2.findModule("m1").isPresent());1431assertTrue(cf2.findModule("m3").isPresent());14321433ResolvedModule m1_1 = cf1.findModule("m1").get();1434ResolvedModule m1_2 = cf2.findModule("m1").get();1435ResolvedModule m2 = cf1.findModule("m2").get();1436ResolvedModule m3 = cf2.findModule("m3").get();14371438assertTrue(m1_1.configuration() == cf1);1439assertTrue(m1_2.configuration() == cf2);1440assertTrue(m3.configuration() == cf2);144114421443// check that m3 reads cf1/m1 and cf2/m21444assertTrue(m3.reads().size() == 2);1445assertTrue(m3.reads().contains(m1_1));1446assertTrue(m3.reads().contains(m2));1447}144814491450/**1451* Root module not found1452*/1453@Test(expectedExceptions = { FindException.class })1454public void testRootNotFound() {1455resolve(ModuleFinder.of(), "m1");1456}145714581459/**1460* Direct dependency not found1461*/1462@Test(expectedExceptions = { FindException.class })1463public void testDirectDependencyNotFound() {1464ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();1465ModuleFinder finder = ModuleUtils.finderOf(descriptor1);1466resolve(finder, "m1");1467}146814691470/**1471* Transitive dependency not found1472*/1473@Test(expectedExceptions = { FindException.class })1474public void testTransitiveDependencyNotFound() {1475ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();1476ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build();1477ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);1478resolve(finder, "m1");1479}148014811482/**1483* Service provider dependency not found1484*/1485@Test(expectedExceptions = { FindException.class })1486public void testServiceProviderDependencyNotFound() {14871488// service provider dependency (on m3) not found14891490ModuleDescriptor descriptor1 = newBuilder("m1")1491.exports("p")1492.uses("p.S")1493.build();14941495ModuleDescriptor descriptor2 = newBuilder("m2")1496.requires("m1")1497.requires("m3")1498.provides("p.S", List.of("q.T"))1499.build();15001501ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);15021503// should throw ResolutionException because m3 is not found1504Configuration cf = resolveAndBind(finder, "m1");1505}150615071508/**1509* Simple cycle.1510*/1511@Test(expectedExceptions = { ResolutionException.class })1512public void testSimpleCycle() {1513ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();1514ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build();1515ModuleDescriptor descriptor3 = newBuilder("m3").requires("m1").build();1516ModuleFinder finder1517= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);1518resolve(finder, "m1");1519}15201521/**1522* Basic test for detecting cycles involving a service provider module1523*/1524@Test(expectedExceptions = { ResolutionException.class })1525public void testCycleInProvider() {15261527ModuleDescriptor descriptor1 = newBuilder("m1")1528.exports("p")1529.uses("p.S")1530.build();1531ModuleDescriptor descriptor2 = newBuilder("m2")1532.requires("m1")1533.requires("m3")1534.provides("p.S", List.of("q.T"))1535.build();1536ModuleDescriptor descriptor3 = newBuilder("m3")1537.requires("m2")1538.build();15391540ModuleFinder finder1541= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);15421543// should throw ResolutionException because of the m2 <--> m3 cycle1544resolveAndBind(finder, "m1");1545}154615471548/**1549* Basic test to detect reading a module with the same name as itself1550*1551* The test consists of three configurations:1552* - Configuration cf1: m1, m2 requires transitive m11553* - Configuration cf2: m1 requires m21554*/1555@Test(expectedExceptions = { ResolutionException.class })1556public void testReadModuleWithSameNameAsSelf() {1557ModuleDescriptor descriptor1_v1 = newBuilder("m1")1558.build();15591560ModuleDescriptor descriptor2 = newBuilder("m2")1561.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")1562.build();15631564ModuleDescriptor descriptor1_v2 = newBuilder("m1")1565.requires("m2")1566.build();15671568ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1_v1, descriptor2);1569Configuration cf1 = resolve(finder1, "m2");1570assertTrue(cf1.modules().size() == 2);15711572// resolve should throw ResolutionException1573ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1_v2);1574resolve(cf1, finder2, "m1");1575}157615771578/**1579* Basic test to detect reading two modules with the same name1580*1581* The test consists of three configurations:1582* - Configuration cf1: m1, m2 requires transitive m11583* - Configuration cf2: m1, m3 requires transitive m11584* - Configuration cf3(cf1,cf2): m4 requires m2, m31585*/1586@Test(expectedExceptions = { ResolutionException.class })1587public void testReadTwoModuleWithSameName() {1588ModuleDescriptor descriptor1 = newBuilder("m1")1589.build();15901591ModuleDescriptor descriptor2 = newBuilder("m2")1592.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")1593.build();15941595ModuleDescriptor descriptor3 = newBuilder("m3")1596.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")1597.build();15981599ModuleDescriptor descriptor4 = newBuilder("m4")1600.requires("m2")1601.requires("m3")1602.build();16031604ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);1605Configuration cf1 = resolve(finder1, "m2");1606assertTrue(cf1.modules().size() == 2);16071608ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);1609Configuration cf2 = resolve(finder2, "m3");1610assertTrue(cf2.modules().size() == 2);16111612// should throw ResolutionException as m4 will read modules named "m1".1613ModuleFinder finder3 = ModuleUtils.finderOf(descriptor4);1614Configuration.resolve(finder3, List.of(cf1, cf2), ModuleFinder.of(), Set.of("m4"));1615}161616171618/**1619* Test two modules exporting package p to a module that reads both.1620*/1621@Test(expectedExceptions = { ResolutionException.class })1622public void testPackageSuppliedByTwoOthers() {16231624ModuleDescriptor descriptor1 = newBuilder("m1")1625.requires("m2")1626.requires("m3")1627.build();16281629ModuleDescriptor descriptor2 = newBuilder("m2")1630.exports("p")1631.build();16321633ModuleDescriptor descriptor3 = newBuilder("m3")1634.exports("p", Set.of("m1"))1635.build();16361637ModuleFinder finder1638= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);16391640// m2 and m3 export package p to module m11641resolve(finder, "m1");1642}164316441645/**1646* Test the scenario where a module contains a package p and reads1647* a module that exports package p.1648*/1649@Test(expectedExceptions = { ResolutionException.class })1650public void testPackageSuppliedBySelfAndOther() {16511652ModuleDescriptor descriptor1 = newBuilder("m1")1653.requires("m2")1654.packages(Set.of("p"))1655.build();16561657ModuleDescriptor descriptor2 = newBuilder("m2")1658.exports("p")1659.build();16601661ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);16621663// m1 contains package p, module m2 exports package p to m11664resolve(finder, "m1");1665}166616671668/**1669* Test the scenario where a module contains a package p and reads1670* a module that also contains a package p.1671*/1672public void testContainsPackageInSelfAndOther() {1673ModuleDescriptor descriptor1 = newBuilder("m1")1674.requires("m2")1675.packages(Set.of("p"))1676.build();16771678ModuleDescriptor descriptor2 = newBuilder("m2")1679.packages(Set.of("p"))1680.build();16811682ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);16831684Configuration cf = resolve(finder, "m1");16851686assertTrue(cf.modules().size() == 2);1687assertTrue(cf.findModule("m1").isPresent());1688assertTrue(cf.findModule("m2").isPresent());16891690// m1 reads m2, m2 reads nothing1691ResolvedModule m1 = cf.findModule("m1").get();1692ResolvedModule m2 = cf.findModule("m2").get();1693assertTrue(m1.reads().size() == 1);1694assertTrue(m1.reads().contains(m2));1695assertTrue(m2.reads().size() == 0);1696}169716981699/**1700* Test the scenario where a module that exports a package that is also1701* exported by a module that it reads in a parent layer.1702*/1703@Test(expectedExceptions = { ResolutionException.class })1704public void testExportSamePackageAsBootLayer() {1705ModuleDescriptor descriptor = newBuilder("m1")1706.requires("java.base")1707.exports("java.lang")1708.build();17091710ModuleFinder finder = ModuleUtils.finderOf(descriptor);17111712Configuration bootConfiguration = ModuleLayer.boot().configuration();17131714// m1 contains package java.lang, java.base exports package java.lang to m11715resolve(bootConfiguration, finder, "m1");1716}171717181719/**1720* Test "uses p.S" where p is contained in the same module.1721*/1722public void testContainsService1() {1723ModuleDescriptor descriptor1 = newBuilder("m1")1724.packages(Set.of("p"))1725.uses("p.S")1726.build();17271728ModuleFinder finder = ModuleUtils.finderOf(descriptor1);17291730Configuration cf = resolve(finder, "m1");17311732assertTrue(cf.modules().size() == 1);1733assertTrue(cf.findModule("m1").isPresent());1734}173517361737/**1738* Test "uses p.S" where p is contained in a different module.1739*/1740@Test(expectedExceptions = { ResolutionException.class })1741public void testContainsService2() {1742ModuleDescriptor descriptor1 = newBuilder("m1")1743.packages(Set.of("p"))1744.build();17451746ModuleDescriptor descriptor2 = newBuilder("m2")1747.requires("m1")1748.uses("p.S")1749.build();17501751ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);17521753// m2 does not read a module that exports p1754resolve(finder, "m2");1755}175617571758/**1759* Test "provides p.S" where p is contained in the same module.1760*/1761public void testContainsService3() {1762ModuleDescriptor descriptor1 = newBuilder("m1")1763.packages(Set.of("p", "q"))1764.provides("p.S", List.of("q.S1"))1765.build();17661767ModuleFinder finder = ModuleUtils.finderOf(descriptor1);17681769Configuration cf = resolve(finder, "m1");17701771assertTrue(cf.modules().size() == 1);1772assertTrue(cf.findModule("m1").isPresent());1773}177417751776/**1777* Test "provides p.S" where p is contained in a different module.1778*/1779@Test(expectedExceptions = { ResolutionException.class })1780public void testContainsService4() {1781ModuleDescriptor descriptor1 = newBuilder("m1")1782.packages(Set.of("p"))1783.build();17841785ModuleDescriptor descriptor2 = newBuilder("m2")1786.requires("m1")1787.provides("p.S", List.of("q.S1"))1788.build();17891790ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);17911792// m2 does not read a module that exports p1793resolve(finder, "m2");1794}179517961797/**1798* Test "uses p.S" where p is not exported to the module.1799*/1800@Test(expectedExceptions = { ResolutionException.class })1801public void testServiceTypePackageNotExported1() {1802ModuleDescriptor descriptor1 = newBuilder("m1")1803.uses("p.S")1804.build();18051806ModuleFinder finder = ModuleUtils.finderOf(descriptor1);18071808// m1 does not read a module that exports p1809resolve(finder, "m1");1810}181118121813/**1814* Test "provides p.S" where p is not exported to the module.1815*/1816@Test(expectedExceptions = { ResolutionException.class })1817public void testServiceTypePackageNotExported2() {1818ModuleDescriptor descriptor1 = newBuilder("m1")1819.provides("p.S", List.of("q.T"))1820.build();18211822ModuleFinder finder = ModuleUtils.finderOf(descriptor1);18231824// m1 does not read a module that exports p1825resolve(finder, "m1");1826}182718281829/**1830* Test the empty configuration.1831*/1832public void testEmptyConfiguration() {1833Configuration cf = Configuration.empty();18341835assertTrue(cf.parents().isEmpty());18361837assertTrue(cf.modules().isEmpty());1838assertFalse(cf.findModule("java.base").isPresent());1839}184018411842// platform specific modules18431844@DataProvider(name = "platformmatch")1845public Object[][] createPlatformMatches() {1846return new Object[][]{18471848{ "", "" },1849{ "linux-arm", "" },1850{ "linux-arm", "linux-arm" },18511852};18531854};18551856@DataProvider(name = "platformmismatch")1857public Object[][] createBad() {1858return new Object[][] {18591860{ "linux-x64", "linux-arm" },1861{ "linux-x64", "windows-x64" },18621863};1864}18651866/**1867* Test creating a configuration containing platform specific modules.1868*/1869@Test(dataProvider = "platformmatch")1870public void testPlatformMatch(String s1, String s2) throws IOException {18711872ModuleDescriptor base = ModuleDescriptor.newModule("java.base").build();1873Path system = writeModule(base, null);18741875ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1")1876.requires("m2")1877.build();1878Path dir1 = writeModule(descriptor1, s1);18791880ModuleDescriptor descriptor2 = ModuleDescriptor.newModule("m2").build();1881Path dir2 = writeModule(descriptor2, s2);18821883ModuleFinder finder = ModuleFinder.of(system, dir1, dir2);18841885Configuration cf = resolve(finder, "m1");18861887assertTrue(cf.modules().size() == 3);1888assertTrue(cf.findModule("java.base").isPresent());1889assertTrue(cf.findModule("m1").isPresent());1890assertTrue(cf.findModule("m2").isPresent());1891}18921893/**1894* Test attempting to create a configuration with modules for different1895* platforms.1896*/1897@Test(dataProvider = "platformmismatch",1898expectedExceptions = FindException.class )1899public void testPlatformMisMatch(String s1, String s2) throws IOException {1900testPlatformMatch(s1, s2);1901}19021903// no parents19041905@Test(expectedExceptions = { IllegalArgumentException.class })1906public void testResolveRequiresWithNoParents() {1907ModuleFinder empty = ModuleFinder.of();1908Configuration.resolve(empty, List.of(), empty, Set.of());1909}19101911@Test(expectedExceptions = { IllegalArgumentException.class })1912public void testResolveRequiresAndUsesWithNoParents() {1913ModuleFinder empty = ModuleFinder.of();1914Configuration.resolveAndBind(empty, List.of(), empty, Set.of());1915}191619171918// parents with modules for specific platforms1919@Test(dataProvider = "platformmatch")1920public void testResolveRequiresWithCompatibleParents(String s1, String s2)1921throws IOException1922{1923ModuleDescriptor base = ModuleDescriptor.newModule("java.base").build();1924Path system = writeModule(base, null);19251926ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1").build();1927Path dir1 = writeModule(descriptor1, s1);19281929ModuleDescriptor descriptor2 = ModuleDescriptor.newModule("m2").build();1930Path dir2 = writeModule(descriptor2, s2);19311932ModuleFinder finder1 = ModuleFinder.of(system, dir1);1933Configuration cf1 = resolve(finder1, "m1");19341935ModuleFinder finder2 = ModuleFinder.of(system, dir2);1936Configuration cf2 = resolve(finder2, "m2");19371938Configuration cf3 = Configuration.resolve(ModuleFinder.of(),1939List.of(cf1, cf2),1940ModuleFinder.of(),1941Set.of());1942assertTrue(cf3.parents().size() == 2);1943}194419451946@Test(dataProvider = "platformmismatch",1947expectedExceptions = IllegalArgumentException.class )1948public void testResolveRequiresWithConflictingParents(String s1, String s2)1949throws IOException1950{1951testResolveRequiresWithCompatibleParents(s1, s2);1952}195319541955// null handling19561957// finder1, finder2, roots195819591960@Test(expectedExceptions = { NullPointerException.class })1961public void testResolveRequiresWithNull1() {1962resolve((ModuleFinder)null, ModuleFinder.of());1963}19641965@Test(expectedExceptions = { NullPointerException.class })1966public void testResolveRequiresWithNull2() {1967resolve(ModuleFinder.of(), (ModuleFinder)null);1968}19691970@Test(expectedExceptions = { NullPointerException.class })1971public void testResolveRequiresWithNull3() {1972Configuration empty = Configuration.empty();1973Configuration.resolve(null, List.of(empty), ModuleFinder.of(), Set.of());1974}19751976@Test(expectedExceptions = { NullPointerException.class })1977public void testResolveRequiresWithNull4() {1978ModuleFinder empty = ModuleFinder.of();1979Configuration.resolve(empty, null, empty, Set.of());1980}19811982@Test(expectedExceptions = { NullPointerException.class })1983public void testResolveRequiresWithNull5() {1984Configuration cf = ModuleLayer.boot().configuration();1985Configuration.resolve(ModuleFinder.of(), List.of(cf), null, Set.of());1986}19871988@Test(expectedExceptions = { NullPointerException.class })1989public void testResolveRequiresWithNull6() {1990ModuleFinder empty = ModuleFinder.of();1991Configuration cf = ModuleLayer.boot().configuration();1992Configuration.resolve(empty, List.of(cf), empty, null);1993}19941995@Test(expectedExceptions = { NullPointerException.class })1996public void testResolveRequiresAndUsesWithNull1() {1997resolveAndBind((ModuleFinder) null, ModuleFinder.of());1998}19992000@Test(expectedExceptions = { NullPointerException.class })2001public void testResolveRequiresAndUsesWithNull2() {2002resolveAndBind(ModuleFinder.of(), (ModuleFinder) null);2003}20042005@Test(expectedExceptions = { NullPointerException.class })2006public void testResolveRequiresAndUsesWithNull3() {2007Configuration empty = Configuration.empty();2008Configuration.resolveAndBind(null, List.of(empty), ModuleFinder.of(), Set.of());2009}20102011@Test(expectedExceptions = { NullPointerException.class })2012public void testResolveRequiresAndUsesWithNull4() {2013ModuleFinder empty = ModuleFinder.of();2014Configuration.resolveAndBind(empty, null, empty, Set.of());2015}20162017@Test(expectedExceptions = { NullPointerException.class })2018public void testResolveRequiresAndUsesWithNull5() {2019Configuration cf = ModuleLayer.boot().configuration();2020Configuration.resolveAndBind(ModuleFinder.of(), List.of(cf), null, Set.of());2021}20222023@Test(expectedExceptions = { NullPointerException.class })2024public void testResolveRequiresAndUsesWithNull6() {2025ModuleFinder empty = ModuleFinder.of();2026Configuration cf = ModuleLayer.boot().configuration();2027Configuration.resolveAndBind(empty, List.of(cf), empty, null);2028}20292030@Test(expectedExceptions = { NullPointerException.class })2031public void testFindModuleWithNull() {2032Configuration.empty().findModule(null);2033}20342035// unmodifiable collections20362037@DataProvider(name = "configurations")2038public Object[][] configurations() {2039// empty, boot, and custom configurations2040return new Object[][] {2041{ Configuration.empty(), null },2042{ ModuleLayer.boot().configuration(), null },2043{ resolve(ModuleFinder.of()), null },2044};2045}20462047@Test(dataProvider = "configurations",2048expectedExceptions = { UnsupportedOperationException.class })2049public void testUnmodifiableParents1(Configuration cf, Object ignore) {2050cf.parents().add(Configuration.empty());2051}20522053@Test(dataProvider = "configurations",2054expectedExceptions = { UnsupportedOperationException.class })2055public void testUnmodifiableParents2(Configuration cf, Object ignore) {2056cf.parents().remove(Configuration.empty());2057}20582059@Test(dataProvider = "configurations",2060expectedExceptions = { UnsupportedOperationException.class })2061public void testUnmodifiableModules1(Configuration cf, Object ignore) {2062ResolvedModule module = ModuleLayer.boot()2063.configuration()2064.findModule("java.base")2065.orElseThrow();2066cf.modules().add(module);2067}20682069@Test(dataProvider = "configurations",2070expectedExceptions = { UnsupportedOperationException.class })2071public void testUnmodifiableModules2(Configuration cf, Object ignore) {2072ResolvedModule module = ModuleLayer.boot()2073.configuration()2074.findModule("java.base")2075.orElseThrow();2076cf.modules().remove(module);2077}20782079/**2080* Invokes parent.resolve(...)2081*/2082private Configuration resolve(Configuration parent,2083ModuleFinder before,2084ModuleFinder after,2085String... roots) {2086return parent.resolve(before, after, Set.of(roots));2087}20882089private Configuration resolve(Configuration parent,2090ModuleFinder before,2091String... roots) {2092return resolve(parent, before, ModuleFinder.of(), roots);2093}20942095private Configuration resolve(ModuleFinder before,2096ModuleFinder after,2097String... roots) {2098return resolve(Configuration.empty(), before, after, roots);2099}21002101private Configuration resolve(ModuleFinder before,2102String... roots) {2103return resolve(Configuration.empty(), before, roots);2104}210521062107/**2108* Invokes parent.resolveAndBind(...)2109*/2110private Configuration resolveAndBind(Configuration parent,2111ModuleFinder before,2112ModuleFinder after,2113String... roots) {2114return parent.resolveAndBind(before, after, Set.of(roots));2115}21162117private Configuration resolveAndBind(Configuration parent,2118ModuleFinder before,2119String... roots) {2120return resolveAndBind(parent, before, ModuleFinder.of(), roots);2121}21222123private Configuration resolveAndBind(ModuleFinder before,2124ModuleFinder after,2125String... roots) {2126return resolveAndBind(Configuration.empty(), before, after, roots);2127}21282129private Configuration resolveAndBind(ModuleFinder before,2130String... roots) {2131return resolveAndBind(Configuration.empty(), before, roots);2132}213321342135/**2136* Writes a module-info.class. If {@code targetPlatform} is not null then2137* it includes the ModuleTarget class file attribute with the target platform.2138*/2139static Path writeModule(ModuleDescriptor descriptor, String targetPlatform)2140throws IOException2141{2142ModuleTarget target;2143if (targetPlatform != null) {2144target = new ModuleTarget(targetPlatform);2145} else {2146target = null;2147}2148String name = descriptor.name();2149Path dir = Files.createTempDirectory(Paths.get(""), name);2150Path mi = dir.resolve("module-info.class");2151try (OutputStream out = Files.newOutputStream(mi)) {2152ModuleInfoWriter.write(descriptor, target, out);2153}2154return dir;2155}2156}215721582159