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(); 1374 ResolvedModule m4 = cf4.findModule("m4").get(); 1375 1376 assertTrue(m1_1.configuration() == cf1); 1377 assertTrue(m1_2.configuration() == cf2); 1378 assertTrue(m2_2.configuration() == cf2); 1379 assertTrue(m1_3.configuration() == cf3); 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() { 1833 return new Object[][]{ 1834 1835 { "linux-*-*", "*-*-*" }, 1836 { "*-arm-*", "*-*-*" }, 1837 { "*-*-2.6", "*-*-*" }, 1838 1839 { "linux-arm-*", "*-*-*" }, 1840 { "linux-*-2.6", "*-*-*" }, 1841 { "*-arm-2.6", "*-*-*" }, 1842 1843 { "linux-arm-2.6", "*-*-*" }, 1844 1845 { "linux-*-*", "linux-*-*" }, 1846 { "*-arm-*", "*-arm-*" }, 1847 { "*-*-2.6", "*-*-2.6" }, 1848 1849 { "linux-arm-*", "linux-arm-*" }, 1850 { "linux-arm-*", "linux-*-*" }, 1851 { "linux-*-2.6", "linux-*-2.6" }, 1852 { "linux-*-2.6", "linux-arm-*" }, 1853 1854 { "linux-arm-2.6", "linux-arm-2.6" }, 1855 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 }