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 } |