< prev index next >

test/java/lang/module/ConfigurationTest.java

Print this page


   1 /*
   2  * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @library /lib/testlibrary

  27  * @build ConfigurationTest ModuleUtils
  28  * @run testng ConfigurationTest
  29  * @summary Basic tests for java.lang.module.Configuration
  30  */
  31 
  32 import java.lang.module.Configuration;

  33 import java.lang.module.ModuleDescriptor;

  34 import java.lang.module.ModuleDescriptor.Requires;
  35 import java.lang.module.ModuleFinder;
  36 import java.lang.module.ResolutionException;
  37 import java.lang.module.ResolvedModule;
  38 import java.lang.reflect.Layer;
  39 import java.util.HashSet;
  40 import java.util.List;
  41 import java.util.Optional;
  42 import java.util.Set;
  43 

  44 import org.testng.annotations.DataProvider;
  45 import org.testng.annotations.Test;
  46 import static org.testng.Assert.*;
  47 
  48 @Test
  49 public class ConfigurationTest {
  50 








  51 
  52     /**
  53      * Basic test of resolver
  54      *     m1 requires m2, m2 requires m3
  55      */
  56     public void testBasic() {
  57         ModuleDescriptor descriptor1
  58             = ModuleDescriptor.module("m1")
  59                 .requires("m2")
  60                 .build();
  61 
  62         ModuleDescriptor descriptor2
  63             = ModuleDescriptor.module("m2")
  64                 .requires("m3")
  65                 .build();
  66 
  67         ModuleDescriptor descriptor3
  68             = ModuleDescriptor.module("m3")
  69                 .build();
  70 
  71         ModuleFinder finder
  72             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
  73 
  74         Configuration cf = resolveRequires(finder, "m1");
  75 
  76         assertTrue(cf.modules().size() == 3);
  77 
  78         assertTrue(cf.findModule("m1").isPresent());
  79         assertTrue(cf.findModule("m2").isPresent());
  80         assertTrue(cf.findModule("m3").isPresent());
  81 
  82         assertTrue(cf.parents().size() == 1);
  83         assertTrue(cf.parents().get(0) == Configuration.empty());
  84 
  85         ResolvedModule m1 = cf.findModule("m1").get();
  86         ResolvedModule m2 = cf.findModule("m2").get();
  87         ResolvedModule m3 = cf.findModule("m3").get();
  88 
  89         // m1 reads m2
  90         assertTrue(m1.reads().size() == 1);
  91         assertTrue(m1.reads().contains(m2));
  92 
  93         // m2 reads m3
  94         assertTrue(m2.reads().size() == 1);
  95         assertTrue(m2.reads().contains(m3));
  96 
  97         // m3 reads nothing
  98         assertTrue(m3.reads().size() == 0);
  99 
 100         // toString
 101         assertTrue(cf.toString().contains("m1"));
 102         assertTrue(cf.toString().contains("m2"));
 103         assertTrue(cf.toString().contains("m3"));
 104     }
 105 
 106 
 107     /**
 108      * Basic test of "requires transitive":
 109      *     m1 requires m2, m2 requires transitive m3
 110      */
 111     public void testRequiresTransitive1() {
 112         // m1 requires m2, m2 requires transitive m3
 113         ModuleDescriptor descriptor1
 114             = ModuleDescriptor.module("m1")
 115                 .requires("m2")
 116                 .build();
 117 
 118         ModuleDescriptor descriptor2
 119             = ModuleDescriptor.module("m2")
 120                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m3")
 121                 .build();
 122 
 123         ModuleDescriptor descriptor3
 124             = ModuleDescriptor.module("m3")
 125                 .build();
 126 
 127         ModuleFinder finder
 128             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 129 
 130         Configuration cf = resolveRequires(finder, "m1");
 131 
 132         assertTrue(cf.modules().size() == 3);
 133 
 134         assertTrue(cf.findModule("m1").isPresent());
 135         assertTrue(cf.findModule("m2").isPresent());
 136         assertTrue(cf.findModule("m3").isPresent());
 137 
 138         assertTrue(cf.parents().size() == 1);
 139         assertTrue(cf.parents().get(0) == Configuration.empty());
 140 
 141         ResolvedModule m1 = cf.findModule("m1").get();
 142         ResolvedModule m2 = cf.findModule("m2").get();
 143         ResolvedModule m3 = cf.findModule("m3").get();
 144 
 145         // m1 reads m2 and m3
 146         assertTrue(m1.reads().size() == 2);
 147         assertTrue(m1.reads().contains(m2));
 148         assertTrue(m1.reads().contains(m3));
 149 
 150         // m2 reads m3
 151         assertTrue(m2.reads().size() == 1);
 152         assertTrue(m2.reads().contains(m3));
 153 
 154         // m3 reads nothing
 155         assertTrue(m3.reads().size() == 0);
 156     }
 157 
 158 
 159     /**
 160      * Basic test of "requires transitive" with configurations.
 161      *
 162      * The test consists of three configurations:
 163      * - Configuration cf1: m1, m2 requires transitive m1
 164      * - Configuration cf2: m3 requires m2
 165      */
 166     public void testRequiresTransitive2() {
 167 
 168         // cf1: m1 and m2, m2 requires transitive m1
 169 
 170         ModuleDescriptor descriptor1
 171             = ModuleDescriptor.module("m1")
 172                 .build();
 173 
 174         ModuleDescriptor descriptor2
 175             = ModuleDescriptor.module("m2")
 176                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 177                 .build();
 178 
 179         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 180 
 181         Configuration cf1 = resolveRequires(finder1, "m2");
 182 
 183         assertTrue(cf1.modules().size() == 2);
 184         assertTrue(cf1.findModule("m1").isPresent());
 185         assertTrue(cf1.findModule("m2").isPresent());
 186         assertTrue(cf1.parents().size() == 1);
 187         assertTrue(cf1.parents().get(0) == Configuration.empty());
 188 
 189         ResolvedModule m1 = cf1.findModule("m1").get();
 190         ResolvedModule m2 = cf1.findModule("m2").get();
 191 
 192         assertTrue(m1.reads().size() == 0);
 193         assertTrue(m2.reads().size() == 1);
 194         assertTrue(m2.reads().contains(m1));
 195 
 196 
 197         // cf2: m3, m3 requires m2
 198 
 199         ModuleDescriptor descriptor3
 200             = ModuleDescriptor.module("m3")
 201                 .requires("m2")
 202                 .build();
 203 
 204         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 205 
 206         Configuration cf2 = resolveRequires(cf1, finder2, "m3");
 207 
 208         assertTrue(cf2.modules().size() == 1);
 209         assertTrue(cf2.findModule("m1").isPresent());  // in parent
 210         assertTrue(cf2.findModule("m2").isPresent());  // in parent
 211         assertTrue(cf2.findModule("m3").isPresent());
 212         assertTrue(cf2.parents().size() == 1);
 213         assertTrue(cf2.parents().get(0) == cf1);
 214 
 215         ResolvedModule m3 = cf2.findModule("m3").get();
 216         assertTrue(m3.configuration() == cf2);
 217         assertTrue(m3.reads().size() == 2);
 218         assertTrue(m3.reads().contains(m1));
 219         assertTrue(m3.reads().contains(m2));
 220     }
 221 
 222 
 223     /**
 224      * Basic test of "requires transitive" with configurations.
 225      *
 226      * The test consists of three configurations:
 227      * - Configuration cf1: m1
 228      * - Configuration cf2: m2 requires transitive m1, m3 requires m2
 229      */
 230     public void testRequiresTransitive3() {
 231 
 232         // cf1: m1
 233 
 234         ModuleDescriptor descriptor1
 235             = ModuleDescriptor.module("m1")
 236                 .build();
 237 
 238         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 239 
 240         Configuration cf1 = resolveRequires(finder1, "m1");
 241 
 242         assertTrue(cf1.modules().size() == 1);
 243         assertTrue(cf1.findModule("m1").isPresent());
 244         assertTrue(cf1.parents().size() == 1);
 245         assertTrue(cf1.parents().get(0) == Configuration.empty());
 246 
 247         ResolvedModule m1 = cf1.findModule("m1").get();
 248         assertTrue(m1.reads().size() == 0);
 249 
 250 
 251         // cf2: m2, m3: m2 requires transitive m1, m3 requires m2
 252 
 253         ModuleDescriptor descriptor2
 254             = ModuleDescriptor.module("m2")
 255                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 256                 .build();
 257 
 258         ModuleDescriptor descriptor3
 259             = ModuleDescriptor.module("m3")
 260                 .requires("m2")
 261                 .build();
 262 
 263         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3);
 264 
 265         Configuration cf2 = resolveRequires(cf1, finder2, "m3");
 266 
 267         assertTrue(cf2.modules().size() == 2);
 268         assertTrue(cf2.findModule("m1").isPresent());   // in parent
 269         assertTrue(cf2.findModule("m2").isPresent());
 270         assertTrue(cf2.findModule("m3").isPresent());
 271         assertTrue(cf2.parents().size() == 1);
 272         assertTrue(cf2.parents().get(0) == cf1);
 273 
 274         ResolvedModule m2 = cf2.findModule("m2").get();
 275         ResolvedModule m3 = cf2.findModule("m3").get();
 276 
 277         assertTrue(m2.configuration() == cf2);
 278         assertTrue(m2.reads().size() == 1);
 279         assertTrue(m2.reads().contains(m1));
 280 
 281         assertTrue(m3.configuration() == cf2);
 282         assertTrue(m3.reads().size() == 2);
 283         assertTrue(m3.reads().contains(m1));
 284         assertTrue(m3.reads().contains(m2));
 285     }
 286 
 287 
 288     /**
 289      * Basic test of "requires transitive" with configurations.
 290      *
 291      * The test consists of three configurations:
 292      * - Configuration cf1: m1
 293      * - Configuration cf2: m2 requires transitive m1
 294      * - Configuraiton cf3: m3 requires m2
 295      */
 296     public void testRequiresTransitive4() {
 297 
 298         // cf1: m1
 299 
 300         ModuleDescriptor descriptor1
 301             = ModuleDescriptor.module("m1")
 302                 .build();
 303 
 304         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 305 
 306         Configuration cf1 = resolveRequires(finder1, "m1");
 307 
 308         assertTrue(cf1.modules().size() == 1);
 309         assertTrue(cf1.findModule("m1").isPresent());
 310         assertTrue(cf1.parents().size() == 1);
 311         assertTrue(cf1.parents().get(0) == Configuration.empty());
 312 
 313         ResolvedModule m1 = cf1.findModule("m1").get();
 314         assertTrue(m1.reads().size() == 0);
 315 
 316 
 317         // cf2: m2 requires transitive m1
 318 
 319         ModuleDescriptor descriptor2
 320             = ModuleDescriptor.module("m2")
 321                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 322                 .build();
 323 
 324         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
 325 
 326         Configuration cf2 = resolveRequires(cf1, finder2, "m2");
 327 
 328         assertTrue(cf2.modules().size() == 1);
 329         assertTrue(cf2.findModule("m1").isPresent());  // in parent
 330         assertTrue(cf2.findModule("m2").isPresent());
 331         assertTrue(cf2.parents().size() == 1);
 332         assertTrue(cf2.parents().get(0) == cf1);
 333 
 334         ResolvedModule m2 = cf2.findModule("m2").get();
 335 
 336         assertTrue(m2.configuration() == cf2);
 337         assertTrue(m2.reads().size() == 1);
 338         assertTrue(m2.reads().contains(m1));
 339 
 340 
 341         // cf3: m3 requires m2
 342 
 343         ModuleDescriptor descriptor3
 344             = ModuleDescriptor.module("m3")
 345                 .requires("m2")
 346                 .build();
 347 
 348         ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3);
 349 
 350         Configuration cf3 = resolveRequires(cf2, finder3, "m3");
 351 
 352         assertTrue(cf3.modules().size() == 1);
 353         assertTrue(cf3.findModule("m1").isPresent());  // in parent
 354         assertTrue(cf3.findModule("m2").isPresent());  // in parent
 355         assertTrue(cf3.findModule("m3").isPresent());
 356         assertTrue(cf3.parents().size() == 1);
 357         assertTrue(cf3.parents().get(0) == cf2);
 358 
 359         ResolvedModule m3 = cf3.findModule("m3").get();
 360 
 361         assertTrue(m3.configuration() == cf3);
 362         assertTrue(m3.reads().size() == 2);
 363         assertTrue(m3.reads().contains(m1));
 364         assertTrue(m3.reads().contains(m2));
 365     }
 366 
 367 
 368     /**
 369      * Basic test of "requires transitive" with configurations.
 370      *
 371      * The test consists of two configurations:
 372      * - Configuration cf1: m1, m2 requires transitive m1
 373      * - Configuration cf2: m3 requires transitive m2, m4 requires m3
 374      */
 375     public void testRequiresTransitive5() {
 376 
 377         // cf1: m1, m2 requires transitive m1
 378 
 379         ModuleDescriptor descriptor1
 380             = ModuleDescriptor.module("m1")
 381                 .build();
 382 
 383         ModuleDescriptor descriptor2
 384             = ModuleDescriptor.module("m2")
 385                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 386                 .build();
 387 
 388         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 389 
 390         Configuration cf1 = resolveRequires(finder1, "m2");
 391 
 392         assertTrue(cf1.modules().size() == 2);
 393         assertTrue(cf1.findModule("m1").isPresent());
 394         assertTrue(cf1.findModule("m2").isPresent());
 395         assertTrue(cf1.parents().size() == 1);
 396         assertTrue(cf1.parents().get(0) == Configuration.empty());
 397 
 398         ResolvedModule m1 = cf1.findModule("m1").get();
 399         ResolvedModule m2 = cf1.findModule("m2").get();
 400 
 401         assertTrue(m1.configuration() == cf1);
 402         assertTrue(m1.reads().size() == 0);
 403 
 404         assertTrue(m2.configuration() == cf1);
 405         assertTrue(m2.reads().size() == 1);
 406         assertTrue(m2.reads().contains(m1));
 407 
 408 
 409         // cf2: m3 requires transitive m2, m4 requires m3
 410 
 411         ModuleDescriptor descriptor3
 412             = ModuleDescriptor.module("m3")
 413                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m2")
 414                 .build();
 415 
 416         ModuleDescriptor descriptor4
 417             = ModuleDescriptor.module("m4")
 418                 .requires("m3")
 419                 .build();
 420 
 421 
 422         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 423 
 424         Configuration cf2 = resolveRequires(cf1, finder2, "m3", "m4");
 425 
 426         assertTrue(cf2.modules().size() == 2);
 427         assertTrue(cf2.findModule("m1").isPresent());   // in parent
 428         assertTrue(cf2.findModule("m2").isPresent());   // in parent
 429         assertTrue(cf2.findModule("m3").isPresent());
 430         assertTrue(cf2.findModule("m4").isPresent());
 431         assertTrue(cf2.parents().size() == 1);
 432         assertTrue(cf2.parents().get(0) == cf1);
 433 
 434         ResolvedModule m3 = cf2.findModule("m3").get();
 435         ResolvedModule m4 = cf2.findModule("m4").get();
 436 
 437         assertTrue(m3.configuration() == cf2);
 438         assertTrue(m3.reads().size() == 2);
 439         assertTrue(m3.reads().contains(m1));
 440         assertTrue(m3.reads().contains(m2));
 441 
 442         assertTrue(m4.configuration() == cf2);
 443         assertTrue(m4.reads().size() == 3);
 444         assertTrue(m4.reads().contains(m1));
 445         assertTrue(m4.reads().contains(m2));
 446         assertTrue(m4.reads().contains(m3));
 447     }
 448 
 449 
 450     /**
 451      * Basic test of "requires transitive" with configurations.
 452      *
 453      * The test consists of three configurations:
 454      * - Configuration cf1: m1, m2 requires transitive m1
 455      * - Configuration cf2: m1, m3 requires transitive m1
 456      * - Configuration cf3(cf1,cf2): m4 requires m2, m3
 457      */
 458     public void testRequiresTransitive6() {
 459         ModuleDescriptor descriptor1
 460             = ModuleDescriptor.module("m1")
 461                 .build();
 462 
 463         ModuleDescriptor descriptor2
 464             = ModuleDescriptor.module("m2")
 465                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 466                 .build();
 467 
 468         ModuleDescriptor descriptor3
 469             = ModuleDescriptor.module("m3")
 470                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 471                 .build();
 472 
 473         ModuleDescriptor descriptor4
 474             = ModuleDescriptor.module("m4")
 475                 .requires("m2")
 476                 .requires("m3")
 477                 .build();
 478 
 479         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 480         Configuration cf1 = resolveRequires(finder1, "m2");
 481         assertTrue(cf1.modules().size() == 2);
 482         assertTrue(cf1.findModule("m1").isPresent());
 483         assertTrue(cf1.findModule("m2").isPresent());
 484         assertTrue(cf1.parents().size() == 1);
 485         assertTrue(cf1.parents().get(0) == Configuration.empty());
 486 
 487         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
 488         Configuration cf2 = resolveRequires(finder2, "m3");
 489         assertTrue(cf2.modules().size() == 2);
 490         assertTrue(cf2.findModule("m3").isPresent());
 491         assertTrue(cf2.findModule("m1").isPresent());
 492         assertTrue(cf2.parents().size() == 1);
 493         assertTrue(cf2.parents().get(0) == Configuration.empty());
 494 
 495         ModuleFinder finder3 = ModuleUtils.finderOf(descriptor4);
 496         Configuration cf3 = Configuration.resolveRequires(finder3,
 497                 List.of(cf1, cf2),
 498                 ModuleFinder.of(),
 499                 Set.of("m4"));
 500         assertTrue(cf3.modules().size() == 1);
 501         assertTrue(cf3.findModule("m4").isPresent());
 502 
 503         ResolvedModule m1_l = cf1.findModule("m1").get();
 504         ResolvedModule m1_r = cf2.findModule("m1").get();
 505         ResolvedModule m2 = cf1.findModule("m2").get();
 506         ResolvedModule m3 = cf2.findModule("m3").get();
 507         ResolvedModule m4 = cf3.findModule("m4").get();
 508         assertTrue(m4.configuration() == cf3);
 509 
 510         assertTrue(m4.reads().size() == 4);
 511         assertTrue(m4.reads().contains(m1_l));
 512         assertTrue(m4.reads().contains(m1_r));
 513         assertTrue(m4.reads().contains(m2));
 514         assertTrue(m4.reads().contains(m3));
 515     }
 516 
 517 
 518     /**
 519      * Basic test of "requires static":
 520      *     m1 requires static m2
 521      *     m2 is not observable
 522      *     resolve m1
 523      */
 524     public void testRequiresStatic1() {
 525         ModuleDescriptor descriptor1
 526             = ModuleDescriptor.module("m1")
 527                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
 528                 .build();
 529 
 530         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 531 
 532         Configuration cf = resolveRequires(finder, "m1");
 533 
 534         assertTrue(cf.modules().size() == 1);
 535 
 536         ResolvedModule m1 = cf.findModule("m1").get();
 537         assertTrue(m1.reads().size() == 0);
 538     }
 539 
 540 
 541     /**
 542      * Basic test of "requires static":
 543      *     m1 requires static m2
 544      *     m2
 545      *     resolve m1
 546      */
 547     public void testRequiresStatic2() {
 548         ModuleDescriptor descriptor1
 549             = ModuleDescriptor.module("m1")
 550                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
 551                 .build();
 552 
 553         ModuleDescriptor descriptor2
 554             = ModuleDescriptor.module("m2")
 555                 .build();
 556 
 557         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 558 
 559         Configuration cf = resolveRequires(finder, "m1");
 560 
 561         assertTrue(cf.modules().size() == 1);
 562 
 563         ResolvedModule m1 = cf.findModule("m1").get();
 564         assertTrue(m1.reads().size() == 0);
 565     }
 566 
 567 
 568     /**
 569      * Basic test of "requires static":
 570      *     m1 requires static m2
 571      *     m2
 572      *     resolve m1, m2
 573      */
 574     public void testRequiresStatic3() {
 575         ModuleDescriptor descriptor1
 576             = ModuleDescriptor.module("m1")
 577                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
 578                 .build();
 579 
 580         ModuleDescriptor descriptor2
 581             = ModuleDescriptor.module("m2")
 582                 .build();
 583 
 584         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 585 
 586         Configuration cf = resolveRequires(finder, "m1", "m2");
 587 
 588         assertTrue(cf.modules().size() == 2);
 589 
 590         ResolvedModule m1 = cf.findModule("m1").get();
 591         ResolvedModule m2 = cf.findModule("m2").get();
 592 
 593         assertTrue(m1.reads().size() == 1);
 594         assertTrue(m1.reads().contains(m2));
 595 
 596         assertTrue(m2.reads().size() == 0);
 597     }
 598 
 599 
 600     /**
 601      * Basic test of "requires static":
 602      *     m1 requires m2, m3
 603      *     m2 requires static m2
 604      *     m3
 605      */
 606     public void testRequiresStatic4() {
 607         ModuleDescriptor descriptor1
 608             = ModuleDescriptor.module("m1")
 609                 .requires("m2")
 610                 .requires("m3")
 611                 .build();
 612 
 613         ModuleDescriptor descriptor2
 614             = ModuleDescriptor.module("m2")
 615                 .requires(Set.of(Requires.Modifier.STATIC), "m3")
 616                 .build();
 617 
 618         ModuleDescriptor descriptor3
 619             = ModuleDescriptor.module("m3")
 620                 .build();
 621 
 622         ModuleFinder finder
 623                 = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 624 
 625         Configuration cf = resolveRequires(finder, "m1");
 626 
 627         assertTrue(cf.modules().size() == 3);
 628 
 629         ResolvedModule m1 = cf.findModule("m1").get();
 630         ResolvedModule m2 = cf.findModule("m2").get();
 631         ResolvedModule m3 = cf.findModule("m3").get();
 632 
 633         assertTrue(m1.reads().size() == 2);
 634         assertTrue(m1.reads().contains(m2));
 635         assertTrue(m1.reads().contains(m3));
 636 
 637         assertTrue(m2.reads().size() == 1);
 638         assertTrue(m2.reads().contains(m3));
 639 
 640         assertTrue(m3.reads().size() == 0);
 641     }
 642 
 643 
 644     /**
 645      * Basic test of "requires static":
 646      * The test consists of three configurations:
 647      * - Configuration cf1: m1, m2
 648      * - Configuration cf2: m3 requires m1, requires static m2
 649      */
 650     public void testRequiresStatic5() {
 651         ModuleDescriptor descriptor1
 652             = ModuleDescriptor.module("m1")
 653                 .build();
 654 
 655         ModuleDescriptor descriptor2
 656             = ModuleDescriptor.module("m2")
 657                 .build();
 658 
 659         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 660 
 661         Configuration cf1 = resolveRequires(finder1, "m1", "m2");
 662 
 663         assertTrue(cf1.modules().size() == 2);
 664         assertTrue(cf1.findModule("m1").isPresent());
 665         assertTrue(cf1.findModule("m2").isPresent());
 666 
 667         ModuleDescriptor descriptor3
 668             = ModuleDescriptor.module("m3")
 669                 .requires("m1")
 670                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
 671                 .build();
 672 
 673         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 674 
 675         Configuration cf2 = resolveRequires(cf1, finder2, "m3");
 676 
 677         assertTrue(cf2.modules().size() == 1);
 678         assertTrue(cf2.findModule("m3").isPresent());
 679 
 680         ResolvedModule m1 = cf1.findModule("m1").get();
 681         ResolvedModule m2 = cf1.findModule("m2").get();
 682         ResolvedModule m3 = cf2.findModule("m3").get();
 683 
 684         assertTrue(m3.reads().size() == 2);
 685         assertTrue(m3.reads().contains(m1));
 686         assertTrue(m3.reads().contains(m2));
 687     }
 688 
 689 
 690     /**
 691      * Basic test of "requires static":
 692      * The test consists of three configurations:
 693      * - Configuration cf1: m1
 694      * - Configuration cf2: m3 requires m1, requires static m2
 695      */
 696     public void testRequiresStatic6() {
 697         ModuleDescriptor descriptor1
 698             = ModuleDescriptor.module("m1")
 699                 .build();
 700 
 701         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 702 
 703         Configuration cf1 = resolveRequires(finder1, "m1");
 704 
 705         assertTrue(cf1.modules().size() == 1);
 706         assertTrue(cf1.findModule("m1").isPresent());
 707 
 708         ModuleDescriptor descriptor3
 709             = ModuleDescriptor.module("m3")
 710                 .requires("m1")
 711                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
 712                 .build();
 713 
 714         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 715 
 716         Configuration cf2 = resolveRequires(cf1, finder2, "m3");
 717 
 718         assertTrue(cf2.modules().size() == 1);
 719         assertTrue(cf2.findModule("m3").isPresent());
 720 
 721         ResolvedModule m1 = cf1.findModule("m1").get();
 722         ResolvedModule m3 = cf2.findModule("m3").get();
 723 
 724         assertTrue(m3.reads().size() == 1);
 725         assertTrue(m3.reads().contains(m1));
 726     }
 727 
 728 
 729     /**
 730      * Basic test of "requires static":
 731      *     (m1 not observable)
 732      *     m2 requires transitive static m1
 733      *     m3 requires m2
 734      */
 735     public void testRequiresStatic7() {
 736         ModuleDescriptor descriptor1 = null;  // not observable
 737 
 738         ModuleDescriptor descriptor2
 739             = ModuleDescriptor.module("m2")
 740                 .requires(Set.of(Requires.Modifier.TRANSITIVE,
 741                                 Requires.Modifier.STATIC),
 742                          "m1")
 743                 .build();
 744 
 745         ModuleDescriptor descriptor3
 746                 = ModuleDescriptor.module("m3")
 747                 .requires("m2")
 748                 .build();
 749 
 750         ModuleFinder finder = ModuleUtils.finderOf(descriptor2, descriptor3);
 751 
 752         Configuration cf = resolveRequires(finder, "m3");
 753 
 754         assertTrue(cf.modules().size() == 2);
 755         assertTrue(cf.findModule("m2").isPresent());
 756         assertTrue(cf.findModule("m3").isPresent());
 757         ResolvedModule m2 = cf.findModule("m2").get();
 758         ResolvedModule m3 = cf.findModule("m3").get();
 759         assertTrue(m2.reads().isEmpty());
 760         assertTrue(m3.reads().size() == 1);
 761         assertTrue(m3.reads().contains(m2));
 762     }
 763 
 764 
 765     /**
 766      * Basic test of "requires static":
 767      * - Configuration cf1: m2 requires transitive static m1
 768      * - Configuration cf2: m3 requires m2
 769      */
 770     public void testRequiresStatic8() {
 771         ModuleDescriptor descriptor1 = null;  // not observable
 772 
 773         ModuleDescriptor descriptor2
 774             = ModuleDescriptor.module("m2")
 775                 .requires(Set.of(Requires.Modifier.TRANSITIVE,
 776                                 Requires.Modifier.STATIC),
 777                         "m1")
 778                 .build();
 779 
 780         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2);
 781 
 782         Configuration cf1 = resolveRequires(finder1, "m2");
 783 
 784         assertTrue(cf1.modules().size() == 1);
 785         assertTrue(cf1.findModule("m2").isPresent());
 786         ResolvedModule m2 = cf1.findModule("m2").get();
 787         assertTrue(m2.reads().isEmpty());
 788 
 789         ModuleDescriptor descriptor3
 790             = ModuleDescriptor.module("m3")
 791                 .requires("m2")
 792                 .build();
 793 
 794         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 795 
 796         Configuration cf2 = resolveRequires(cf1, finder2, "m3");
 797 
 798         assertTrue(cf2.modules().size() == 1);
 799         assertTrue(cf2.findModule("m3").isPresent());
 800         ResolvedModule m3 = cf2.findModule("m3").get();
 801         assertTrue(m3.reads().size() == 1);
 802         assertTrue(m3.reads().contains(m2));
 803     }
 804 
 805 
 806     /**
 807      * Basic test of binding services
 808      *     m1 uses p.S
 809      *     m2 provides p.S
 810      */
 811     public void testServiceBinding1() {
 812 
 813         ModuleDescriptor descriptor1
 814             = ModuleDescriptor.module("m1")
 815                 .exports("p")
 816                 .uses("p.S")
 817                 .build();
 818 
 819         ModuleDescriptor descriptor2
 820             = ModuleDescriptor.module("m2")
 821                 .requires("m1")
 822                 .contains("q")
 823                 .provides("p.S", "q.T")
 824                 .build();
 825 
 826         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 827 
 828         Configuration cf = resolveRequiresAndUses(finder, "m1");
 829 
 830         assertTrue(cf.modules().size() == 2);
 831         assertTrue(cf.findModule("m1").isPresent());
 832         assertTrue(cf.findModule("m2").isPresent());
 833         assertTrue(cf.parents().size() == 1);
 834         assertTrue(cf.parents().get(0) == Configuration.empty());
 835 
 836         ResolvedModule m1 = cf.findModule("m1").get();
 837         ResolvedModule m2 = cf.findModule("m2").get();
 838 
 839         assertTrue(m1.configuration() == cf);
 840         assertTrue(m1.reads().size() == 0);
 841 
 842         assertTrue(m2.configuration() == cf);
 843         assertTrue(m2.reads().size() == 1);
 844         assertTrue(m2.reads().contains(m1));
 845     }
 846 
 847 
 848     /**
 849      * Basic test of binding services
 850      *     m1 uses p.S1
 851      *     m2 provides p.S1, m2 uses p.S2
 852      *     m3 provides p.S2
 853      */
 854     public void testServiceBinding2() {
 855 
 856         ModuleDescriptor descriptor1
 857             = ModuleDescriptor.module("m1")
 858                 .exports("p")
 859                 .uses("p.S1")
 860                 .build();
 861 
 862         ModuleDescriptor descriptor2
 863             = ModuleDescriptor.module("m2")
 864                 .requires("m1")
 865                 .uses("p.S2")
 866                 .contains("q")
 867                 .provides("p.S1", "q.Service1Impl")
 868                 .build();
 869 
 870         ModuleDescriptor descriptor3
 871             = ModuleDescriptor.module("m3")
 872                 .requires("m1")
 873                 .contains("q")
 874                 .provides("p.S2", "q.Service2Impl")
 875                 .build();
 876 
 877         ModuleFinder finder
 878             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 879 
 880         Configuration cf = resolveRequiresAndUses(finder, "m1");
 881 
 882         assertTrue(cf.modules().size() == 3);
 883         assertTrue(cf.findModule("m1").isPresent());
 884         assertTrue(cf.findModule("m2").isPresent());
 885         assertTrue(cf.findModule("m3").isPresent());
 886         assertTrue(cf.parents().size() == 1);
 887         assertTrue(cf.parents().get(0) == Configuration.empty());
 888 
 889         ResolvedModule m1 = cf.findModule("m1").get();
 890         ResolvedModule m2 = cf.findModule("m2").get();
 891         ResolvedModule m3 = cf.findModule("m3").get();
 892 
 893         assertTrue(m1.configuration() == cf);
 894         assertTrue(m1.reads().size() == 0);
 895 
 896         assertTrue(m2.configuration() == cf);
 897         assertTrue(m2.reads().size() == 1);
 898         assertTrue(m2.reads().contains(m1));
 899 
 900         assertTrue(m3.configuration() == cf);
 901         assertTrue(m3.reads().size() == 1);
 902         assertTrue(m3.reads().contains(m1));
 903     }
 904 
 905 
 906     /**
 907      * Basic test of binding services with configurations.
 908      *
 909      * The test consists of two configurations:
 910      * - Configuration cf1: m1 uses p.S
 911      * - Configuration cf2: m2 provides p.S
 912      */
 913     public void testServiceBindingWithConfigurations1() {
 914 
 915         ModuleDescriptor descriptor1
 916             = ModuleDescriptor.module("m1")
 917                 .exports("p")
 918                 .uses("p.S")
 919                 .build();
 920 
 921         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 922 
 923         Configuration cf1 = resolveRequires(finder1, "m1");
 924 
 925         assertTrue(cf1.modules().size() == 1);
 926         assertTrue(cf1.findModule("m1").isPresent());
 927 
 928         ModuleDescriptor descriptor2
 929             = ModuleDescriptor.module("m2")
 930                 .requires("m1")
 931                 .contains("q")
 932                 .provides("p.S", "q.T")
 933                 .build();
 934 
 935         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
 936 
 937         Configuration cf2 = resolveRequiresAndUses(cf1, finder2); // no roots
 938 
 939         assertTrue(cf2.parents().size() == 1);
 940         assertTrue(cf2.parents().get(0) == cf1);
 941 
 942         assertTrue(cf2.modules().size() == 1);
 943         assertTrue(cf2.findModule("m2").isPresent());
 944 
 945         ResolvedModule m1 = cf1.findModule("m1").get();
 946         ResolvedModule m2 = cf2.findModule("m2").get();
 947 
 948         assertTrue(m2.reads().size() == 1);
 949         assertTrue(m2.reads().contains(m1));
 950     }
 951 
 952 
 953     /**
 954      * Basic test of binding services with configurations.
 955      *
 956      * The test consists of two configurations:
 957      * - Configuration cf1: m1 uses p.S && provides p.S,
 958      *                      m2 provides p.S
 959      * - Configuration cf2: m3 provides p.S
 960      *                      m4 provides p.S
 961      */
 962     public void testServiceBindingWithConfigurations2() {
 963 
 964         ModuleDescriptor descriptor1
 965             = ModuleDescriptor.module("m1")
 966                 .exports("p")
 967                 .uses("p.S")
 968                 .contains("p1")
 969                 .provides("p.S", "p1.ServiceImpl")
 970                 .build();
 971 
 972         ModuleDescriptor descriptor2
 973             = ModuleDescriptor.module("m2")
 974                 .requires("m1")
 975                 .contains("p2")
 976                 .provides("p.S", "p2.ServiceImpl")
 977                 .build();
 978 
 979         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 980 
 981         Configuration cf1 = resolveRequiresAndUses(finder1, "m1");
 982 
 983         assertTrue(cf1.modules().size() == 2);
 984         assertTrue(cf1.findModule("m1").isPresent());
 985         assertTrue(cf1.findModule("m2").isPresent());
 986 
 987 
 988         ModuleDescriptor descriptor3
 989             = ModuleDescriptor.module("m3")
 990                 .requires("m1")
 991                 .contains("p3")
 992                 .provides("p.S", "p3.ServiceImpl")
 993                 .build();
 994 
 995         ModuleDescriptor descriptor4
 996             = ModuleDescriptor.module("m4")
 997                 .requires("m1")
 998                 .contains("p4")
 999                 .provides("p.S", "p4.ServiceImpl")
1000                 .build();
1001 
1002         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
1003 
1004         Configuration cf2 = resolveRequiresAndUses(cf1, finder2); // no roots
1005 
1006         assertTrue(cf2.parents().size() == 1);
1007         assertTrue(cf2.parents().get(0) == cf1);
1008 
1009         assertTrue(cf2.modules().size() == 2);
1010         assertTrue(cf2.findModule("m3").isPresent());
1011         assertTrue(cf2.findModule("m4").isPresent());
1012 
1013         ResolvedModule m1 = cf2.findModule("m1").get();  // should find in parent
1014         ResolvedModule m2 = cf2.findModule("m2").get();
1015         ResolvedModule m3 = cf2.findModule("m3").get();
1016         ResolvedModule m4 = cf2.findModule("m4").get();
1017 
1018         assertTrue(m1.reads().size() == 0);
1019 
1020         assertTrue(m2.reads().size() == 1);
1021         assertTrue(m2.reads().contains(m1));
1022 
1023         assertTrue(m3.reads().size() == 1);
1024         assertTrue(m3.reads().contains(m1));
1025 
1026         assertTrue(m4.reads().size() == 1);
1027         assertTrue(m4.reads().contains(m1));
1028     }
1029 
1030 
1031     /**
1032      * Basic test of binding services with configurations.
1033      *
1034      * Configuration cf1: p@1.0 provides p.S
1035      * Test configuration cf2: m1 uses p.S, p@2.0 provides p.S
1036      * Test configuration cf2: m1 uses p.S
1037      */
1038     public void testServiceBindingWithConfigurations3() {
1039 
1040         ModuleDescriptor service
1041             = ModuleDescriptor.module("s")
1042                 .exports("p")
1043                 .build();
1044 
1045         ModuleDescriptor provider_v1
1046             = ModuleDescriptor.module("p")
1047                 .version("1.0")
1048                 .requires("s")
1049                 .contains("q")
1050                 .provides("p.S", "q.T")
1051                 .build();
1052 
1053         ModuleFinder finder1 = ModuleUtils.finderOf(service, provider_v1);
1054 
1055         Configuration cf1 = resolveRequires(finder1, "p");
1056 
1057         assertTrue(cf1.modules().size() == 2);
1058         assertTrue(cf1.findModule("s").isPresent());
1059         assertTrue(cf1.findModule("p").isPresent());
1060 
1061         // p@1.0 in cf1
1062         ResolvedModule p = cf1.findModule("p").get();
1063         assertEquals(p.reference().descriptor(), provider_v1);
1064 
1065 
1066         ModuleDescriptor descriptor1
1067             = ModuleDescriptor.module("m1")
1068                 .requires("s")
1069                 .uses("p.S")
1070                 .build();
1071 
1072         ModuleDescriptor provider_v2
1073             = ModuleDescriptor.module("p")
1074                 .version("2.0")
1075                 .requires("s")
1076                 .contains("q")
1077                 .provides("p.S", "q.T")
1078                 .build();
1079 
1080         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, provider_v2);
1081 
1082 
1083         // finder2 is the before ModuleFinder and so p@2.0 should be located
1084 
1085         Configuration cf2 = resolveRequiresAndUses(cf1, finder2, "m1");
1086 
1087         assertTrue(cf2.parents().size() == 1);
1088         assertTrue(cf2.parents().get(0) == cf1);
1089         assertTrue(cf2.modules().size() == 2);
1090 
1091         // p should be found in cf2
1092         p = cf2.findModule("p").get();
1093         assertTrue(p.configuration() == cf2);
1094         assertEquals(p.reference().descriptor(), provider_v2);
1095 
1096 
1097         // finder2 is the after ModuleFinder and so p@2.0 should not be located
1098         // as module p is in parent configuration.
1099 
1100         cf2 = resolveRequiresAndUses(cf1, ModuleFinder.of(), finder2, "m1");
1101 
1102         assertTrue(cf2.parents().size() == 1);
1103         assertTrue(cf2.parents().get(0) == cf1);
1104         assertTrue(cf2.modules().size() == 1);
1105 
1106         // p should be found in cf1
1107         p = cf2.findModule("p").get();
1108         assertTrue(p.configuration() == cf1);
1109         assertEquals(p.reference().descriptor(), provider_v1);
1110     }
1111 
1112 
1113     /**
1114      * Basic test with two module finders.
1115      *
1116      * Module m2 can be found by both the before and after finders.
1117      */
1118     public void testWithTwoFinders1() {
1119 
1120         ModuleDescriptor descriptor1
1121             = ModuleDescriptor.module("m1")
1122                 .requires("m2")
1123                 .build();
1124 
1125         ModuleDescriptor descriptor2_v1
1126             = ModuleDescriptor.module("m2")
1127                 .version("1.0")
1128                 .build();
1129 
1130         ModuleDescriptor descriptor2_v2
1131             = ModuleDescriptor.module("m2")
1132                 .version("2.0")
1133                 .build();
1134 
1135         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2_v1);
1136         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor2_v2);
1137 
1138         Configuration cf = resolveRequires(finder1, finder2, "m1");
1139 
1140         assertTrue(cf.modules().size() == 2);
1141         assertTrue(cf.findModule("m1").isPresent());
1142         assertTrue(cf.findModule("m2").isPresent());
1143 
1144         ResolvedModule m1 = cf.findModule("m1").get();
1145         ResolvedModule m2 = cf.findModule("m2").get();
1146 
1147         assertEquals(m1.reference().descriptor(), descriptor1);
1148         assertEquals(m2.reference().descriptor(), descriptor2_v1);
1149     }
1150 
1151 
1152     /**
1153      * Basic test with two modules finders and service binding.
1154      *
1155      * The before and after ModuleFinders both locate a service provider module
1156      * named "m2" that provide implementations of the same service type.
1157      */
1158     public void testWithTwoFinders2() {
1159 
1160         ModuleDescriptor descriptor1
1161             = ModuleDescriptor.module("m1")
1162                 .exports("p")
1163                 .uses("p.S")
1164                 .build();
1165 
1166         ModuleDescriptor descriptor2_v1
1167             = ModuleDescriptor.module("m2")
1168                 .requires("m1")
1169                 .contains("q")
1170                 .provides("p.S", "q.T")
1171                 .build();
1172 
1173         ModuleDescriptor descriptor2_v2
1174             = ModuleDescriptor.module("m2")
1175                 .requires("m1")
1176                 .contains("q")
1177                 .provides("p.S", "q.T")
1178                 .build();
1179 
1180         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2_v1);
1181         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2_v2);
1182 
1183         Configuration cf = resolveRequiresAndUses(finder1, finder2, "m1");
1184 
1185         assertTrue(cf.modules().size() == 2);
1186         assertTrue(cf.findModule("m1").isPresent());
1187         assertTrue(cf.findModule("m2").isPresent());
1188 
1189         ResolvedModule m1 = cf.findModule("m1").get();
1190         ResolvedModule m2 = cf.findModule("m2").get();
1191 
1192         assertEquals(m1.reference().descriptor(), descriptor1);
1193         assertEquals(m2.reference().descriptor(), descriptor2_v1);
1194     }
1195 
1196 
1197     /**
1198      * Basic test for resolving a module that is located in the parent
1199      * configuration.
1200      */
1201     public void testResolvedInParent1() {
1202 
1203         ModuleDescriptor descriptor1
1204             = ModuleDescriptor.module("m1")
1205                 .build();
1206 
1207         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1208 
1209         Configuration cf1 = resolveRequires(finder, "m1");
1210 
1211         assertTrue(cf1.modules().size() == 1);
1212         assertTrue(cf1.findModule("m1").isPresent());
1213 
1214         Configuration cf2 = resolveRequires(cf1, finder, "m1");
1215 
1216         assertTrue(cf2.modules().size() == 1);
1217     }
1218 
1219 
1220     /**
1221      * Basic test for resolving a module that has a dependency on a module
1222      * in the parent configuration.
1223      */
1224     public void testResolvedInParent2() {
1225 
1226         ModuleDescriptor descriptor1
1227             = ModuleDescriptor.module("m1")
1228                 .build();
1229 
1230         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
1231 
1232         Configuration cf1 = resolveRequires(finder1, "m1");
1233 
1234         assertTrue(cf1.modules().size() == 1);
1235         assertTrue(cf1.findModule("m1").isPresent());
1236 
1237 
1238         ModuleDescriptor descriptor2
1239             = ModuleDescriptor.module("m2")
1240                 .requires("m1")
1241                 .build();
1242 
1243         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
1244 
1245         Configuration cf2 = resolveRequires(cf1, ModuleFinder.of(), finder2, "m2");
1246 
1247         assertTrue(cf2.modules().size() == 1);
1248         assertTrue(cf2.findModule("m2").isPresent());
1249 
1250         ResolvedModule m1 = cf2.findModule("m1").get();   // find in parent
1251         ResolvedModule m2 = cf2.findModule("m2").get();
1252 
1253         assertTrue(m1.reads().size() == 0);
1254         assertTrue(m2.reads().size() == 1);
1255         assertTrue(m2.reads().contains(m1));
1256     }
1257 
1258 
1259     /**
1260      * Basic test of resolving a module that depends on modules in two parent
1261      * configurations.
1262      *
1263      * The test consists of three configurations:
1264      * - Configuration cf1: m1
1265      * - Configuration cf2: m2
1266      * - Configuration cf3(cf1,cf2): m3 requires m1, m2
1267      */
1268     public void testResolvedInMultipleParents1() {
1269 
1270         // Configuration cf1: m1
1271         ModuleDescriptor descriptor1 = ModuleDescriptor.module("m1").build();
1272         Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
1273         assertEquals(cf1.parents(), List.of(Configuration.empty()));
1274         assertTrue(cf1.findModule("m1").isPresent());
1275         ResolvedModule m1 = cf1.findModule("m1").get();
1276         assertTrue(m1.configuration() == cf1);
1277 
1278         // Configuration cf2: m2
1279         ModuleDescriptor descriptor2 = ModuleDescriptor.module("m2").build();
1280         Configuration cf2 = resolveRequires(ModuleUtils.finderOf(descriptor2), "m2");
1281         assertEquals(cf2.parents(), List.of(Configuration.empty()));
1282         assertTrue(cf2.findModule("m2").isPresent());
1283         ResolvedModule m2 = cf2.findModule("m2").get();
1284         assertTrue(m2.configuration() == cf2);
1285 
1286         // Configuration cf3(cf1,cf2): m3 requires m1 and m2
1287         ModuleDescriptor descriptor3
1288             = ModuleDescriptor.module("m3")
1289                 .requires("m1")
1290                 .requires("m2")
1291                 .build();
1292         ModuleFinder finder = ModuleUtils.finderOf(descriptor3);
1293         Configuration cf3 = Configuration.resolveRequires(
1294                 finder,
1295                 List.of(cf1, cf2),  // parents
1296                 ModuleFinder.of(),
1297                 Set.of("m3"));
1298         assertEquals(cf3.parents(), List.of(cf1, cf2));
1299         assertTrue(cf3.findModule("m3").isPresent());
1300         ResolvedModule m3 = cf3.findModule("m3").get();
1301         assertTrue(m3.configuration() == cf3);
1302 
1303         // check readability
1304         assertTrue(m1.reads().isEmpty());
1305         assertTrue(m2.reads().isEmpty());
1306         assertEquals(m3.reads(), Set.of(m1, m2));
1307     }
1308 
1309 
1310     /**
1311      * Basic test of resolving a module that depends on modules in three parent
1312      * configurations arranged in a diamond (two direct parents).
1313      *
1314      * The test consists of four configurations:
1315      * - Configuration cf1: m1
1316      * - Configuration cf2(cf1): m2 requires m1
1317      * - Configuration cf3(cf3): m3 requires m1
1318      * - Configuration cf4(cf2,cf3): m4 requires m1,m2,m3
1319      */
1320     public void testResolvedInMultipleParents2() {
1321         // Configuration cf1: m1
1322         ModuleDescriptor descriptor1 = ModuleDescriptor.module("m1").build();
1323         Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
1324         assertEquals(cf1.parents(), List.of(Configuration.empty()));
1325         assertTrue(cf1.findModule("m1").isPresent());
1326         ResolvedModule m1 = cf1.findModule("m1").get();
1327         assertTrue(m1.configuration() == cf1);
1328 
1329         // Configuration cf2(cf1): m2 requires m1
1330         ModuleDescriptor descriptor2
1331             = ModuleDescriptor.module("m2")
1332                 .requires("m1")
1333                 .build();
1334         Configuration cf2 = Configuration.resolveRequires(
1335                 ModuleUtils.finderOf(descriptor2),
1336                 List.of(cf1),  // parents
1337                 ModuleFinder.of(),
1338                 Set.of("m2"));
1339         assertEquals(cf2.parents(), List.of(cf1));
1340         assertTrue(cf2.findModule("m2").isPresent());
1341         ResolvedModule m2 = cf2.findModule("m2").get();
1342         assertTrue(m2.configuration() == cf2);
1343 
1344         // Configuration cf3(cf1): m3 requires m1
1345         ModuleDescriptor descriptor3
1346             = ModuleDescriptor.module("m3")
1347                 .requires("m1")
1348                 .build();
1349         Configuration cf3 = Configuration.resolveRequires(
1350                 ModuleUtils.finderOf(descriptor3),
1351                 List.of(cf1),  // parents
1352                 ModuleFinder.of(),
1353                 Set.of("m3"));
1354         assertEquals(cf3.parents(), List.of(cf1));
1355         assertTrue(cf3.findModule("m3").isPresent());
1356         ResolvedModule m3 = cf3.findModule("m3").get();
1357         assertTrue(m3.configuration() == cf3);
1358 
1359         // Configuration cf4(cf2,cf3): m4 requires m1,m2,m3
1360         ModuleDescriptor descriptor4
1361             = ModuleDescriptor.module("m4")
1362                 .requires("m1")
1363                 .requires("m2")
1364                 .requires("m3")
1365                 .build();
1366         Configuration cf4 = Configuration.resolveRequires(
1367                 ModuleUtils.finderOf(descriptor4),
1368                 List.of(cf2, cf3),  // parents
1369                 ModuleFinder.of(),
1370                 Set.of("m4"));
1371         assertEquals(cf4.parents(), List.of(cf2, cf3));
1372         assertTrue(cf4.findModule("m4").isPresent());
1373         ResolvedModule m4 = cf4.findModule("m4").get();
1374         assertTrue(m4.configuration() == cf4);
1375 
1376         // check readability
1377         assertTrue(m1.reads().isEmpty());
1378         assertEquals(m2.reads(), Set.of(m1));
1379         assertEquals(m3.reads(), Set.of(m1));
1380         assertEquals(m4.reads(), Set.of(m1, m2, m3));
1381     }
1382 
1383 
1384     /**
1385      * Basic test of resolving a module that depends on modules in three parent
1386      * configurations arranged in a diamond (two direct parents).
1387      *
1388      * The test consists of four configurations:
1389      * - Configuration cf1: m1@1
1390      * - Configuration cf2: m1@2, m2@2
1391      * - Configuration cf3: m1@3, m2@3, m3@3
1392      * - Configuration cf4(cf1,cf2,cf3): m4 requires m1,m2,m3
1393      */
1394     public void testResolvedInMultipleParents3() {
1395         ModuleDescriptor descriptor1, descriptor2, descriptor3;
1396 
1397         // Configuration cf1: m1@1
1398         descriptor1 = ModuleDescriptor.module("m1").version("1").build();
1399         Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
1400         assertEquals(cf1.parents(), List.of(Configuration.empty()));
1401 
1402         // Configuration cf2: m1@2, m2@2
1403         descriptor1 = ModuleDescriptor.module("m1").version("2").build();
1404         descriptor2 = ModuleDescriptor.module("m2").version("2").build();
1405         Configuration cf2 = resolveRequires(
1406                 ModuleUtils.finderOf(descriptor1, descriptor2),
1407                 "m1", "m2");
1408         assertEquals(cf2.parents(), List.of(Configuration.empty()));
1409 
1410         // Configuration cf3: m1@3, m2@3, m3@3
1411         descriptor1 = ModuleDescriptor.module("m1").version("3").build();
1412         descriptor2 = ModuleDescriptor.module("m2").version("3").build();
1413         descriptor3 = ModuleDescriptor.module("m3").version("3").build();
1414         Configuration cf3 = resolveRequires(
1415                 ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3),
1416                 "m1", "m2", "m3");
1417         assertEquals(cf3.parents(), List.of(Configuration.empty()));
1418 
1419         // Configuration cf4(cf1,cf2,cf3): m4 requires m1,m2,m3
1420         ModuleDescriptor descriptor4
1421                 = ModuleDescriptor.module("m4")
1422                 .requires("m1")
1423                 .requires("m2")
1424                 .requires("m3")
1425                 .build();
1426         Configuration cf4 = Configuration.resolveRequires(
1427                 ModuleUtils.finderOf(descriptor4),
1428                 List.of(cf1, cf2, cf3),  // parents
1429                 ModuleFinder.of(),
1430                 Set.of("m4"));
1431         assertEquals(cf4.parents(), List.of(cf1, cf2, cf3));
1432 
1433         assertTrue(cf1.findModule("m1").isPresent());
1434         assertTrue(cf2.findModule("m1").isPresent());
1435         assertTrue(cf2.findModule("m2").isPresent());
1436         assertTrue(cf3.findModule("m1").isPresent());
1437         assertTrue(cf3.findModule("m2").isPresent());
1438         assertTrue(cf3.findModule("m3").isPresent());
1439         assertTrue(cf4.findModule("m4").isPresent());
1440 
1441         ResolvedModule m1_1 = cf1.findModule("m1").get();
1442         ResolvedModule m1_2 = cf2.findModule("m1").get();
1443         ResolvedModule m2_2 = cf2.findModule("m2").get();
1444         ResolvedModule m1_3 = cf3.findModule("m1").get();
1445         ResolvedModule m2_3 = cf3.findModule("m2").get();
1446         ResolvedModule m3_3 = cf3.findModule("m3").get();


1453         assertTrue(m2_3.configuration() == cf3);
1454         assertTrue(m3_3.configuration() == cf3);
1455         assertTrue(m4.configuration() == cf4);
1456 
1457         // check readability
1458         assertTrue(m1_1.reads().isEmpty());
1459         assertTrue(m1_2.reads().isEmpty());
1460         assertTrue(m2_2.reads().isEmpty());
1461         assertTrue(m1_3.reads().isEmpty());
1462         assertTrue(m2_3.reads().isEmpty());
1463         assertTrue(m3_3.reads().isEmpty());
1464         assertEquals(m4.reads(), Set.of(m1_1, m2_2, m3_3));
1465     }
1466 
1467 
1468     /**
1469      * Basic test of using the beforeFinder to override a module in a parent
1470      * configuration.
1471      */
1472     public void testOverriding1() {
1473         ModuleDescriptor descriptor1
1474             = ModuleDescriptor.module("m1")
1475                 .build();
1476 
1477         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1478 
1479         Configuration cf1 = resolveRequires(finder, "m1");
1480         assertTrue(cf1.modules().size() == 1);
1481         assertTrue(cf1.findModule("m1").isPresent());
1482 
1483         Configuration cf2 = resolveRequires(cf1, finder, "m1");
1484         assertTrue(cf2.modules().size() == 1);
1485         assertTrue(cf2.findModule("m1").isPresent());
1486     }
1487 
1488     /**
1489      * Basic test of using the beforeFinder to override a module in a parent
1490      * configuration.
1491      */
1492     public void testOverriding2() {
1493         ModuleDescriptor descriptor1 = ModuleDescriptor.module("m1").build();
1494         Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
1495         assertTrue(cf1.modules().size() == 1);
1496         assertTrue(cf1.findModule("m1").isPresent());
1497 
1498         ModuleDescriptor descriptor2 = ModuleDescriptor.module("m2").build();
1499         Configuration cf2 = resolveRequires(ModuleUtils.finderOf(descriptor2), "m2");
1500         assertTrue(cf2.modules().size() == 1);
1501         assertTrue(cf2.findModule("m2").isPresent());
1502 
1503         ModuleDescriptor descriptor3 = ModuleDescriptor.module("m3").build();
1504         Configuration cf3 = resolveRequires(ModuleUtils.finderOf(descriptor3), "m3");
1505         assertTrue(cf3.modules().size() == 1);
1506         assertTrue(cf3.findModule("m3").isPresent());
1507 
1508         // override m2, m1 and m3 should be found in parent configurations
1509         ModuleFinder finder = ModuleUtils.finderOf(descriptor2);
1510         Configuration cf4 = Configuration.resolveRequires(
1511                 finder,
1512                 List.of(cf1, cf2, cf3),
1513                 ModuleFinder.of(),
1514                 Set.of("m1", "m2", "m3"));
1515         assertTrue(cf4.modules().size() == 1);
1516         assertTrue(cf4.findModule("m2").isPresent());
1517         ResolvedModule m2 = cf4.findModule("m2").get();
1518         assertTrue(m2.configuration() == cf4);
1519     }
1520 
1521 
1522     /**
1523      * Basic test of using the beforeFinder to override a module in the parent
1524      * configuration but where implied readability in the picture so that the
1525      * module in the parent is read.
1526      *
1527      * The test consists of two configurations:
1528      * - Configuration cf1: m1, m2 requires transitive m1
1529      * - Configuration cf2: m1, m3 requires m2
1530      */
1531     public void testOverriding3() {
1532 
1533         ModuleDescriptor descriptor1
1534             = ModuleDescriptor.module("m1")
1535                 .build();
1536 
1537         ModuleDescriptor descriptor2
1538             = ModuleDescriptor.module("m2")
1539                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
1540                 .build();
1541 
1542         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
1543 
1544         Configuration cf1 = resolveRequires(finder1, "m2");
1545 
1546         assertTrue(cf1.modules().size() == 2);
1547         assertTrue(cf1.findModule("m1").isPresent());
1548         assertTrue(cf1.findModule("m2").isPresent());
1549 
1550         // cf2: m3 requires m2, m1
1551 
1552         ModuleDescriptor descriptor3
1553             = ModuleDescriptor.module("m3")
1554                 .requires("m2")
1555                 .build();
1556 
1557         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
1558 
1559         Configuration cf2 = resolveRequires(cf1, finder2, "m1", "m3");
1560 
1561         assertTrue(cf2.parents().size() == 1);
1562         assertTrue(cf2.parents().get(0) == cf1);
1563 
1564         assertTrue(cf2.modules().size() == 2);
1565         assertTrue(cf2.findModule("m1").isPresent());
1566         assertTrue(cf2.findModule("m3").isPresent());
1567 
1568         ResolvedModule m1_1 = cf1.findModule("m1").get();
1569         ResolvedModule m1_2 = cf2.findModule("m1").get();
1570         ResolvedModule m2 = cf1.findModule("m2").get();
1571         ResolvedModule m3 = cf2.findModule("m3").get();
1572 
1573         assertTrue(m1_1.configuration() == cf1);
1574         assertTrue(m1_2.configuration() == cf2);
1575         assertTrue(m3.configuration() == cf2);
1576 
1577 
1578         // check that m3 reads cf1/m1 and cf2/m2
1579         assertTrue(m3.reads().size() == 2);
1580         assertTrue(m3.reads().contains(m1_1));
1581         assertTrue(m3.reads().contains(m2));
1582     }
1583 
1584 
1585     /**
1586      * Root module not found
1587      */
1588     @Test(expectedExceptions = { ResolutionException.class })
1589     public void testRootNotFound() {
1590         resolveRequires(ModuleFinder.of(), "m1");
1591     }
1592 
1593 
1594     /**
1595      * Direct dependency not found
1596      */
1597     @Test(expectedExceptions = { ResolutionException.class })
1598     public void testDirectDependencyNotFound() {
1599         ModuleDescriptor descriptor1
1600             = ModuleDescriptor.module("m1").requires("m2").build();
1601         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1602         resolveRequires(finder, "m1");
1603     }
1604 
1605 
1606     /**
1607      * Transitive dependency not found
1608      */
1609     @Test(expectedExceptions = { ResolutionException.class })
1610     public void testTransitiveDependencyNotFound() {
1611         ModuleDescriptor descriptor1
1612             = ModuleDescriptor.module("m1").requires("m2").build();
1613         ModuleDescriptor descriptor2
1614             = ModuleDescriptor.module("m2").requires("m3").build();
1615         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1616         resolveRequires(finder, "m1");
1617     }
1618 
1619 
1620     /**
1621      * Service provider dependency not found
1622      */
1623     @Test(expectedExceptions = { ResolutionException.class })
1624     public void testServiceProviderDependencyNotFound() {
1625 
1626         // service provider dependency (on m3) not found
1627 
1628         ModuleDescriptor descriptor1
1629             = ModuleDescriptor.module("m1")
1630                 .exports("p")
1631                 .uses("p.S")
1632                 .build();
1633 
1634         ModuleDescriptor descriptor2
1635             = ModuleDescriptor.module("m2")
1636                 .requires("m1")
1637                 .requires("m3")
1638                 .contains("q")
1639                 .provides("p.S", "q.T")
1640                 .build();
1641 
1642         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1643 
1644         // should throw ResolutionException because m3 is not found
1645         Configuration cf = resolveRequiresAndUses(finder, "m1");
1646     }
1647 
1648 
1649     /**
1650      * Simple cycle.
1651      */
1652     @Test(expectedExceptions = { ResolutionException.class })
1653     public void testSimpleCycle() {
1654         ModuleDescriptor descriptor1
1655             = ModuleDescriptor.module("m1").requires("m2").build();
1656         ModuleDescriptor descriptor2
1657             = ModuleDescriptor.module("m2").requires("m3").build();
1658         ModuleDescriptor descriptor3
1659             = ModuleDescriptor.module("m3").requires("m1").build();
1660         ModuleFinder finder
1661             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
1662         resolveRequires(finder, "m1");
1663     }
1664 
1665     /**
1666      * Basic test for detecting cycles involving a service provider module
1667      */
1668     @Test(expectedExceptions = { ResolutionException.class })
1669     public void testCycleInProvider() {
1670 
1671         ModuleDescriptor descriptor1
1672             = ModuleDescriptor.module("m1")
1673                 .exports("p")
1674                 .uses("p.S")
1675                 .build();
1676         ModuleDescriptor descriptor2
1677             = ModuleDescriptor.module("m2")
1678                 .requires("m1")
1679                 .requires("m3")
1680                 .contains("q")
1681                 .provides("p.S", "q.T")
1682                 .build();
1683         ModuleDescriptor descriptor3
1684             = ModuleDescriptor.module("m3")
1685                 .requires("m2")
1686                 .build();
1687 
1688         ModuleFinder finder
1689             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
1690 
1691         // should throw ResolutionException because of the m2 <--> m3 cycle
1692         resolveRequiresAndUses(finder, "m1");
1693     }
1694 
1695 
1696     /**
1697      * Test two modules exporting package p to a module that reads both.
1698      */
1699     @Test(expectedExceptions = { ResolutionException.class })
1700     public void testPackageSuppliedByTwoOthers() {
1701 
1702         ModuleDescriptor descriptor1
1703             =  ModuleDescriptor.module("m1")
1704                 .requires("m2")
1705                 .requires("m3")
1706                 .build();
1707 
1708         ModuleDescriptor descriptor2
1709             =  ModuleDescriptor.module("m2")
1710                 .exports("p")
1711                 .build();
1712 
1713         ModuleDescriptor descriptor3
1714             =  ModuleDescriptor.module("m3")
1715                 .exports("p", Set.of("m1"))
1716                 .build();
1717 
1718         ModuleFinder finder
1719             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
1720 
1721         // m2 and m3 export package p to module m1
1722         resolveRequires(finder, "m1");
1723     }
1724 
1725 
1726     /**
1727      * Test the scenario where a module contains a package p and reads
1728      * a module that exports package p.
1729      */
1730     @Test(expectedExceptions = { ResolutionException.class })
1731     public void testPackageSuppliedBySelfAndOther() {
1732 
1733         ModuleDescriptor descriptor1
1734             =  ModuleDescriptor.module("m1")
1735                 .requires("m2")
1736                 .contains("p")
1737                 .build();
1738 
1739         ModuleDescriptor descriptor2
1740             =  ModuleDescriptor.module("m2")
1741                 .exports("p")
1742                 .build();
1743 
1744         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1745 
1746         // m1 contains package p, module m2 exports package p to m1
1747         resolveRequires(finder, "m1");
1748     }
1749 
1750 
1751     /**
1752      * Test the scenario where a module contains a package p and reads
1753      * a module that also contains a package p.
1754      */
1755     public void testContainsPackageInSelfAndOther() {
1756         ModuleDescriptor descriptor1
1757             =  ModuleDescriptor.module("m1")
1758                 .requires("m2")
1759                 .contains("p")
1760                 .build();
1761 
1762         ModuleDescriptor descriptor2
1763             =  ModuleDescriptor.module("m2")
1764                 .contains("p")
1765                 .build();
1766 
1767         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1768 
1769         Configuration cf = resolveRequires(finder, "m1");
1770 
1771         assertTrue(cf.modules().size() == 2);
1772         assertTrue(cf.findModule("m1").isPresent());
1773         assertTrue(cf.findModule("m2").isPresent());
1774 
1775         // m1 reads m2, m2 reads nothing
1776         ResolvedModule m1 = cf.findModule("m1").get();
1777         ResolvedModule m2 = cf.findModule("m2").get();
1778         assertTrue(m1.reads().size() == 1);
1779         assertTrue(m1.reads().contains(m2));
1780         assertTrue(m2.reads().size() == 0);
1781     }
1782 
1783 
1784     /**
1785      * Test the scenario where a module that exports a package that is also
1786      * exported by a module that it reads in a parent layer.
1787      */
1788     @Test(expectedExceptions = { ResolutionException.class })
1789     public void testExportSamePackageAsBootLayer() {
1790         ModuleDescriptor descriptor
1791             =  ModuleDescriptor.module("m1")
1792                 .requires("java.base")
1793                 .exports("java.lang")
1794                 .build();
1795 
1796         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
1797 
1798         Configuration bootConfiguration = Layer.boot().configuration();
1799 
1800         // m1 contains package java.lang, java.base exports package java.lang to m1
1801         resolveRequires(bootConfiguration, finder, "m1");
1802     }
1803 
1804 
1805     /**
1806      * Test "uses p.S" where p is contained in the same module.
1807      */
1808     public void testContainsService1() {
1809         ModuleDescriptor descriptor1
1810             = ModuleDescriptor.module("m1")
1811                 .contains("p")
1812                 .uses("p.S")
1813                 .build();
1814 
1815         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1816 
1817         Configuration cf = resolveRequires(finder, "m1");
1818 
1819         assertTrue(cf.modules().size() == 1);
1820         assertTrue(cf.findModule("m1").isPresent());
1821     }
1822 
1823 
1824     /**
1825      * Test "uses p.S" where p is contained in a different module.
1826      */
1827     @Test(expectedExceptions = { ResolutionException.class })
1828     public void testContainsService2() {
1829         ModuleDescriptor descriptor1
1830             = ModuleDescriptor.module("m1")
1831                 .contains("p")
1832                 .build();
1833 
1834         ModuleDescriptor descriptor2
1835             = ModuleDescriptor.module("m2")
1836                 .requires("m1")
1837                 .uses("p.S")
1838                 .build();
1839 
1840         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1841 
1842         // m2 does not read a module that exports p
1843         resolveRequires(finder, "m2");
1844     }
1845 
1846 
1847     /**
1848      * Test "provides p.S" where p is contained in the same module.
1849      */
1850     public void testContainsService3() {
1851         ModuleDescriptor descriptor1
1852             = ModuleDescriptor.module("m1")
1853                 .contains("p")
1854                 .contains("q")
1855                 .provides("p.S", "q.S1")
1856                 .build();
1857 
1858         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1859 
1860         Configuration cf = resolveRequires(finder, "m1");
1861 
1862         assertTrue(cf.modules().size() == 1);
1863         assertTrue(cf.findModule("m1").isPresent());
1864     }
1865 
1866 
1867     /**
1868      * Test "provides p.S" where p is contained in a different module.
1869      */
1870     @Test(expectedExceptions = { ResolutionException.class })
1871     public void testContainsService4() {
1872         ModuleDescriptor descriptor1
1873             = ModuleDescriptor.module("m1")
1874                 .contains("p")
1875                 .build();
1876 
1877         ModuleDescriptor descriptor2
1878             = ModuleDescriptor.module("m2")
1879                 .requires("m1")
1880                 .contains("q")
1881                 .provides("p.S", "q.S1")
1882                 .build();
1883 
1884         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1885 
1886         // m2 does not read a module that exports p
1887         resolveRequires(finder, "m2");
1888     }
1889 
1890 
1891     /**
1892      * Test "uses p.S" where p is not exported to the module.
1893      */
1894     @Test(expectedExceptions = { ResolutionException.class })
1895     public void testServiceTypePackageNotExported1() {
1896         ModuleDescriptor descriptor1
1897             = ModuleDescriptor.module("m1")
1898                 .uses("p.S")
1899                 .build();
1900 
1901         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1902 
1903         // m1 does not read a module that exports p
1904         resolveRequires(finder, "m1");
1905     }
1906 
1907 
1908     /**
1909      * Test "provides p.S" where p is not exported to the module.
1910      */
1911     @Test(expectedExceptions = { ResolutionException.class })
1912     public void testServiceTypePackageNotExported2() {
1913         ModuleDescriptor descriptor1
1914             = ModuleDescriptor.module("m1")
1915                 .contains("q")
1916                 .provides("p.S", "q.T")
1917                 .build();
1918 
1919         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1920 
1921         // m1 does not read a module that exports p
1922         resolveRequires(finder, "m1");
1923     }
1924 
1925 
1926     /**
1927      * Test "provides p.S with q.T" where q.T is not local
1928      */
1929     @Test(expectedExceptions = { ResolutionException.class })
1930     public void testProviderPackageNotLocal() {
1931         ModuleDescriptor descriptor1
1932             = ModuleDescriptor.module("m1")
1933                 .exports("p")
1934                 .exports("q")
1935                 .build();
1936 
1937         ModuleDescriptor descriptor2
1938             = ModuleDescriptor.module("m2")
1939                 .requires("m1")
1940                 .provides("p.S", "q.T")
1941                 .build();
1942 
1943         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1944 
1945         // q.T not in module m2
1946         resolveRequires(finder, "m2");
1947     }
1948 
1949 
1950     /**
1951      * Test the empty configuration.
1952      */
1953     public void testEmptyConfiguration() {
1954         Configuration cf = Configuration.empty();
1955 
1956         assertTrue(cf.parents().isEmpty());
1957 
1958         assertTrue(cf.modules().isEmpty());
1959         assertFalse(cf.findModule("java.base").isPresent());
1960     }
1961 
1962 
1963     // platform specific modules
1964 
1965     @DataProvider(name = "platformmatch")
1966     public Object[][] createPlatformMatches() {


1990         };
1991 
1992     };
1993 
1994     @DataProvider(name = "platformmismatch")
1995     public Object[][] createBad() {
1996         return new Object[][] {
1997 
1998             { "linux-*-*",        "solaris-*-*"   },
1999             { "linux-x86-*",      "linux-arm-*"   },
2000             { "linux-*-2.4",      "linux-x86-2.6" },
2001         };
2002     }
2003 
2004     /**
2005      * Test creating a configuration containing platform specific modules.
2006      */
2007     @Test(dataProvider = "platformmatch")
2008     public void testPlatformMatch(String s1, String s2) {
2009 
2010         ModuleDescriptor.Builder builder
2011             = ModuleDescriptor.module("m1").requires("m2");
2012 
2013         String[] s = s1.split("-");
2014         if (!s[0].equals("*"))
2015             builder.osName(s[0]);
2016         if (!s[1].equals("*"))
2017             builder.osArch(s[1]);
2018         if (!s[2].equals("*"))
2019             builder.osVersion(s[2]);
2020 
2021         ModuleDescriptor descriptor1 = builder.build();
2022 
2023         builder = ModuleDescriptor.module("m2");
2024 
2025         s = s2.split("-");
2026         if (!s[0].equals("*"))
2027             builder.osName(s[0]);
2028         if (!s[1].equals("*"))
2029             builder.osArch(s[1]);
2030         if (!s[2].equals("*"))
2031             builder.osVersion(s[2]);
2032 
2033         ModuleDescriptor descriptor2 = builder.build();
2034 
2035         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
2036 
2037         Configuration cf = resolveRequires(finder, "m1");
2038 
2039         assertTrue(cf.modules().size() == 2);
2040         assertTrue(cf.findModule("m1").isPresent());
2041         assertTrue(cf.findModule("m2").isPresent());
2042     }
2043 
2044     /**
2045      * Test attempting to create a configuration with modules for different
2046      * platforms.
2047      */
2048     @Test(dataProvider = "platformmismatch",
2049           expectedExceptions = ResolutionException.class )
2050     public void testPlatformMisMatch(String s1, String s2) {
2051         testPlatformMatch(s1, s2);
2052     }
2053 
2054 
2055     // no parents
2056 
2057     @Test(expectedExceptions = { IllegalArgumentException.class })
2058     public void testResolveRequiresWithNoParents() {
2059         ModuleFinder empty = ModuleFinder.of();
2060         Configuration.resolveRequires(empty, List.of(), empty, Set.of());
2061     }
2062 
2063     @Test(expectedExceptions = { IllegalArgumentException.class })
2064     public void testResolveRequiresAndUsesWithNoParents() {
2065         ModuleFinder empty = ModuleFinder.of();
2066         Configuration.resolveRequiresAndUses(empty, List.of(), empty, Set.of());


















































2067     }
2068 
2069 

2070     // null handling
2071 
2072     // finder1, finder2, roots
2073 
2074 
2075     @Test(expectedExceptions = { NullPointerException.class })
2076     public void testResolveRequiresWithNull1() {
2077         resolveRequires((ModuleFinder)null, ModuleFinder.of());
2078     }
2079 
2080     @Test(expectedExceptions = { NullPointerException.class })
2081     public void testResolveRequiresWithNull2() {
2082         resolveRequires(ModuleFinder.of(), (ModuleFinder)null);
2083     }
2084 
2085     @Test(expectedExceptions = { NullPointerException.class })
2086     public void testResolveRequiresWithNull3() {
2087         Configuration empty = Configuration.empty();
2088         Configuration.resolveRequires(null, List.of(empty),  ModuleFinder.of(), Set.of());
2089     }
2090 
2091     @Test(expectedExceptions = { NullPointerException.class })
2092     public void testResolveRequiresWithNull4() {
2093         ModuleFinder empty = ModuleFinder.of();
2094         Configuration.resolveRequires(empty, null, empty, Set.of());
2095     }
2096 
2097     @Test(expectedExceptions = { NullPointerException.class })
2098     public void testResolveRequiresWithNull5() {
2099         Configuration cf = Layer.boot().configuration();
2100         Configuration.resolveRequires(ModuleFinder.of(), List.of(cf), null, Set.of());
2101     }
2102 
2103     @Test(expectedExceptions = { NullPointerException.class })
2104     public void testResolveRequiresWithNull6() {
2105         ModuleFinder empty = ModuleFinder.of();
2106         Configuration cf = Layer.boot().configuration();
2107         Configuration.resolveRequires(empty, List.of(cf), empty, null);
2108     }
2109 
2110     @Test(expectedExceptions = { NullPointerException.class })
2111     public void testResolveRequiresAndUsesWithNull1() {
2112         resolveRequiresAndUses((ModuleFinder) null, ModuleFinder.of());
2113     }
2114 
2115     @Test(expectedExceptions = { NullPointerException.class })
2116     public void testResolveRequiresAndUsesWithNull2() {
2117         resolveRequiresAndUses(ModuleFinder.of(), (ModuleFinder) null);
2118     }
2119 
2120     @Test(expectedExceptions = { NullPointerException.class })
2121     public void testResolveRequiresAndUsesWithNull3() {
2122         Configuration empty = Configuration.empty();
2123         Configuration.resolveRequiresAndUses(null, List.of(empty), ModuleFinder.of(), Set.of());
2124     }
2125 
2126     @Test(expectedExceptions = { NullPointerException.class })
2127     public void testResolveRequiresAndUsesWithNull4() {
2128         ModuleFinder empty = ModuleFinder.of();
2129         Configuration.resolveRequiresAndUses(empty, null, empty, Set.of());
2130     }
2131 
2132     @Test(expectedExceptions = { NullPointerException.class })
2133     public void testResolveRequiresAndUsesWithNull5() {
2134         Configuration cf = Layer.boot().configuration();
2135         Configuration.resolveRequiresAndUses(ModuleFinder.of(), List.of(cf), null, Set.of());
2136     }
2137 
2138     @Test(expectedExceptions = { NullPointerException.class })
2139     public void testResolveRequiresAndUsesWithNull6() {
2140         ModuleFinder empty = ModuleFinder.of();
2141         Configuration cf = Layer.boot().configuration();
2142         Configuration.resolveRequiresAndUses(empty, List.of(cf), empty, null);
2143     }
2144 
2145     @Test(expectedExceptions = { NullPointerException.class })
2146     public void testFindModuleWithNull() {
2147         Configuration.empty().findModule(null);
2148     }
2149 
2150     // immutable sets
2151 
2152     @Test(expectedExceptions = { UnsupportedOperationException.class })
2153     public void testImmutableSet1() {
2154         Configuration cf = Layer.boot().configuration();
2155         ResolvedModule base = cf.findModule("java.base").get();
2156         cf.modules().add(base);
2157     }
2158 
2159     @Test(expectedExceptions = { UnsupportedOperationException.class })
2160     public void testImmutableSet2() {
2161         Configuration cf = Layer.boot().configuration();
2162         ResolvedModule base = cf.findModule("java.base").get();
2163         base.reads().add(base);
2164     }
2165 
2166 
2167     /**
2168      * Invokes parent.resolveRequires(...)
2169      */
2170     private Configuration resolveRequires(Configuration parent,
2171                                           ModuleFinder before,
2172                                           ModuleFinder after,
2173                                           String... roots) {
2174         return parent.resolveRequires(before, after, Set.of(roots));
2175     }
2176 
2177     private Configuration resolveRequires(Configuration parent,
2178                                           ModuleFinder before,
2179                                           String... roots) {
2180         return resolveRequires(parent, before, ModuleFinder.of(), roots);
2181     }
2182 
2183     private Configuration resolveRequires(ModuleFinder before,
2184                                           ModuleFinder after,
2185                                           String... roots) {
2186         return resolveRequires(Configuration.empty(), before, after, roots);
2187     }
2188 
2189     private Configuration resolveRequires(ModuleFinder before,
2190                                           String... roots) {
2191         return resolveRequires(Configuration.empty(), before, roots);
2192     }
2193 
2194 
2195     /**
2196      * Invokes parent.resolveRequiresAndUses(...)
2197      */
2198     private Configuration resolveRequiresAndUses(Configuration parent,
2199                                                  ModuleFinder before,
2200                                                  ModuleFinder after,
2201                                                  String... roots) {
2202         return parent.resolveRequiresAndUses(before, after, Set.of(roots));
2203     }
2204 
2205     private Configuration resolveRequiresAndUses(Configuration parent,
2206                                                  ModuleFinder before,
2207                                                  String... roots) {
2208         return resolveRequiresAndUses(parent, before, ModuleFinder.of(), roots);
2209     }
2210 
2211     private Configuration resolveRequiresAndUses(ModuleFinder before,
2212                                                  ModuleFinder after,
2213                                                  String... roots) {
2214         return resolveRequiresAndUses(Configuration.empty(), before, after, roots);
2215     }
2216 
2217     private Configuration resolveRequiresAndUses(ModuleFinder before,
2218                                                  String... roots) {
2219         return resolveRequiresAndUses(Configuration.empty(), before, roots);
2220     }
2221 
2222 
2223     /**
2224      * Returns {@code true} if the configuration contains module mn1
2225      * that reads module mn2.
2226      */
2227     static boolean reads(Configuration cf, String mn1, String mn2) {
2228         Optional<ResolvedModule> om1 = cf.findModule(mn1);
2229         if (!om1.isPresent())
2230             return false;
2231 
2232         return om1.get().reads().stream()
2233                 .map(ResolvedModule::name)
2234                 .anyMatch(mn2::equals);
2235     }
2236 
2237 












2238 }
   1 /*
   2  * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @library /lib/testlibrary
  27  * @modules java.base/jdk.internal.misc
  28  * @build ConfigurationTest ModuleUtils
  29  * @run testng ConfigurationTest
  30  * @summary Basic tests for java.lang.module.Configuration
  31  */
  32 
  33 import java.lang.module.Configuration;
  34 import java.lang.module.FindException;
  35 import java.lang.module.ModuleDescriptor;
  36 import java.lang.module.ModuleDescriptor.Builder;
  37 import java.lang.module.ModuleDescriptor.Requires;
  38 import java.lang.module.ModuleFinder;
  39 import java.lang.module.ResolutionException;
  40 import java.lang.module.ResolvedModule;
  41 import java.lang.reflect.Layer;

  42 import java.util.List;
  43 import java.util.Optional;
  44 import java.util.Set;
  45 
  46 import jdk.internal.misc.SharedSecrets;
  47 import org.testng.annotations.DataProvider;
  48 import org.testng.annotations.Test;
  49 import static org.testng.Assert.*;
  50 
  51 @Test
  52 public class ConfigurationTest {
  53 
  54     /**
  55      * Creates a "non-strict" builder for building a module. This allows the
  56      * test the create ModuleDescriptor objects that do not require java.base.
  57      */
  58     private static ModuleDescriptor.Builder newBuilder(String mn) {
  59         return SharedSecrets.getJavaLangModuleAccess()
  60                 .newModuleBuilder(mn, false, Set.of());
  61     }
  62 
  63     /**
  64      * Basic test of resolver
  65      *     m1 requires m2, m2 requires m3
  66      */
  67     public void testBasic() {
  68         ModuleDescriptor descriptor1 = newBuilder("m1")

  69                 .requires("m2")
  70                 .build();
  71 
  72         ModuleDescriptor descriptor2 = newBuilder("m2")

  73                 .requires("m3")
  74                 .build();
  75 
  76         ModuleDescriptor descriptor3 = newBuilder("m3")

  77                 .build();
  78 
  79         ModuleFinder finder
  80             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
  81 
  82         Configuration cf = resolve(finder, "m1");
  83 
  84         assertTrue(cf.modules().size() == 3);
  85 
  86         assertTrue(cf.findModule("m1").isPresent());
  87         assertTrue(cf.findModule("m2").isPresent());
  88         assertTrue(cf.findModule("m3").isPresent());
  89 
  90         assertTrue(cf.parents().size() == 1);
  91         assertTrue(cf.parents().get(0) == Configuration.empty());
  92 
  93         ResolvedModule m1 = cf.findModule("m1").get();
  94         ResolvedModule m2 = cf.findModule("m2").get();
  95         ResolvedModule m3 = cf.findModule("m3").get();
  96 
  97         // m1 reads m2
  98         assertTrue(m1.reads().size() == 1);
  99         assertTrue(m1.reads().contains(m2));
 100 
 101         // m2 reads m3
 102         assertTrue(m2.reads().size() == 1);
 103         assertTrue(m2.reads().contains(m3));
 104 
 105         // m3 reads nothing
 106         assertTrue(m3.reads().size() == 0);
 107 
 108         // toString
 109         assertTrue(cf.toString().contains("m1"));
 110         assertTrue(cf.toString().contains("m2"));
 111         assertTrue(cf.toString().contains("m3"));
 112     }
 113 
 114 
 115     /**
 116      * Basic test of "requires transitive":
 117      *     m1 requires m2, m2 requires transitive m3
 118      */
 119     public void testRequiresTransitive1() {
 120         // m1 requires m2, m2 requires transitive m3
 121         ModuleDescriptor descriptor1 = newBuilder("m1")

 122                 .requires("m2")
 123                 .build();
 124 
 125         ModuleDescriptor descriptor2 = newBuilder("m2")

 126                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m3")
 127                 .build();
 128 
 129         ModuleDescriptor descriptor3 = newBuilder("m3")

 130                 .build();
 131 
 132         ModuleFinder finder
 133             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 134 
 135         Configuration cf = resolve(finder, "m1");
 136 
 137         assertTrue(cf.modules().size() == 3);
 138 
 139         assertTrue(cf.findModule("m1").isPresent());
 140         assertTrue(cf.findModule("m2").isPresent());
 141         assertTrue(cf.findModule("m3").isPresent());
 142 
 143         assertTrue(cf.parents().size() == 1);
 144         assertTrue(cf.parents().get(0) == Configuration.empty());
 145 
 146         ResolvedModule m1 = cf.findModule("m1").get();
 147         ResolvedModule m2 = cf.findModule("m2").get();
 148         ResolvedModule m3 = cf.findModule("m3").get();
 149 
 150         // m1 reads m2 and m3
 151         assertTrue(m1.reads().size() == 2);
 152         assertTrue(m1.reads().contains(m2));
 153         assertTrue(m1.reads().contains(m3));
 154 
 155         // m2 reads m3
 156         assertTrue(m2.reads().size() == 1);
 157         assertTrue(m2.reads().contains(m3));
 158 
 159         // m3 reads nothing
 160         assertTrue(m3.reads().size() == 0);
 161     }
 162 
 163 
 164     /**
 165      * Basic test of "requires transitive" with configurations.
 166      *
 167      * The test consists of three configurations:
 168      * - Configuration cf1: m1, m2 requires transitive m1
 169      * - Configuration cf2: m3 requires m2
 170      */
 171     public void testRequiresTransitive2() {
 172 
 173         // cf1: m1 and m2, m2 requires transitive m1
 174 
 175         ModuleDescriptor descriptor1 = newBuilder("m1")

 176                 .build();
 177 
 178         ModuleDescriptor descriptor2 = newBuilder("m2")

 179                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 180                 .build();
 181 
 182         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 183 
 184         Configuration cf1 = resolve(finder1, "m2");
 185 
 186         assertTrue(cf1.modules().size() == 2);
 187         assertTrue(cf1.findModule("m1").isPresent());
 188         assertTrue(cf1.findModule("m2").isPresent());
 189         assertTrue(cf1.parents().size() == 1);
 190         assertTrue(cf1.parents().get(0) == Configuration.empty());
 191 
 192         ResolvedModule m1 = cf1.findModule("m1").get();
 193         ResolvedModule m2 = cf1.findModule("m2").get();
 194 
 195         assertTrue(m1.reads().size() == 0);
 196         assertTrue(m2.reads().size() == 1);
 197         assertTrue(m2.reads().contains(m1));
 198 
 199 
 200         // cf2: m3, m3 requires m2
 201 
 202         ModuleDescriptor descriptor3 = newBuilder("m3")

 203                 .requires("m2")
 204                 .build();
 205 
 206         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 207 
 208         Configuration cf2 = resolve(cf1, finder2, "m3");
 209 
 210         assertTrue(cf2.modules().size() == 1);
 211         assertTrue(cf2.findModule("m1").isPresent());  // in parent
 212         assertTrue(cf2.findModule("m2").isPresent());  // in parent
 213         assertTrue(cf2.findModule("m3").isPresent());
 214         assertTrue(cf2.parents().size() == 1);
 215         assertTrue(cf2.parents().get(0) == cf1);
 216 
 217         ResolvedModule m3 = cf2.findModule("m3").get();
 218         assertTrue(m3.configuration() == cf2);
 219         assertTrue(m3.reads().size() == 2);
 220         assertTrue(m3.reads().contains(m1));
 221         assertTrue(m3.reads().contains(m2));
 222     }
 223 
 224 
 225     /**
 226      * Basic test of "requires transitive" with configurations.
 227      *
 228      * The test consists of three configurations:
 229      * - Configuration cf1: m1
 230      * - Configuration cf2: m2 requires transitive m1, m3 requires m2
 231      */
 232     public void testRequiresTransitive3() {
 233 
 234         // cf1: m1
 235 
 236         ModuleDescriptor descriptor1 = newBuilder("m1").build();


 237 
 238         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 239 
 240         Configuration cf1 = resolve(finder1, "m1");
 241 
 242         assertTrue(cf1.modules().size() == 1);
 243         assertTrue(cf1.findModule("m1").isPresent());
 244         assertTrue(cf1.parents().size() == 1);
 245         assertTrue(cf1.parents().get(0) == Configuration.empty());
 246 
 247         ResolvedModule m1 = cf1.findModule("m1").get();
 248         assertTrue(m1.reads().size() == 0);
 249 
 250 
 251         // cf2: m2, m3: m2 requires transitive m1, m3 requires m2
 252 
 253         ModuleDescriptor descriptor2 = newBuilder("m2")

 254                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 255                 .build();
 256 
 257         ModuleDescriptor descriptor3 = newBuilder("m3")

 258                 .requires("m2")
 259                 .build();
 260 
 261         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3);
 262 
 263         Configuration cf2 = resolve(cf1, finder2, "m3");
 264 
 265         assertTrue(cf2.modules().size() == 2);
 266         assertTrue(cf2.findModule("m1").isPresent());   // in parent
 267         assertTrue(cf2.findModule("m2").isPresent());
 268         assertTrue(cf2.findModule("m3").isPresent());
 269         assertTrue(cf2.parents().size() == 1);
 270         assertTrue(cf2.parents().get(0) == cf1);
 271 
 272         ResolvedModule m2 = cf2.findModule("m2").get();
 273         ResolvedModule m3 = cf2.findModule("m3").get();
 274 
 275         assertTrue(m2.configuration() == cf2);
 276         assertTrue(m2.reads().size() == 1);
 277         assertTrue(m2.reads().contains(m1));
 278 
 279         assertTrue(m3.configuration() == cf2);
 280         assertTrue(m3.reads().size() == 2);
 281         assertTrue(m3.reads().contains(m1));
 282         assertTrue(m3.reads().contains(m2));
 283     }
 284 
 285 
 286     /**
 287      * Basic test of "requires transitive" with configurations.
 288      *
 289      * The test consists of three configurations:
 290      * - Configuration cf1: m1
 291      * - Configuration cf2: m2 requires transitive m1
 292      * - Configuraiton cf3: m3 requires m2
 293      */
 294     public void testRequiresTransitive4() {
 295 
 296         // cf1: m1
 297 
 298         ModuleDescriptor descriptor1 = newBuilder("m1").build();


 299 
 300         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 301 
 302         Configuration cf1 = resolve(finder1, "m1");
 303 
 304         assertTrue(cf1.modules().size() == 1);
 305         assertTrue(cf1.findModule("m1").isPresent());
 306         assertTrue(cf1.parents().size() == 1);
 307         assertTrue(cf1.parents().get(0) == Configuration.empty());
 308 
 309         ResolvedModule m1 = cf1.findModule("m1").get();
 310         assertTrue(m1.reads().size() == 0);
 311 
 312 
 313         // cf2: m2 requires transitive m1
 314 
 315         ModuleDescriptor descriptor2 = newBuilder("m2")

 316                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 317                 .build();
 318 
 319         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
 320 
 321         Configuration cf2 = resolve(cf1, finder2, "m2");
 322 
 323         assertTrue(cf2.modules().size() == 1);
 324         assertTrue(cf2.findModule("m1").isPresent());  // in parent
 325         assertTrue(cf2.findModule("m2").isPresent());
 326         assertTrue(cf2.parents().size() == 1);
 327         assertTrue(cf2.parents().get(0) == cf1);
 328 
 329         ResolvedModule m2 = cf2.findModule("m2").get();
 330 
 331         assertTrue(m2.configuration() == cf2);
 332         assertTrue(m2.reads().size() == 1);
 333         assertTrue(m2.reads().contains(m1));
 334 
 335 
 336         // cf3: m3 requires m2
 337 
 338         ModuleDescriptor descriptor3 = newBuilder("m3")

 339                 .requires("m2")
 340                 .build();
 341 
 342         ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3);
 343 
 344         Configuration cf3 = resolve(cf2, finder3, "m3");
 345 
 346         assertTrue(cf3.modules().size() == 1);
 347         assertTrue(cf3.findModule("m1").isPresent());  // in parent
 348         assertTrue(cf3.findModule("m2").isPresent());  // in parent
 349         assertTrue(cf3.findModule("m3").isPresent());
 350         assertTrue(cf3.parents().size() == 1);
 351         assertTrue(cf3.parents().get(0) == cf2);
 352 
 353         ResolvedModule m3 = cf3.findModule("m3").get();
 354 
 355         assertTrue(m3.configuration() == cf3);
 356         assertTrue(m3.reads().size() == 2);
 357         assertTrue(m3.reads().contains(m1));
 358         assertTrue(m3.reads().contains(m2));
 359     }
 360 
 361 
 362     /**
 363      * Basic test of "requires transitive" with configurations.
 364      *
 365      * The test consists of two configurations:
 366      * - Configuration cf1: m1, m2 requires transitive m1
 367      * - Configuration cf2: m3 requires transitive m2, m4 requires m3
 368      */
 369     public void testRequiresTransitive5() {
 370 
 371         // cf1: m1, m2 requires transitive m1
 372 
 373         ModuleDescriptor descriptor1 = newBuilder("m1")

 374                 .build();
 375 
 376         ModuleDescriptor descriptor2 = newBuilder("m2")

 377                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 378                 .build();
 379 
 380         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 381 
 382         Configuration cf1 = resolve(finder1, "m2");
 383 
 384         assertTrue(cf1.modules().size() == 2);
 385         assertTrue(cf1.findModule("m1").isPresent());
 386         assertTrue(cf1.findModule("m2").isPresent());
 387         assertTrue(cf1.parents().size() == 1);
 388         assertTrue(cf1.parents().get(0) == Configuration.empty());
 389 
 390         ResolvedModule m1 = cf1.findModule("m1").get();
 391         ResolvedModule m2 = cf1.findModule("m2").get();
 392 
 393         assertTrue(m1.configuration() == cf1);
 394         assertTrue(m1.reads().size() == 0);
 395 
 396         assertTrue(m2.configuration() == cf1);
 397         assertTrue(m2.reads().size() == 1);
 398         assertTrue(m2.reads().contains(m1));
 399 
 400 
 401         // cf2: m3 requires transitive m2, m4 requires m3
 402 
 403         ModuleDescriptor descriptor3 = newBuilder("m3")

 404                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m2")
 405                 .build();
 406 
 407         ModuleDescriptor descriptor4 = newBuilder("m4")

 408                 .requires("m3")
 409                 .build();
 410 
 411 
 412         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 413 
 414         Configuration cf2 = resolve(cf1, finder2, "m3", "m4");
 415 
 416         assertTrue(cf2.modules().size() == 2);
 417         assertTrue(cf2.findModule("m1").isPresent());   // in parent
 418         assertTrue(cf2.findModule("m2").isPresent());   // in parent
 419         assertTrue(cf2.findModule("m3").isPresent());
 420         assertTrue(cf2.findModule("m4").isPresent());
 421         assertTrue(cf2.parents().size() == 1);
 422         assertTrue(cf2.parents().get(0) == cf1);
 423 
 424         ResolvedModule m3 = cf2.findModule("m3").get();
 425         ResolvedModule m4 = cf2.findModule("m4").get();
 426 
 427         assertTrue(m3.configuration() == cf2);
 428         assertTrue(m3.reads().size() == 2);
 429         assertTrue(m3.reads().contains(m1));
 430         assertTrue(m3.reads().contains(m2));
 431 
 432         assertTrue(m4.configuration() == cf2);
 433         assertTrue(m4.reads().size() == 3);
 434         assertTrue(m4.reads().contains(m1));
 435         assertTrue(m4.reads().contains(m2));
 436         assertTrue(m4.reads().contains(m3));
 437     }
 438 
 439 
 440     /**
 441      * Basic test of "requires transitive" with configurations.
 442      *
 443      * The test consists of three configurations:
 444      * - Configuration cf1: m1, m2 requires transitive m1
 445      * - Configuration cf2: m1, m3 requires transitive m1
 446      * - Configuration cf3(cf1,cf2): m4 requires m2, m3
 447      */
 448     public void testRequiresTransitive6() {
 449         ModuleDescriptor descriptor1 = newBuilder("m1")

 450                 .build();
 451 
 452         ModuleDescriptor descriptor2 = newBuilder("m2")

 453                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 454                 .build();
 455 
 456         ModuleDescriptor descriptor3 = newBuilder("m3")

 457                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 458                 .build();
 459 
 460         ModuleDescriptor descriptor4 = newBuilder("m4")

 461                 .requires("m2")
 462                 .requires("m3")
 463                 .build();
 464 
 465         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 466         Configuration cf1 = resolve(finder1, "m2");
 467         assertTrue(cf1.modules().size() == 2);
 468         assertTrue(cf1.findModule("m1").isPresent());
 469         assertTrue(cf1.findModule("m2").isPresent());
 470         assertTrue(cf1.parents().size() == 1);
 471         assertTrue(cf1.parents().get(0) == Configuration.empty());
 472 
 473         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
 474         Configuration cf2 = resolve(finder2, "m3");
 475         assertTrue(cf2.modules().size() == 2);
 476         assertTrue(cf2.findModule("m3").isPresent());
 477         assertTrue(cf2.findModule("m1").isPresent());
 478         assertTrue(cf2.parents().size() == 1);
 479         assertTrue(cf2.parents().get(0) == Configuration.empty());
 480 
 481         ModuleFinder finder3 = ModuleUtils.finderOf(descriptor4);
 482         Configuration cf3 = Configuration.resolve(finder3,
 483                 List.of(cf1, cf2),
 484                 ModuleFinder.of(),
 485                 Set.of("m4"));
 486         assertTrue(cf3.modules().size() == 1);
 487         assertTrue(cf3.findModule("m4").isPresent());
 488 
 489         ResolvedModule m1_l = cf1.findModule("m1").get();
 490         ResolvedModule m1_r = cf2.findModule("m1").get();
 491         ResolvedModule m2 = cf1.findModule("m2").get();
 492         ResolvedModule m3 = cf2.findModule("m3").get();
 493         ResolvedModule m4 = cf3.findModule("m4").get();
 494         assertTrue(m4.configuration() == cf3);
 495 
 496         assertTrue(m4.reads().size() == 4);
 497         assertTrue(m4.reads().contains(m1_l));
 498         assertTrue(m4.reads().contains(m1_r));
 499         assertTrue(m4.reads().contains(m2));
 500         assertTrue(m4.reads().contains(m3));
 501     }
 502 
 503 
 504     /**
 505      * Basic test of "requires static":
 506      *     m1 requires static m2
 507      *     m2 is not observable
 508      *     resolve m1
 509      */
 510     public void testRequiresStatic1() {
 511         ModuleDescriptor descriptor1 = newBuilder("m1")

 512                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
 513                 .build();
 514 
 515         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 516 
 517         Configuration cf = resolve(finder, "m1");
 518 
 519         assertTrue(cf.modules().size() == 1);
 520 
 521         ResolvedModule m1 = cf.findModule("m1").get();
 522         assertTrue(m1.reads().size() == 0);
 523     }
 524 
 525 
 526     /**
 527      * Basic test of "requires static":
 528      *     m1 requires static m2
 529      *     m2
 530      *     resolve m1
 531      */
 532     public void testRequiresStatic2() {
 533         ModuleDescriptor descriptor1 = newBuilder("m1")

 534                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
 535                 .build();
 536 
 537         ModuleDescriptor descriptor2 = newBuilder("m2")

 538                 .build();
 539 
 540         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 541 
 542         Configuration cf = resolve(finder, "m1");
 543 
 544         assertTrue(cf.modules().size() == 1);
 545 
 546         ResolvedModule m1 = cf.findModule("m1").get();
 547         assertTrue(m1.reads().size() == 0);
 548     }
 549 
 550 
 551     /**
 552      * Basic test of "requires static":
 553      *     m1 requires static m2
 554      *     m2
 555      *     resolve m1, m2
 556      */
 557     public void testRequiresStatic3() {
 558         ModuleDescriptor descriptor1 = newBuilder("m1")

 559                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
 560                 .build();
 561 
 562         ModuleDescriptor descriptor2 = newBuilder("m2")

 563                 .build();
 564 
 565         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 566 
 567         Configuration cf = resolve(finder, "m1", "m2");
 568 
 569         assertTrue(cf.modules().size() == 2);
 570 
 571         ResolvedModule m1 = cf.findModule("m1").get();
 572         ResolvedModule m2 = cf.findModule("m2").get();
 573 
 574         assertTrue(m1.reads().size() == 1);
 575         assertTrue(m1.reads().contains(m2));
 576 
 577         assertTrue(m2.reads().size() == 0);
 578     }
 579 
 580 
 581     /**
 582      * Basic test of "requires static":
 583      *     m1 requires m2, m3
 584      *     m2 requires static m2
 585      *     m3
 586      */
 587     public void testRequiresStatic4() {
 588         ModuleDescriptor descriptor1 = newBuilder("m1")

 589                 .requires("m2")
 590                 .requires("m3")
 591                 .build();
 592 
 593         ModuleDescriptor descriptor2 = newBuilder("m2")

 594                 .requires(Set.of(Requires.Modifier.STATIC), "m3")
 595                 .build();
 596 
 597         ModuleDescriptor descriptor3 = newBuilder("m3")

 598                 .build();
 599 
 600         ModuleFinder finder
 601             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 602 
 603         Configuration cf = resolve(finder, "m1");
 604 
 605         assertTrue(cf.modules().size() == 3);
 606 
 607         ResolvedModule m1 = cf.findModule("m1").get();
 608         ResolvedModule m2 = cf.findModule("m2").get();
 609         ResolvedModule m3 = cf.findModule("m3").get();
 610 
 611         assertTrue(m1.reads().size() == 2);
 612         assertTrue(m1.reads().contains(m2));
 613         assertTrue(m1.reads().contains(m3));
 614 
 615         assertTrue(m2.reads().size() == 1);
 616         assertTrue(m2.reads().contains(m3));
 617 
 618         assertTrue(m3.reads().size() == 0);
 619     }
 620 
 621 
 622     /**
 623      * Basic test of "requires static":
 624      * The test consists of three configurations:
 625      * - Configuration cf1: m1, m2
 626      * - Configuration cf2: m3 requires m1, requires static m2
 627      */
 628     public void testRequiresStatic5() {
 629         ModuleDescriptor descriptor1 = newBuilder("m1")

 630                 .build();
 631 
 632         ModuleDescriptor descriptor2 = newBuilder("m2")

 633                 .build();
 634 
 635         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 636 
 637         Configuration cf1 = resolve(finder1, "m1", "m2");
 638 
 639         assertTrue(cf1.modules().size() == 2);
 640         assertTrue(cf1.findModule("m1").isPresent());
 641         assertTrue(cf1.findModule("m2").isPresent());
 642 
 643         ModuleDescriptor descriptor3 = newBuilder("m3")

 644                 .requires("m1")
 645                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
 646                 .build();
 647 
 648         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 649 
 650         Configuration cf2 = resolve(cf1, finder2, "m3");
 651 
 652         assertTrue(cf2.modules().size() == 1);
 653         assertTrue(cf2.findModule("m3").isPresent());
 654 
 655         ResolvedModule m1 = cf1.findModule("m1").get();
 656         ResolvedModule m2 = cf1.findModule("m2").get();
 657         ResolvedModule m3 = cf2.findModule("m3").get();
 658 
 659         assertTrue(m3.reads().size() == 2);
 660         assertTrue(m3.reads().contains(m1));
 661         assertTrue(m3.reads().contains(m2));
 662     }
 663 
 664 
 665     /**
 666      * Basic test of "requires static":
 667      * The test consists of three configurations:
 668      * - Configuration cf1: m1
 669      * - Configuration cf2: m3 requires m1, requires static m2
 670      */
 671     public void testRequiresStatic6() {
 672         ModuleDescriptor descriptor1 = newBuilder("m1")

 673                 .build();
 674 
 675         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 676 
 677         Configuration cf1 = resolve(finder1, "m1");
 678 
 679         assertTrue(cf1.modules().size() == 1);
 680         assertTrue(cf1.findModule("m1").isPresent());
 681 
 682         ModuleDescriptor descriptor3 = newBuilder("m3")

 683                 .requires("m1")
 684                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
 685                 .build();
 686 
 687         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 688 
 689         Configuration cf2 = resolve(cf1, finder2, "m3");
 690 
 691         assertTrue(cf2.modules().size() == 1);
 692         assertTrue(cf2.findModule("m3").isPresent());
 693 
 694         ResolvedModule m1 = cf1.findModule("m1").get();
 695         ResolvedModule m3 = cf2.findModule("m3").get();
 696 
 697         assertTrue(m3.reads().size() == 1);
 698         assertTrue(m3.reads().contains(m1));
 699     }
 700 
 701 
 702     /**
 703      * Basic test of "requires static":
 704      *     (m1 not observable)
 705      *     m2 requires transitive static m1
 706      *     m3 requires m2
 707      */
 708     public void testRequiresStatic7() {
 709         ModuleDescriptor descriptor1 = null;  // not observable
 710 
 711         ModuleDescriptor descriptor2 = newBuilder("m2")

 712                 .requires(Set.of(Requires.Modifier.TRANSITIVE,
 713                                 Requires.Modifier.STATIC),
 714                          "m1")
 715                 .build();
 716 
 717         ModuleDescriptor descriptor3 = newBuilder("m3")

 718                 .requires("m2")
 719                 .build();
 720 
 721         ModuleFinder finder = ModuleUtils.finderOf(descriptor2, descriptor3);
 722 
 723         Configuration cf = resolve(finder, "m3");
 724 
 725         assertTrue(cf.modules().size() == 2);
 726         assertTrue(cf.findModule("m2").isPresent());
 727         assertTrue(cf.findModule("m3").isPresent());
 728         ResolvedModule m2 = cf.findModule("m2").get();
 729         ResolvedModule m3 = cf.findModule("m3").get();
 730         assertTrue(m2.reads().isEmpty());
 731         assertTrue(m3.reads().size() == 1);
 732         assertTrue(m3.reads().contains(m2));
 733     }
 734 
 735 
 736     /**
 737      * Basic test of "requires static":
 738      * - Configuration cf1: m2 requires transitive static m1
 739      * - Configuration cf2: m3 requires m2
 740      */
 741     public void testRequiresStatic8() {
 742         ModuleDescriptor descriptor1 = null;  // not observable
 743 
 744         ModuleDescriptor descriptor2 = newBuilder("m2")

 745                 .requires(Set.of(Requires.Modifier.TRANSITIVE,
 746                                 Requires.Modifier.STATIC),
 747                         "m1")
 748                 .build();
 749 
 750         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2);
 751 
 752         Configuration cf1 = resolve(finder1, "m2");
 753 
 754         assertTrue(cf1.modules().size() == 1);
 755         assertTrue(cf1.findModule("m2").isPresent());
 756         ResolvedModule m2 = cf1.findModule("m2").get();
 757         assertTrue(m2.reads().isEmpty());
 758 
 759         ModuleDescriptor descriptor3 = newBuilder("m3")

 760                 .requires("m2")
 761                 .build();
 762 
 763         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 764 
 765         Configuration cf2 = resolve(cf1, finder2, "m3");
 766 
 767         assertTrue(cf2.modules().size() == 1);
 768         assertTrue(cf2.findModule("m3").isPresent());
 769         ResolvedModule m3 = cf2.findModule("m3").get();
 770         assertTrue(m3.reads().size() == 1);
 771         assertTrue(m3.reads().contains(m2));
 772     }
 773 
 774 
 775     /**
 776      * Basic test of binding services
 777      *     m1 uses p.S
 778      *     m2 provides p.S
 779      */
 780     public void testServiceBinding1() {
 781 
 782         ModuleDescriptor descriptor1 = newBuilder("m1")

 783                 .exports("p")
 784                 .uses("p.S")
 785                 .build();
 786 
 787         ModuleDescriptor descriptor2 = newBuilder("m2")

 788                 .requires("m1")
 789                 .provides("p.S", List.of("q.T"))

 790                 .build();
 791 
 792         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 793 
 794         Configuration cf = resolveAndBind(finder, "m1");
 795 
 796         assertTrue(cf.modules().size() == 2);
 797         assertTrue(cf.findModule("m1").isPresent());
 798         assertTrue(cf.findModule("m2").isPresent());
 799         assertTrue(cf.parents().size() == 1);
 800         assertTrue(cf.parents().get(0) == Configuration.empty());
 801 
 802         ResolvedModule m1 = cf.findModule("m1").get();
 803         ResolvedModule m2 = cf.findModule("m2").get();
 804 
 805         assertTrue(m1.configuration() == cf);
 806         assertTrue(m1.reads().size() == 0);
 807 
 808         assertTrue(m2.configuration() == cf);
 809         assertTrue(m2.reads().size() == 1);
 810         assertTrue(m2.reads().contains(m1));
 811     }
 812 
 813 
 814     /**
 815      * Basic test of binding services
 816      *     m1 uses p.S1
 817      *     m2 provides p.S1, m2 uses p.S2
 818      *     m3 provides p.S2
 819      */
 820     public void testServiceBinding2() {
 821 
 822         ModuleDescriptor descriptor1 = newBuilder("m1")

 823                 .exports("p")
 824                 .uses("p.S1")
 825                 .build();
 826 
 827         ModuleDescriptor descriptor2 = newBuilder("m2")

 828                 .requires("m1")
 829                 .uses("p.S2")
 830                 .provides("p.S1", List.of("q.Service1Impl"))

 831                 .build();
 832 
 833         ModuleDescriptor descriptor3 = newBuilder("m3")

 834                 .requires("m1")
 835                 .provides("p.S2", List.of("q.Service2Impl"))

 836                 .build();
 837 
 838         ModuleFinder finder
 839             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 840 
 841         Configuration cf = resolveAndBind(finder, "m1");
 842 
 843         assertTrue(cf.modules().size() == 3);
 844         assertTrue(cf.findModule("m1").isPresent());
 845         assertTrue(cf.findModule("m2").isPresent());
 846         assertTrue(cf.findModule("m3").isPresent());
 847         assertTrue(cf.parents().size() == 1);
 848         assertTrue(cf.parents().get(0) == Configuration.empty());
 849 
 850         ResolvedModule m1 = cf.findModule("m1").get();
 851         ResolvedModule m2 = cf.findModule("m2").get();
 852         ResolvedModule m3 = cf.findModule("m3").get();
 853 
 854         assertTrue(m1.configuration() == cf);
 855         assertTrue(m1.reads().size() == 0);
 856 
 857         assertTrue(m2.configuration() == cf);
 858         assertTrue(m2.reads().size() == 1);
 859         assertTrue(m2.reads().contains(m1));
 860 
 861         assertTrue(m3.configuration() == cf);
 862         assertTrue(m3.reads().size() == 1);
 863         assertTrue(m3.reads().contains(m1));
 864     }
 865 
 866 
 867     /**
 868      * Basic test of binding services with configurations.
 869      *
 870      * The test consists of two configurations:
 871      * - Configuration cf1: m1 uses p.S
 872      * - Configuration cf2: m2 provides p.S
 873      */
 874     public void testServiceBindingWithConfigurations1() {
 875 
 876         ModuleDescriptor descriptor1 = newBuilder("m1")

 877                 .exports("p")
 878                 .uses("p.S")
 879                 .build();
 880 
 881         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 882 
 883         Configuration cf1 = resolve(finder1, "m1");
 884 
 885         assertTrue(cf1.modules().size() == 1);
 886         assertTrue(cf1.findModule("m1").isPresent());
 887 
 888         ModuleDescriptor descriptor2 = newBuilder("m2")

 889                 .requires("m1")
 890                 .provides("p.S", List.of("q.T"))

 891                 .build();
 892 
 893         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
 894 
 895         Configuration cf2 = resolveAndBind(cf1, finder2); // no roots
 896 
 897         assertTrue(cf2.parents().size() == 1);
 898         assertTrue(cf2.parents().get(0) == cf1);
 899 
 900         assertTrue(cf2.modules().size() == 1);
 901         assertTrue(cf2.findModule("m2").isPresent());
 902 
 903         ResolvedModule m1 = cf1.findModule("m1").get();
 904         ResolvedModule m2 = cf2.findModule("m2").get();
 905 
 906         assertTrue(m2.reads().size() == 1);
 907         assertTrue(m2.reads().contains(m1));
 908     }
 909 
 910 
 911     /**
 912      * Basic test of binding services with configurations.
 913      *
 914      * The test consists of two configurations:
 915      * - Configuration cf1: m1 uses p.S && provides p.S,
 916      *                      m2 provides p.S
 917      * - Configuration cf2: m3 provides p.S
 918      *                      m4 provides p.S
 919      */
 920     public void testServiceBindingWithConfigurations2() {
 921 
 922         ModuleDescriptor descriptor1 = newBuilder("m1")

 923                 .exports("p")
 924                 .uses("p.S")
 925                 .provides("p.S", List.of("p1.ServiceImpl"))

 926                 .build();
 927 
 928         ModuleDescriptor descriptor2 = newBuilder("m2")

 929                 .requires("m1")
 930                 .provides("p.S", List.of("p2.ServiceImpl"))

 931                 .build();
 932 
 933         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 934 
 935         Configuration cf1 = resolveAndBind(finder1, "m1");
 936 
 937         assertTrue(cf1.modules().size() == 2);
 938         assertTrue(cf1.findModule("m1").isPresent());
 939         assertTrue(cf1.findModule("m2").isPresent());
 940 
 941 
 942         ModuleDescriptor descriptor3 = newBuilder("m3")

 943                 .requires("m1")
 944                 .provides("p.S", List.of("p3.ServiceImpl"))

 945                 .build();
 946 
 947         ModuleDescriptor descriptor4 = newBuilder("m4")

 948                 .requires("m1")
 949                 .provides("p.S", List.of("p4.ServiceImpl"))

 950                 .build();
 951 
 952         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 953 
 954         Configuration cf2 = resolveAndBind(cf1, finder2); // no roots
 955 
 956         assertTrue(cf2.parents().size() == 1);
 957         assertTrue(cf2.parents().get(0) == cf1);
 958 
 959         assertTrue(cf2.modules().size() == 2);
 960         assertTrue(cf2.findModule("m3").isPresent());
 961         assertTrue(cf2.findModule("m4").isPresent());
 962 
 963         ResolvedModule m1 = cf2.findModule("m1").get();  // should find in parent
 964         ResolvedModule m2 = cf2.findModule("m2").get();
 965         ResolvedModule m3 = cf2.findModule("m3").get();
 966         ResolvedModule m4 = cf2.findModule("m4").get();
 967 
 968         assertTrue(m1.reads().size() == 0);
 969 
 970         assertTrue(m2.reads().size() == 1);
 971         assertTrue(m2.reads().contains(m1));
 972 
 973         assertTrue(m3.reads().size() == 1);
 974         assertTrue(m3.reads().contains(m1));
 975 
 976         assertTrue(m4.reads().size() == 1);
 977         assertTrue(m4.reads().contains(m1));
 978     }
 979 
 980 
 981     /**
 982      * Basic test of binding services with configurations.
 983      *
 984      * Configuration cf1: p@1.0 provides p.S
 985      * Test configuration cf2: m1 uses p.S, p@2.0 provides p.S
 986      * Test configuration cf2: m1 uses p.S
 987      */
 988     public void testServiceBindingWithConfigurations3() {
 989 
 990         ModuleDescriptor service = newBuilder("s")

 991                 .exports("p")
 992                 .build();
 993 
 994         ModuleDescriptor provider_v1 = newBuilder("p")

 995                 .version("1.0")
 996                 .requires("s")
 997                 .provides("p.S", List.of("q.T"))

 998                 .build();
 999 
1000         ModuleFinder finder1 = ModuleUtils.finderOf(service, provider_v1);
1001 
1002         Configuration cf1 = resolve(finder1, "p");
1003 
1004         assertTrue(cf1.modules().size() == 2);
1005         assertTrue(cf1.findModule("s").isPresent());
1006         assertTrue(cf1.findModule("p").isPresent());
1007 
1008         // p@1.0 in cf1
1009         ResolvedModule p = cf1.findModule("p").get();
1010         assertEquals(p.reference().descriptor(), provider_v1);
1011 
1012 
1013         ModuleDescriptor descriptor1 = newBuilder("m1")

1014                 .requires("s")
1015                 .uses("p.S")
1016                 .build();
1017 
1018         ModuleDescriptor provider_v2 = newBuilder("p")

1019                 .version("2.0")
1020                 .requires("s")
1021                 .provides("p.S", List.of("q.T"))

1022                 .build();
1023 
1024         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, provider_v2);
1025 
1026 
1027         // finder2 is the before ModuleFinder and so p@2.0 should be located
1028 
1029         Configuration cf2 = resolveAndBind(cf1, finder2, "m1");
1030 
1031         assertTrue(cf2.parents().size() == 1);
1032         assertTrue(cf2.parents().get(0) == cf1);
1033         assertTrue(cf2.modules().size() == 2);
1034 
1035         // p should be found in cf2
1036         p = cf2.findModule("p").get();
1037         assertTrue(p.configuration() == cf2);
1038         assertEquals(p.reference().descriptor(), provider_v2);
1039 
1040 
1041         // finder2 is the after ModuleFinder and so p@2.0 should not be located
1042         // as module p is in parent configuration.
1043 
1044         cf2 = resolveAndBind(cf1, ModuleFinder.of(), finder2, "m1");
1045 
1046         assertTrue(cf2.parents().size() == 1);
1047         assertTrue(cf2.parents().get(0) == cf1);
1048         assertTrue(cf2.modules().size() == 1);
1049 
1050         // p should be found in cf1
1051         p = cf2.findModule("p").get();
1052         assertTrue(p.configuration() == cf1);
1053         assertEquals(p.reference().descriptor(), provider_v1);
1054     }
1055 
1056 
1057     /**
1058      * Basic test with two module finders.
1059      *
1060      * Module m2 can be found by both the before and after finders.
1061      */
1062     public void testWithTwoFinders1() {
1063 
1064         ModuleDescriptor descriptor1 = newBuilder("m1")

1065                 .requires("m2")
1066                 .build();
1067 
1068         ModuleDescriptor descriptor2_v1 = newBuilder("m2")

1069                 .version("1.0")
1070                 .build();
1071 
1072         ModuleDescriptor descriptor2_v2 = newBuilder("m2")

1073                 .version("2.0")
1074                 .build();
1075 
1076         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2_v1);
1077         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor2_v2);
1078 
1079         Configuration cf = resolve(finder1, finder2, "m1");
1080 
1081         assertTrue(cf.modules().size() == 2);
1082         assertTrue(cf.findModule("m1").isPresent());
1083         assertTrue(cf.findModule("m2").isPresent());
1084 
1085         ResolvedModule m1 = cf.findModule("m1").get();
1086         ResolvedModule m2 = cf.findModule("m2").get();
1087 
1088         assertEquals(m1.reference().descriptor(), descriptor1);
1089         assertEquals(m2.reference().descriptor(), descriptor2_v1);
1090     }
1091 
1092 
1093     /**
1094      * Basic test with two modules finders and service binding.
1095      *
1096      * The before and after ModuleFinders both locate a service provider module
1097      * named "m2" that provide implementations of the same service type.
1098      */
1099     public void testWithTwoFinders2() {
1100 
1101         ModuleDescriptor descriptor1 = newBuilder("m1")

1102                 .exports("p")
1103                 .uses("p.S")
1104                 .build();
1105 
1106         ModuleDescriptor descriptor2_v1 = newBuilder("m2")

1107                 .requires("m1")
1108                 .provides("p.S", List.of("q.T"))

1109                 .build();
1110 
1111         ModuleDescriptor descriptor2_v2 = newBuilder("m2")

1112                 .requires("m1")
1113                 .provides("p.S", List.of("q.T"))

1114                 .build();
1115 
1116         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2_v1);
1117         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2_v2);
1118 
1119         Configuration cf = resolveAndBind(finder1, finder2, "m1");
1120 
1121         assertTrue(cf.modules().size() == 2);
1122         assertTrue(cf.findModule("m1").isPresent());
1123         assertTrue(cf.findModule("m2").isPresent());
1124 
1125         ResolvedModule m1 = cf.findModule("m1").get();
1126         ResolvedModule m2 = cf.findModule("m2").get();
1127 
1128         assertEquals(m1.reference().descriptor(), descriptor1);
1129         assertEquals(m2.reference().descriptor(), descriptor2_v1);
1130     }
1131 
1132 
1133     /**
1134      * Basic test for resolving a module that is located in the parent
1135      * configuration.
1136      */
1137     public void testResolvedInParent1() {
1138 
1139         ModuleDescriptor descriptor1 = newBuilder("m1")

1140                 .build();
1141 
1142         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1143 
1144         Configuration cf1 = resolve(finder, "m1");
1145 
1146         assertTrue(cf1.modules().size() == 1);
1147         assertTrue(cf1.findModule("m1").isPresent());
1148 
1149         Configuration cf2 = resolve(cf1, finder, "m1");
1150 
1151         assertTrue(cf2.modules().size() == 1);
1152     }
1153 
1154 
1155     /**
1156      * Basic test for resolving a module that has a dependency on a module
1157      * in the parent configuration.
1158      */
1159     public void testResolvedInParent2() {
1160 
1161         ModuleDescriptor descriptor1 = newBuilder("m1").build();


1162 
1163         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
1164 
1165         Configuration cf1 = resolve(finder1, "m1");
1166 
1167         assertTrue(cf1.modules().size() == 1);
1168         assertTrue(cf1.findModule("m1").isPresent());
1169 
1170 
1171         ModuleDescriptor descriptor2 = newBuilder("m2")

1172                 .requires("m1")
1173                 .build();
1174 
1175         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
1176 
1177         Configuration cf2 = resolve(cf1, ModuleFinder.of(), finder2, "m2");
1178 
1179         assertTrue(cf2.modules().size() == 1);
1180         assertTrue(cf2.findModule("m2").isPresent());
1181 
1182         ResolvedModule m1 = cf2.findModule("m1").get();   // find in parent
1183         ResolvedModule m2 = cf2.findModule("m2").get();
1184 
1185         assertTrue(m1.reads().size() == 0);
1186         assertTrue(m2.reads().size() == 1);
1187         assertTrue(m2.reads().contains(m1));
1188     }
1189 
1190 
1191     /**
1192      * Basic test of resolving a module that depends on modules in two parent
1193      * configurations.
1194      *
1195      * The test consists of three configurations:
1196      * - Configuration cf1: m1
1197      * - Configuration cf2: m2
1198      * - Configuration cf3(cf1,cf2): m3 requires m1, m2
1199      */
1200     public void testResolvedInMultipleParents1() {
1201 
1202         // Configuration cf1: m1
1203         ModuleDescriptor descriptor1 = newBuilder("m1").build();
1204         Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
1205         assertEquals(cf1.parents(), List.of(Configuration.empty()));
1206         assertTrue(cf1.findModule("m1").isPresent());
1207         ResolvedModule m1 = cf1.findModule("m1").get();
1208         assertTrue(m1.configuration() == cf1);
1209 
1210         // Configuration cf2: m2
1211         ModuleDescriptor descriptor2 = newBuilder("m2").build();
1212         Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2");
1213         assertEquals(cf2.parents(), List.of(Configuration.empty()));
1214         assertTrue(cf2.findModule("m2").isPresent());
1215         ResolvedModule m2 = cf2.findModule("m2").get();
1216         assertTrue(m2.configuration() == cf2);
1217 
1218         // Configuration cf3(cf1,cf2): m3 requires m1 and m2
1219         ModuleDescriptor descriptor3 = newBuilder("m3")

1220                 .requires("m1")
1221                 .requires("m2")
1222                 .build();
1223         ModuleFinder finder = ModuleUtils.finderOf(descriptor3);
1224         Configuration cf3 = Configuration.resolve(
1225                 finder,
1226                 List.of(cf1, cf2),  // parents
1227                 ModuleFinder.of(),
1228                 Set.of("m3"));
1229         assertEquals(cf3.parents(), List.of(cf1, cf2));
1230         assertTrue(cf3.findModule("m3").isPresent());
1231         ResolvedModule m3 = cf3.findModule("m3").get();
1232         assertTrue(m3.configuration() == cf3);
1233 
1234         // check readability
1235         assertTrue(m1.reads().isEmpty());
1236         assertTrue(m2.reads().isEmpty());
1237         assertEquals(m3.reads(), Set.of(m1, m2));
1238     }
1239 
1240 
1241     /**
1242      * Basic test of resolving a module that depends on modules in three parent
1243      * configurations arranged in a diamond (two direct parents).
1244      *
1245      * The test consists of four configurations:
1246      * - Configuration cf1: m1
1247      * - Configuration cf2(cf1): m2 requires m1
1248      * - Configuration cf3(cf3): m3 requires m1
1249      * - Configuration cf4(cf2,cf3): m4 requires m1,m2,m3
1250      */
1251     public void testResolvedInMultipleParents2() {
1252         // Configuration cf1: m1
1253         ModuleDescriptor descriptor1 = newBuilder("m1").build();
1254         Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
1255         assertEquals(cf1.parents(), List.of(Configuration.empty()));
1256         assertTrue(cf1.findModule("m1").isPresent());
1257         ResolvedModule m1 = cf1.findModule("m1").get();
1258         assertTrue(m1.configuration() == cf1);
1259 
1260         // Configuration cf2(cf1): m2 requires m1
1261         ModuleDescriptor descriptor2 = newBuilder("m2")

1262                 .requires("m1")
1263                 .build();
1264         Configuration cf2 = Configuration.resolve(
1265                 ModuleUtils.finderOf(descriptor2),
1266                 List.of(cf1),  // parents
1267                 ModuleFinder.of(),
1268                 Set.of("m2"));
1269         assertEquals(cf2.parents(), List.of(cf1));
1270         assertTrue(cf2.findModule("m2").isPresent());
1271         ResolvedModule m2 = cf2.findModule("m2").get();
1272         assertTrue(m2.configuration() == cf2);
1273 
1274         // Configuration cf3(cf1): m3 requires m1
1275         ModuleDescriptor descriptor3 = newBuilder("m3")

1276                 .requires("m1")
1277                 .build();
1278         Configuration cf3 = Configuration.resolve(
1279                 ModuleUtils.finderOf(descriptor3),
1280                 List.of(cf1),  // parents
1281                 ModuleFinder.of(),
1282                 Set.of("m3"));
1283         assertEquals(cf3.parents(), List.of(cf1));
1284         assertTrue(cf3.findModule("m3").isPresent());
1285         ResolvedModule m3 = cf3.findModule("m3").get();
1286         assertTrue(m3.configuration() == cf3);
1287 
1288         // Configuration cf4(cf2,cf3): m4 requires m1,m2,m3
1289         ModuleDescriptor descriptor4 = newBuilder("m4")

1290                 .requires("m1")
1291                 .requires("m2")
1292                 .requires("m3")
1293                 .build();
1294         Configuration cf4 = Configuration.resolve(
1295                 ModuleUtils.finderOf(descriptor4),
1296                 List.of(cf2, cf3),  // parents
1297                 ModuleFinder.of(),
1298                 Set.of("m4"));
1299         assertEquals(cf4.parents(), List.of(cf2, cf3));
1300         assertTrue(cf4.findModule("m4").isPresent());
1301         ResolvedModule m4 = cf4.findModule("m4").get();
1302         assertTrue(m4.configuration() == cf4);
1303 
1304         // check readability
1305         assertTrue(m1.reads().isEmpty());
1306         assertEquals(m2.reads(), Set.of(m1));
1307         assertEquals(m3.reads(), Set.of(m1));
1308         assertEquals(m4.reads(), Set.of(m1, m2, m3));
1309     }
1310 
1311 
1312     /**
1313      * Basic test of resolving a module that depends on modules in three parent
1314      * configurations arranged in a diamond (two direct parents).
1315      *
1316      * The test consists of four configurations:
1317      * - Configuration cf1: m1@1
1318      * - Configuration cf2: m1@2, m2@2
1319      * - Configuration cf3: m1@3, m2@3, m3@3
1320      * - Configuration cf4(cf1,cf2,cf3): m4 requires m1,m2,m3
1321      */
1322     public void testResolvedInMultipleParents3() {
1323         ModuleDescriptor descriptor1, descriptor2, descriptor3;
1324 
1325         // Configuration cf1: m1@1
1326         descriptor1 = newBuilder("m1").version("1").build();
1327         Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
1328         assertEquals(cf1.parents(), List.of(Configuration.empty()));
1329 
1330         // Configuration cf2: m1@2, m2@2
1331         descriptor1 = newBuilder("m1").version("2").build();
1332         descriptor2 = newBuilder("m2").version("2").build();
1333         Configuration cf2 = resolve(
1334                 ModuleUtils.finderOf(descriptor1, descriptor2),
1335                 "m1", "m2");
1336         assertEquals(cf2.parents(), List.of(Configuration.empty()));
1337 
1338         // Configuration cf3: m1@3, m2@3, m3@3
1339         descriptor1 = newBuilder("m1").version("3").build();
1340         descriptor2 = newBuilder("m2").version("3").build();
1341         descriptor3 = newBuilder("m3").version("3").build();
1342         Configuration cf3 = resolve(
1343                 ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3),
1344                 "m1", "m2", "m3");
1345         assertEquals(cf3.parents(), List.of(Configuration.empty()));
1346 
1347         // Configuration cf4(cf1,cf2,cf3): m4 requires m1,m2,m3
1348         ModuleDescriptor descriptor4 = newBuilder("m4")

1349                 .requires("m1")
1350                 .requires("m2")
1351                 .requires("m3")
1352                 .build();
1353         Configuration cf4 = Configuration.resolve(
1354                 ModuleUtils.finderOf(descriptor4),
1355                 List.of(cf1, cf2, cf3),  // parents
1356                 ModuleFinder.of(),
1357                 Set.of("m4"));
1358         assertEquals(cf4.parents(), List.of(cf1, cf2, cf3));
1359 
1360         assertTrue(cf1.findModule("m1").isPresent());
1361         assertTrue(cf2.findModule("m1").isPresent());
1362         assertTrue(cf2.findModule("m2").isPresent());
1363         assertTrue(cf3.findModule("m1").isPresent());
1364         assertTrue(cf3.findModule("m2").isPresent());
1365         assertTrue(cf3.findModule("m3").isPresent());
1366         assertTrue(cf4.findModule("m4").isPresent());
1367 
1368         ResolvedModule m1_1 = cf1.findModule("m1").get();
1369         ResolvedModule m1_2 = cf2.findModule("m1").get();
1370         ResolvedModule m2_2 = cf2.findModule("m2").get();
1371         ResolvedModule m1_3 = cf3.findModule("m1").get();
1372         ResolvedModule m2_3 = cf3.findModule("m2").get();
1373         ResolvedModule m3_3 = cf3.findModule("m3").get();


1380         assertTrue(m2_3.configuration() == cf3);
1381         assertTrue(m3_3.configuration() == cf3);
1382         assertTrue(m4.configuration() == cf4);
1383 
1384         // check readability
1385         assertTrue(m1_1.reads().isEmpty());
1386         assertTrue(m1_2.reads().isEmpty());
1387         assertTrue(m2_2.reads().isEmpty());
1388         assertTrue(m1_3.reads().isEmpty());
1389         assertTrue(m2_3.reads().isEmpty());
1390         assertTrue(m3_3.reads().isEmpty());
1391         assertEquals(m4.reads(), Set.of(m1_1, m2_2, m3_3));
1392     }
1393 
1394 
1395     /**
1396      * Basic test of using the beforeFinder to override a module in a parent
1397      * configuration.
1398      */
1399     public void testOverriding1() {
1400         ModuleDescriptor descriptor1 = newBuilder("m1").build();


1401 
1402         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1403 
1404         Configuration cf1 = resolve(finder, "m1");
1405         assertTrue(cf1.modules().size() == 1);
1406         assertTrue(cf1.findModule("m1").isPresent());
1407 
1408         Configuration cf2 = resolve(cf1, finder, "m1");
1409         assertTrue(cf2.modules().size() == 1);
1410         assertTrue(cf2.findModule("m1").isPresent());
1411     }
1412 
1413     /**
1414      * Basic test of using the beforeFinder to override a module in a parent
1415      * configuration.
1416      */
1417     public void testOverriding2() {
1418         ModuleDescriptor descriptor1 = newBuilder("m1").build();
1419         Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
1420         assertTrue(cf1.modules().size() == 1);
1421         assertTrue(cf1.findModule("m1").isPresent());
1422 
1423         ModuleDescriptor descriptor2 = newBuilder("m2").build();
1424         Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2");
1425         assertTrue(cf2.modules().size() == 1);
1426         assertTrue(cf2.findModule("m2").isPresent());
1427 
1428         ModuleDescriptor descriptor3 = newBuilder("m3").build();
1429         Configuration cf3 = resolve(ModuleUtils.finderOf(descriptor3), "m3");
1430         assertTrue(cf3.modules().size() == 1);
1431         assertTrue(cf3.findModule("m3").isPresent());
1432 
1433         // override m2, m1 and m3 should be found in parent configurations
1434         ModuleFinder finder = ModuleUtils.finderOf(descriptor2);
1435         Configuration cf4 = Configuration.resolve(
1436                 finder,
1437                 List.of(cf1, cf2, cf3),
1438                 ModuleFinder.of(),
1439                 Set.of("m1", "m2", "m3"));
1440         assertTrue(cf4.modules().size() == 1);
1441         assertTrue(cf4.findModule("m2").isPresent());
1442         ResolvedModule m2 = cf4.findModule("m2").get();
1443         assertTrue(m2.configuration() == cf4);
1444     }
1445 
1446 
1447     /**
1448      * Basic test of using the beforeFinder to override a module in the parent
1449      * configuration but where implied readability in the picture so that the
1450      * module in the parent is read.
1451      *
1452      * The test consists of two configurations:
1453      * - Configuration cf1: m1, m2 requires transitive m1
1454      * - Configuration cf2: m1, m3 requires m2
1455      */
1456     public void testOverriding3() {
1457 
1458         ModuleDescriptor descriptor1 = newBuilder("m1")

1459                 .build();
1460 
1461         ModuleDescriptor descriptor2 = newBuilder("m2")

1462                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
1463                 .build();
1464 
1465         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
1466 
1467         Configuration cf1 = resolve(finder1, "m2");
1468 
1469         assertTrue(cf1.modules().size() == 2);
1470         assertTrue(cf1.findModule("m1").isPresent());
1471         assertTrue(cf1.findModule("m2").isPresent());
1472 
1473         // cf2: m3 requires m2, m1
1474 
1475         ModuleDescriptor descriptor3 = newBuilder("m3")

1476                 .requires("m2")
1477                 .build();
1478 
1479         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
1480 
1481         Configuration cf2 = resolve(cf1, finder2, "m1", "m3");
1482 
1483         assertTrue(cf2.parents().size() == 1);
1484         assertTrue(cf2.parents().get(0) == cf1);
1485 
1486         assertTrue(cf2.modules().size() == 2);
1487         assertTrue(cf2.findModule("m1").isPresent());
1488         assertTrue(cf2.findModule("m3").isPresent());
1489 
1490         ResolvedModule m1_1 = cf1.findModule("m1").get();
1491         ResolvedModule m1_2 = cf2.findModule("m1").get();
1492         ResolvedModule m2 = cf1.findModule("m2").get();
1493         ResolvedModule m3 = cf2.findModule("m3").get();
1494 
1495         assertTrue(m1_1.configuration() == cf1);
1496         assertTrue(m1_2.configuration() == cf2);
1497         assertTrue(m3.configuration() == cf2);
1498 
1499 
1500         // check that m3 reads cf1/m1 and cf2/m2
1501         assertTrue(m3.reads().size() == 2);
1502         assertTrue(m3.reads().contains(m1_1));
1503         assertTrue(m3.reads().contains(m2));
1504     }
1505 
1506 
1507     /**
1508      * Root module not found
1509      */
1510     @Test(expectedExceptions = { FindException.class })
1511     public void testRootNotFound() {
1512         resolve(ModuleFinder.of(), "m1");
1513     }
1514 
1515 
1516     /**
1517      * Direct dependency not found
1518      */
1519     @Test(expectedExceptions = { FindException.class })
1520     public void testDirectDependencyNotFound() {
1521         ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();

1522         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1523         resolve(finder, "m1");
1524     }
1525 
1526 
1527     /**
1528      * Transitive dependency not found
1529      */
1530     @Test(expectedExceptions = { FindException.class })
1531     public void testTransitiveDependencyNotFound() {
1532         ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();
1533         ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build();


1534         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1535         resolve(finder, "m1");
1536     }
1537 
1538 
1539     /**
1540      * Service provider dependency not found
1541      */
1542     @Test(expectedExceptions = { FindException.class })
1543     public void testServiceProviderDependencyNotFound() {
1544 
1545         // service provider dependency (on m3) not found
1546 
1547         ModuleDescriptor descriptor1 = newBuilder("m1")

1548                 .exports("p")
1549                 .uses("p.S")
1550                 .build();
1551 
1552         ModuleDescriptor descriptor2 = newBuilder("m2")

1553                 .requires("m1")
1554                 .requires("m3")
1555                 .provides("p.S", List.of("q.T"))

1556                 .build();
1557 
1558         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1559 
1560         // should throw ResolutionException because m3 is not found
1561         Configuration cf = resolveAndBind(finder, "m1");
1562     }
1563 
1564 
1565     /**
1566      * Simple cycle.
1567      */
1568     @Test(expectedExceptions = { ResolutionException.class })
1569     public void testSimpleCycle() {
1570         ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();
1571         ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build();
1572         ModuleDescriptor descriptor3 = newBuilder("m3").requires("m1").build();



1573         ModuleFinder finder
1574             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
1575         resolve(finder, "m1");
1576     }
1577 
1578     /**
1579      * Basic test for detecting cycles involving a service provider module
1580      */
1581     @Test(expectedExceptions = { ResolutionException.class })
1582     public void testCycleInProvider() {
1583 
1584         ModuleDescriptor descriptor1 = newBuilder("m1")

1585                 .exports("p")
1586                 .uses("p.S")
1587                 .build();
1588         ModuleDescriptor descriptor2 = newBuilder("m2")

1589                 .requires("m1")
1590                 .requires("m3")
1591                 .provides("p.S", List.of("q.T"))

1592                 .build();
1593         ModuleDescriptor descriptor3 = newBuilder("m3")

1594                 .requires("m2")
1595                 .build();
1596 
1597         ModuleFinder finder
1598             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
1599 
1600         // should throw ResolutionException because of the m2 <--> m3 cycle
1601         resolveAndBind(finder, "m1");
1602     }
1603 
1604 
1605     /**
1606      * Test two modules exporting package p to a module that reads both.
1607      */
1608     @Test(expectedExceptions = { ResolutionException.class })
1609     public void testPackageSuppliedByTwoOthers() {
1610 
1611         ModuleDescriptor descriptor1 = newBuilder("m1")

1612                 .requires("m2")
1613                 .requires("m3")
1614                 .build();
1615 
1616         ModuleDescriptor descriptor2 = newBuilder("m2")

1617                 .exports("p")
1618                 .build();
1619 
1620         ModuleDescriptor descriptor3 = newBuilder("m3")

1621                 .exports("p", Set.of("m1"))
1622                 .build();
1623 
1624         ModuleFinder finder
1625             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
1626 
1627         // m2 and m3 export package p to module m1
1628         resolve(finder, "m1");
1629     }
1630 
1631 
1632     /**
1633      * Test the scenario where a module contains a package p and reads
1634      * a module that exports package p.
1635      */
1636     @Test(expectedExceptions = { ResolutionException.class })
1637     public void testPackageSuppliedBySelfAndOther() {
1638 
1639         ModuleDescriptor descriptor1 = newBuilder("m1")

1640                 .requires("m2")
1641                 .packages(Set.of("p"))
1642                 .build();
1643 
1644         ModuleDescriptor descriptor2 = newBuilder("m2")

1645                 .exports("p")
1646                 .build();
1647 
1648         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1649 
1650         // m1 contains package p, module m2 exports package p to m1
1651         resolve(finder, "m1");
1652     }
1653 
1654 
1655     /**
1656      * Test the scenario where a module contains a package p and reads
1657      * a module that also contains a package p.
1658      */
1659     public void testContainsPackageInSelfAndOther() {
1660         ModuleDescriptor descriptor1 = newBuilder("m1")

1661                 .requires("m2")
1662                 .packages(Set.of("p"))
1663                 .build();
1664 
1665         ModuleDescriptor descriptor2 = newBuilder("m2")
1666                 .packages(Set.of("p"))

1667                 .build();
1668 
1669         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1670 
1671         Configuration cf = resolve(finder, "m1");
1672 
1673         assertTrue(cf.modules().size() == 2);
1674         assertTrue(cf.findModule("m1").isPresent());
1675         assertTrue(cf.findModule("m2").isPresent());
1676 
1677         // m1 reads m2, m2 reads nothing
1678         ResolvedModule m1 = cf.findModule("m1").get();
1679         ResolvedModule m2 = cf.findModule("m2").get();
1680         assertTrue(m1.reads().size() == 1);
1681         assertTrue(m1.reads().contains(m2));
1682         assertTrue(m2.reads().size() == 0);
1683     }
1684 
1685 
1686     /**
1687      * Test the scenario where a module that exports a package that is also
1688      * exported by a module that it reads in a parent layer.
1689      */
1690     @Test(expectedExceptions = { ResolutionException.class })
1691     public void testExportSamePackageAsBootLayer() {
1692         ModuleDescriptor descriptor = newBuilder("m1")

1693                 .requires("java.base")
1694                 .exports("java.lang")
1695                 .build();
1696 
1697         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
1698 
1699         Configuration bootConfiguration = Layer.boot().configuration();
1700 
1701         // m1 contains package java.lang, java.base exports package java.lang to m1
1702         resolve(bootConfiguration, finder, "m1");
1703     }
1704 
1705 
1706     /**
1707      * Test "uses p.S" where p is contained in the same module.
1708      */
1709     public void testContainsService1() {
1710         ModuleDescriptor descriptor1 = newBuilder("m1")
1711                 .packages(Set.of("p"))

1712                 .uses("p.S")
1713                 .build();
1714 
1715         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1716 
1717         Configuration cf = resolve(finder, "m1");
1718 
1719         assertTrue(cf.modules().size() == 1);
1720         assertTrue(cf.findModule("m1").isPresent());
1721     }
1722 
1723 
1724     /**
1725      * Test "uses p.S" where p is contained in a different module.
1726      */
1727     @Test(expectedExceptions = { ResolutionException.class })
1728     public void testContainsService2() {
1729         ModuleDescriptor descriptor1 = newBuilder("m1")
1730                 .packages(Set.of("p"))

1731                 .build();
1732 
1733         ModuleDescriptor descriptor2 = newBuilder("m2")

1734                 .requires("m1")
1735                 .uses("p.S")
1736                 .build();
1737 
1738         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1739 
1740         // m2 does not read a module that exports p
1741         resolve(finder, "m2");
1742     }
1743 
1744 
1745     /**
1746      * Test "provides p.S" where p is contained in the same module.
1747      */
1748     public void testContainsService3() {
1749         ModuleDescriptor descriptor1 = newBuilder("m1")
1750                 .packages(Set.of("p", "q"))
1751                 .provides("p.S", List.of("q.S1"))


1752                 .build();
1753 
1754         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1755 
1756         Configuration cf = resolve(finder, "m1");
1757 
1758         assertTrue(cf.modules().size() == 1);
1759         assertTrue(cf.findModule("m1").isPresent());
1760     }
1761 
1762 
1763     /**
1764      * Test "provides p.S" where p is contained in a different module.
1765      */
1766     @Test(expectedExceptions = { ResolutionException.class })
1767     public void testContainsService4() {
1768         ModuleDescriptor descriptor1 = newBuilder("m1")
1769                 .packages(Set.of("p"))

1770                 .build();
1771 
1772         ModuleDescriptor descriptor2 = newBuilder("m2")

1773                 .requires("m1")
1774                 .provides("p.S", List.of("q.S1"))

1775                 .build();
1776 
1777         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1778 
1779         // m2 does not read a module that exports p
1780         resolve(finder, "m2");
1781     }
1782 
1783 
1784     /**
1785      * Test "uses p.S" where p is not exported to the module.
1786      */
1787     @Test(expectedExceptions = { ResolutionException.class })
1788     public void testServiceTypePackageNotExported1() {
1789         ModuleDescriptor descriptor1 = newBuilder("m1")

1790                 .uses("p.S")
1791                 .build();
1792 
1793         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1794 
1795         // m1 does not read a module that exports p
1796         resolve(finder, "m1");
1797     }
1798 
1799 
1800     /**
1801      * Test "provides p.S" where p is not exported to the module.
1802      */
1803     @Test(expectedExceptions = { ResolutionException.class })
1804     public void testServiceTypePackageNotExported2() {
1805         ModuleDescriptor descriptor1 = newBuilder("m1")
1806                 .provides("p.S", List.of("q.T"))


1807                 .build();
1808 
1809         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
1810 
1811         // m1 does not read a module that exports p
1812         resolve(finder, "m1");
























1813     }
1814 
1815 
1816     /**
1817      * Test the empty configuration.
1818      */
1819     public void testEmptyConfiguration() {
1820         Configuration cf = Configuration.empty();
1821 
1822         assertTrue(cf.parents().isEmpty());
1823 
1824         assertTrue(cf.modules().isEmpty());
1825         assertFalse(cf.findModule("java.base").isPresent());
1826     }
1827 
1828 
1829     // platform specific modules
1830 
1831     @DataProvider(name = "platformmatch")
1832     public Object[][] createPlatformMatches() {


1856         };
1857 
1858     };
1859 
1860     @DataProvider(name = "platformmismatch")
1861     public Object[][] createBad() {
1862         return new Object[][] {
1863 
1864             { "linux-*-*",        "solaris-*-*"   },
1865             { "linux-x86-*",      "linux-arm-*"   },
1866             { "linux-*-2.4",      "linux-x86-2.6" },
1867         };
1868     }
1869 
1870     /**
1871      * Test creating a configuration containing platform specific modules.
1872      */
1873     @Test(dataProvider = "platformmatch")
1874     public void testPlatformMatch(String s1, String s2) {
1875 
1876         Builder builder = newBuilder("m1").requires("m2");
1877         addPlatformConstraints(builder, s1);









1878         ModuleDescriptor descriptor1 = builder.build();
1879 
1880         builder = newBuilder("m2");
1881         addPlatformConstraints(builder, s2);








1882         ModuleDescriptor descriptor2 = builder.build();
1883 
1884         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
1885 
1886         Configuration cf = resolve(finder, "m1");
1887 
1888         assertTrue(cf.modules().size() == 2);
1889         assertTrue(cf.findModule("m1").isPresent());
1890         assertTrue(cf.findModule("m2").isPresent());
1891     }
1892 
1893     /**
1894      * Test attempting to create a configuration with modules for different
1895      * platforms.
1896      */
1897     @Test(dataProvider = "platformmismatch",
1898           expectedExceptions = FindException.class )
1899     public void testPlatformMisMatch(String s1, String s2) {
1900         testPlatformMatch(s1, s2);
1901     }
1902 
1903 
1904     // no parents
1905 
1906     @Test(expectedExceptions = { IllegalArgumentException.class })
1907     public void testResolveRequiresWithNoParents() {
1908         ModuleFinder empty = ModuleFinder.of();
1909         Configuration.resolve(empty, List.of(), empty, Set.of());
1910     }
1911 
1912     @Test(expectedExceptions = { IllegalArgumentException.class })
1913     public void testResolveRequiresAndUsesWithNoParents() {
1914         ModuleFinder empty = ModuleFinder.of();
1915         Configuration.resolveAndBind(empty, List.of(), empty, Set.of());
1916     }
1917 
1918 
1919     // parents with modules for specific platforms
1920 
1921     @Test(dataProvider = "platformmatch")
1922     public void testResolveRequiresWithCompatibleParents(String s1, String s2) {
1923         Builder builder = newBuilder("m1");
1924         addPlatformConstraints(builder, s1);
1925         ModuleDescriptor descriptor1 = builder.build();
1926 
1927         builder = newBuilder("m2");
1928         addPlatformConstraints(builder, s2);
1929         ModuleDescriptor descriptor2 = builder.build();
1930 
1931         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
1932         Configuration cf1 = resolve(finder1, "m1");
1933 
1934         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
1935         Configuration cf2 = resolve(finder2, "m2");
1936 
1937         Configuration cf3 = Configuration.resolve(ModuleFinder.of(),
1938                                                   List.of(cf1, cf2),
1939                                                   ModuleFinder.of(),
1940                                                   Set.of());
1941         assertTrue(cf3.parents().size() == 2);
1942     }
1943 
1944     @Test(dataProvider = "platformmismatch",
1945           expectedExceptions = IllegalArgumentException.class )
1946     public void testResolveRequiresWithConflictingParents(String s1, String s2) {
1947         Builder builder = newBuilder("m1");
1948         addPlatformConstraints(builder, s1);
1949         ModuleDescriptor descriptor1 = builder.build();
1950 
1951         builder = newBuilder("m2");
1952         addPlatformConstraints(builder, s2);
1953         ModuleDescriptor descriptor2 = builder.build();
1954 
1955         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
1956         Configuration cf1 = resolve(finder1, "m1");
1957 
1958         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
1959         Configuration cf2 = resolve(finder2, "m2");
1960 
1961         // should throw IAE
1962         Configuration.resolve(ModuleFinder.of(),
1963                               List.of(cf1, cf2),
1964                               ModuleFinder.of(),
1965                               Set.of());
1966     }
1967 
1968 
1969 
1970     // null handling
1971 
1972     // finder1, finder2, roots
1973 
1974 
1975     @Test(expectedExceptions = { NullPointerException.class })
1976     public void testResolveRequiresWithNull1() {
1977         resolve((ModuleFinder)null, ModuleFinder.of());
1978     }
1979 
1980     @Test(expectedExceptions = { NullPointerException.class })
1981     public void testResolveRequiresWithNull2() {
1982         resolve(ModuleFinder.of(), (ModuleFinder)null);
1983     }
1984 
1985     @Test(expectedExceptions = { NullPointerException.class })
1986     public void testResolveRequiresWithNull3() {
1987         Configuration empty = Configuration.empty();
1988         Configuration.resolve(null, List.of(empty),  ModuleFinder.of(), Set.of());
1989     }
1990 
1991     @Test(expectedExceptions = { NullPointerException.class })
1992     public void testResolveRequiresWithNull4() {
1993         ModuleFinder empty = ModuleFinder.of();
1994         Configuration.resolve(empty, null, empty, Set.of());
1995     }
1996 
1997     @Test(expectedExceptions = { NullPointerException.class })
1998     public void testResolveRequiresWithNull5() {
1999         Configuration cf = Layer.boot().configuration();
2000         Configuration.resolve(ModuleFinder.of(), List.of(cf), null, Set.of());
2001     }
2002 
2003     @Test(expectedExceptions = { NullPointerException.class })
2004     public void testResolveRequiresWithNull6() {
2005         ModuleFinder empty = ModuleFinder.of();
2006         Configuration cf = Layer.boot().configuration();
2007         Configuration.resolve(empty, List.of(cf), empty, null);
2008     }
2009 
2010     @Test(expectedExceptions = { NullPointerException.class })
2011     public void testResolveRequiresAndUsesWithNull1() {
2012         resolveAndBind((ModuleFinder) null, ModuleFinder.of());
2013     }
2014 
2015     @Test(expectedExceptions = { NullPointerException.class })
2016     public void testResolveRequiresAndUsesWithNull2() {
2017         resolveAndBind(ModuleFinder.of(), (ModuleFinder) null);
2018     }
2019 
2020     @Test(expectedExceptions = { NullPointerException.class })
2021     public void testResolveRequiresAndUsesWithNull3() {
2022         Configuration empty = Configuration.empty();
2023         Configuration.resolveAndBind(null, List.of(empty), ModuleFinder.of(), Set.of());
2024     }
2025 
2026     @Test(expectedExceptions = { NullPointerException.class })
2027     public void testResolveRequiresAndUsesWithNull4() {
2028         ModuleFinder empty = ModuleFinder.of();
2029         Configuration.resolveAndBind(empty, null, empty, Set.of());
2030     }
2031 
2032     @Test(expectedExceptions = { NullPointerException.class })
2033     public void testResolveRequiresAndUsesWithNull5() {
2034         Configuration cf = Layer.boot().configuration();
2035         Configuration.resolveAndBind(ModuleFinder.of(), List.of(cf), null, Set.of());
2036     }
2037 
2038     @Test(expectedExceptions = { NullPointerException.class })
2039     public void testResolveRequiresAndUsesWithNull6() {
2040         ModuleFinder empty = ModuleFinder.of();
2041         Configuration cf = Layer.boot().configuration();
2042         Configuration.resolveAndBind(empty, List.of(cf), empty, null);
2043     }
2044 
2045     @Test(expectedExceptions = { NullPointerException.class })
2046     public void testFindModuleWithNull() {
2047         Configuration.empty().findModule(null);
2048     }
2049 
2050     // immutable sets
2051 
2052     @Test(expectedExceptions = { UnsupportedOperationException.class })
2053     public void testImmutableSet1() {
2054         Configuration cf = Layer.boot().configuration();
2055         ResolvedModule base = cf.findModule("java.base").get();
2056         cf.modules().add(base);
2057     }
2058 
2059     @Test(expectedExceptions = { UnsupportedOperationException.class })
2060     public void testImmutableSet2() {
2061         Configuration cf = Layer.boot().configuration();
2062         ResolvedModule base = cf.findModule("java.base").get();
2063         base.reads().add(base);
2064     }
2065 
2066 
2067     /**
2068      * Invokes parent.resolve(...)
2069      */
2070     private Configuration resolve(Configuration parent,
2071                                   ModuleFinder before,
2072                                   ModuleFinder after,
2073                                   String... roots) {
2074         return parent.resolve(before, after, Set.of(roots));
2075     }
2076 
2077     private Configuration resolve(Configuration parent,
2078                                   ModuleFinder before,
2079                                   String... roots) {
2080         return resolve(parent, before, ModuleFinder.of(), roots);
2081     }
2082 
2083     private Configuration resolve(ModuleFinder before,
2084                                   ModuleFinder after,
2085                                   String... roots) {
2086         return resolve(Configuration.empty(), before, after, roots);
2087     }
2088 
2089     private Configuration resolve(ModuleFinder before,
2090                                   String... roots) {
2091         return resolve(Configuration.empty(), before, roots);
2092     }
2093 
2094 
2095     /**
2096      * Invokes parent.resolveAndBind(...)
2097      */
2098     private Configuration resolveAndBind(Configuration parent,
2099                                          ModuleFinder before,
2100                                          ModuleFinder after,
2101                                          String... roots) {
2102         return parent.resolveAndBind(before, after, Set.of(roots));
2103     }
2104 
2105     private Configuration resolveAndBind(Configuration parent,
2106                                          ModuleFinder before,
2107                                          String... roots) {
2108         return resolveAndBind(parent, before, ModuleFinder.of(), roots);
2109     }
2110 
2111     private Configuration resolveAndBind(ModuleFinder before,
2112                                          ModuleFinder after,
2113                                          String... roots) {
2114         return resolveAndBind(Configuration.empty(), before, after, roots);
2115     }
2116 
2117     private Configuration resolveAndBind(ModuleFinder before,
2118                                          String... roots) {
2119         return resolveAndBind(Configuration.empty(), before, roots);
2120     }
2121 
2122 
2123     /**
2124      * Returns {@code true} if the configuration contains module mn1
2125      * that reads module mn2.
2126      */
2127     static boolean reads(Configuration cf, String mn1, String mn2) {
2128         Optional<ResolvedModule> om1 = cf.findModule(mn1);
2129         if (!om1.isPresent())
2130             return false;
2131 
2132         return om1.get().reads().stream()
2133                 .map(ResolvedModule::name)
2134                 .anyMatch(mn2::equals);
2135     }
2136 
2137     /**
2138      * Decodes the platform string and calls the builder osName/osArch/osVersion
2139      * methods to set the platform constraints.
2140      */
2141     static void addPlatformConstraints(Builder builder, String platformString) {
2142         String[] s = platformString.split("-");
2143         if (!s[0].equals("*"))
2144             builder.osName(s[0]);
2145         if (!s[1].equals("*"))
2146             builder.osArch(s[1]);
2147         if (!s[2].equals("*"))
2148             builder.osVersion(s[2]);
2149     }
2150 }
< prev index next >