1 /* 2 * Copyright (c) 2014, 2023, 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 * @enablePreview 27 * @modules java.base/jdk.internal.access 28 * java.base/jdk.internal.module 29 * @library /test/lib 30 * @build ConfigurationTest 31 * jdk.test.lib.util.ModuleInfoWriter 32 * jdk.test.lib.util.ModuleUtils 33 * @run testng ConfigurationTest 34 * @summary Basic tests for java.lang.module.Configuration 35 */ 36 37 import java.io.IOException; 38 import java.io.OutputStream; 39 import java.lang.module.Configuration; 40 import java.lang.module.FindException; 41 import java.lang.module.ModuleDescriptor; 42 import java.lang.module.ModuleDescriptor.Requires; 43 import java.lang.module.ModuleFinder; 44 import java.lang.module.ResolutionException; 45 import java.lang.module.ResolvedModule; 46 import java.nio.file.Files; 47 import java.nio.file.Path; 48 import java.nio.file.Paths; 49 import java.util.List; 50 import java.util.Set; 51 52 import jdk.test.lib.util.ModuleInfoWriter; 53 import jdk.test.lib.util.ModuleUtils; 54 55 import jdk.internal.access.SharedSecrets; 56 import jdk.internal.module.ModuleTarget; 57 import org.testng.annotations.DataProvider; 58 import org.testng.annotations.Test; 59 import static org.testng.Assert.*; 60 61 @Test 62 public class ConfigurationTest { 63 64 /** 65 * Creates a "non-strict" builder for building a module. This allows the 66 * test the create ModuleDescriptor objects that do not require java.base. 67 */ 68 private static ModuleDescriptor.Builder newBuilder(String mn) { 69 return SharedSecrets.getJavaLangModuleAccess() 70 .newModuleBuilder(mn, false, Set.of()); 71 } 72 73 /** 74 * Basic test of resolver 75 * m1 requires m2, m2 requires m3 76 */ 77 public void testBasic() { 78 ModuleDescriptor descriptor1 = newBuilder("m1") 79 .requires("m2") 80 .build(); 81 82 ModuleDescriptor descriptor2 = newBuilder("m2") 83 .requires("m3") 84 .build(); 85 86 ModuleDescriptor descriptor3 = newBuilder("m3") 87 .build(); 88 89 ModuleFinder finder 90 = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); 91 92 Configuration cf = resolve(finder, "m1"); 93 94 assertTrue(cf.modules().size() == 3); 95 96 assertTrue(cf.findModule("m1").isPresent()); 97 assertTrue(cf.findModule("m2").isPresent()); 98 assertTrue(cf.findModule("m3").isPresent()); 99 100 assertTrue(cf.parents().size() == 1); 101 assertTrue(cf.parents().get(0) == Configuration.empty()); 102 103 ResolvedModule m1 = cf.findModule("m1").get(); 104 ResolvedModule m2 = cf.findModule("m2").get(); 105 ResolvedModule m3 = cf.findModule("m3").get(); 106 107 // m1 reads m2 108 assertTrue(m1.reads().size() == 1); 109 assertTrue(m1.reads().contains(m2)); 110 111 // m2 reads m3 112 assertTrue(m2.reads().size() == 1); 113 assertTrue(m2.reads().contains(m3)); 114 115 // m3 reads nothing 116 assertTrue(m3.reads().size() == 0); 117 118 // toString 119 assertTrue(cf.toString().contains("m1")); 120 assertTrue(cf.toString().contains("m2")); 121 assertTrue(cf.toString().contains("m3")); 122 } 123 124 125 /** 126 * Basic test of "requires transitive": 127 * m1 requires m2, m2 requires transitive m3 128 */ 129 public void testRequiresTransitive1() { 130 // m1 requires m2, m2 requires transitive m3 131 ModuleDescriptor descriptor1 = newBuilder("m1") 132 .requires("m2") 133 .build(); 134 135 ModuleDescriptor descriptor2 = newBuilder("m2") 136 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m3") 137 .build(); 138 139 ModuleDescriptor descriptor3 = newBuilder("m3") 140 .build(); 141 142 ModuleFinder finder 143 = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); 144 145 Configuration cf = resolve(finder, "m1"); 146 147 assertTrue(cf.modules().size() == 3); 148 149 assertTrue(cf.findModule("m1").isPresent()); 150 assertTrue(cf.findModule("m2").isPresent()); 151 assertTrue(cf.findModule("m3").isPresent()); 152 153 assertTrue(cf.parents().size() == 1); 154 assertTrue(cf.parents().get(0) == Configuration.empty()); 155 156 ResolvedModule m1 = cf.findModule("m1").get(); 157 ResolvedModule m2 = cf.findModule("m2").get(); 158 ResolvedModule m3 = cf.findModule("m3").get(); 159 160 // m1 reads m2 and m3 161 assertTrue(m1.reads().size() == 2); 162 assertTrue(m1.reads().contains(m2)); 163 assertTrue(m1.reads().contains(m3)); 164 165 // m2 reads m3 166 assertTrue(m2.reads().size() == 1); 167 assertTrue(m2.reads().contains(m3)); 168 169 // m3 reads nothing 170 assertTrue(m3.reads().size() == 0); 171 } 172 173 174 /** 175 * Basic test of "requires transitive" with configurations. 176 * 177 * The test consists of three configurations: 178 * - Configuration cf1: m1, m2 requires transitive m1 179 * - Configuration cf2: m3 requires m2 180 */ 181 public void testRequiresTransitive2() { 182 183 // cf1: m1 and m2, m2 requires transitive m1 184 185 ModuleDescriptor descriptor1 = newBuilder("m1") 186 .build(); 187 188 ModuleDescriptor descriptor2 = newBuilder("m2") 189 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") 190 .build(); 191 192 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); 193 194 Configuration cf1 = resolve(finder1, "m2"); 195 196 assertTrue(cf1.modules().size() == 2); 197 assertTrue(cf1.findModule("m1").isPresent()); 198 assertTrue(cf1.findModule("m2").isPresent()); 199 assertTrue(cf1.parents().size() == 1); 200 assertTrue(cf1.parents().get(0) == Configuration.empty()); 201 202 ResolvedModule m1 = cf1.findModule("m1").get(); 203 ResolvedModule m2 = cf1.findModule("m2").get(); 204 205 assertTrue(m1.reads().size() == 0); 206 assertTrue(m2.reads().size() == 1); 207 assertTrue(m2.reads().contains(m1)); 208 209 210 // cf2: m3, m3 requires m2 211 212 ModuleDescriptor descriptor3 = newBuilder("m3") 213 .requires("m2") 214 .build(); 215 216 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3); 217 218 Configuration cf2 = resolve(cf1, finder2, "m3"); 219 220 assertTrue(cf2.modules().size() == 1); 221 assertTrue(cf2.findModule("m1").isPresent()); // in parent 222 assertTrue(cf2.findModule("m2").isPresent()); // in parent 223 assertTrue(cf2.findModule("m3").isPresent()); 224 assertTrue(cf2.parents().size() == 1); 225 assertTrue(cf2.parents().get(0) == cf1); 226 227 ResolvedModule m3 = cf2.findModule("m3").get(); 228 assertTrue(m3.configuration() == cf2); 229 assertTrue(m3.reads().size() == 2); 230 assertTrue(m3.reads().contains(m1)); 231 assertTrue(m3.reads().contains(m2)); 232 } 233 234 235 /** 236 * Basic test of "requires transitive" with configurations. 237 * 238 * The test consists of three configurations: 239 * - Configuration cf1: m1 240 * - Configuration cf2: m2 requires transitive m1, m3 requires m2 241 */ 242 public void testRequiresTransitive3() { 243 244 // cf1: m1 245 246 ModuleDescriptor descriptor1 = newBuilder("m1").build(); 247 248 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); 249 250 Configuration cf1 = resolve(finder1, "m1"); 251 252 assertTrue(cf1.modules().size() == 1); 253 assertTrue(cf1.findModule("m1").isPresent()); 254 assertTrue(cf1.parents().size() == 1); 255 assertTrue(cf1.parents().get(0) == Configuration.empty()); 256 257 ResolvedModule m1 = cf1.findModule("m1").get(); 258 assertTrue(m1.reads().size() == 0); 259 260 261 // cf2: m2, m3: m2 requires transitive m1, m3 requires m2 262 263 ModuleDescriptor descriptor2 = newBuilder("m2") 264 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") 265 .build(); 266 267 ModuleDescriptor descriptor3 = newBuilder("m3") 268 .requires("m2") 269 .build(); 270 271 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3); 272 273 Configuration cf2 = resolve(cf1, finder2, "m3"); 274 275 assertTrue(cf2.modules().size() == 2); 276 assertTrue(cf2.findModule("m1").isPresent()); // in parent 277 assertTrue(cf2.findModule("m2").isPresent()); 278 assertTrue(cf2.findModule("m3").isPresent()); 279 assertTrue(cf2.parents().size() == 1); 280 assertTrue(cf2.parents().get(0) == cf1); 281 282 ResolvedModule m2 = cf2.findModule("m2").get(); 283 ResolvedModule m3 = cf2.findModule("m3").get(); 284 285 assertTrue(m2.configuration() == cf2); 286 assertTrue(m2.reads().size() == 1); 287 assertTrue(m2.reads().contains(m1)); 288 289 assertTrue(m3.configuration() == cf2); 290 assertTrue(m3.reads().size() == 2); 291 assertTrue(m3.reads().contains(m1)); 292 assertTrue(m3.reads().contains(m2)); 293 } 294 295 296 /** 297 * Basic test of "requires transitive" with configurations. 298 * 299 * The test consists of three configurations: 300 * - Configuration cf1: m1 301 * - Configuration cf2: m2 requires transitive m1 302 * - Configuraiton cf3: m3 requires m2 303 */ 304 public void testRequiresTransitive4() { 305 306 // cf1: m1 307 308 ModuleDescriptor descriptor1 = newBuilder("m1").build(); 309 310 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); 311 312 Configuration cf1 = resolve(finder1, "m1"); 313 314 assertTrue(cf1.modules().size() == 1); 315 assertTrue(cf1.findModule("m1").isPresent()); 316 assertTrue(cf1.parents().size() == 1); 317 assertTrue(cf1.parents().get(0) == Configuration.empty()); 318 319 ResolvedModule m1 = cf1.findModule("m1").get(); 320 assertTrue(m1.reads().size() == 0); 321 322 323 // cf2: m2 requires transitive m1 324 325 ModuleDescriptor descriptor2 = newBuilder("m2") 326 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") 327 .build(); 328 329 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); 330 331 Configuration cf2 = resolve(cf1, finder2, "m2"); 332 333 assertTrue(cf2.modules().size() == 1); 334 assertTrue(cf2.findModule("m1").isPresent()); // in parent 335 assertTrue(cf2.findModule("m2").isPresent()); 336 assertTrue(cf2.parents().size() == 1); 337 assertTrue(cf2.parents().get(0) == cf1); 338 339 ResolvedModule m2 = cf2.findModule("m2").get(); 340 341 assertTrue(m2.configuration() == cf2); 342 assertTrue(m2.reads().size() == 1); 343 assertTrue(m2.reads().contains(m1)); 344 345 346 // cf3: m3 requires m2 347 348 ModuleDescriptor descriptor3 = newBuilder("m3") 349 .requires("m2") 350 .build(); 351 352 ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3); 353 354 Configuration cf3 = resolve(cf2, finder3, "m3"); 355 356 assertTrue(cf3.modules().size() == 1); 357 assertTrue(cf3.findModule("m1").isPresent()); // in parent 358 assertTrue(cf3.findModule("m2").isPresent()); // in parent 359 assertTrue(cf3.findModule("m3").isPresent()); 360 assertTrue(cf3.parents().size() == 1); 361 assertTrue(cf3.parents().get(0) == cf2); 362 363 ResolvedModule m3 = cf3.findModule("m3").get(); 364 365 assertTrue(m3.configuration() == cf3); 366 assertTrue(m3.reads().size() == 2); 367 assertTrue(m3.reads().contains(m1)); 368 assertTrue(m3.reads().contains(m2)); 369 } 370 371 372 /** 373 * Basic test of "requires transitive" with configurations. 374 * 375 * The test consists of two configurations: 376 * - Configuration cf1: m1, m2 requires transitive m1 377 * - Configuration cf2: m3 requires transitive m2, m4 requires m3 378 */ 379 public void testRequiresTransitive5() { 380 381 // cf1: m1, m2 requires transitive m1 382 383 ModuleDescriptor descriptor1 = newBuilder("m1") 384 .build(); 385 386 ModuleDescriptor descriptor2 = newBuilder("m2") 387 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") 388 .build(); 389 390 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); 391 392 Configuration cf1 = resolve(finder1, "m2"); 393 394 assertTrue(cf1.modules().size() == 2); 395 assertTrue(cf1.findModule("m1").isPresent()); 396 assertTrue(cf1.findModule("m2").isPresent()); 397 assertTrue(cf1.parents().size() == 1); 398 assertTrue(cf1.parents().get(0) == Configuration.empty()); 399 400 ResolvedModule m1 = cf1.findModule("m1").get(); 401 ResolvedModule m2 = cf1.findModule("m2").get(); 402 403 assertTrue(m1.configuration() == cf1); 404 assertTrue(m1.reads().size() == 0); 405 406 assertTrue(m2.configuration() == cf1); 407 assertTrue(m2.reads().size() == 1); 408 assertTrue(m2.reads().contains(m1)); 409 410 411 // cf2: m3 requires transitive m2, m4 requires m3 412 413 ModuleDescriptor descriptor3 = newBuilder("m3") 414 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m2") 415 .build(); 416 417 ModuleDescriptor descriptor4 = newBuilder("m4") 418 .requires("m3") 419 .build(); 420 421 422 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4); 423 424 Configuration cf2 = resolve(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 static": 452 * m1 requires static m2 453 * m2 is not observable 454 * resolve m1 455 */ 456 public void testRequiresStatic1() { 457 ModuleDescriptor descriptor1 = newBuilder("m1") 458 .requires(Set.of(Requires.Modifier.STATIC), "m2") 459 .build(); 460 461 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); 462 463 Configuration cf = resolve(finder, "m1"); 464 465 assertTrue(cf.modules().size() == 1); 466 467 ResolvedModule m1 = cf.findModule("m1").get(); 468 assertTrue(m1.reads().size() == 0); 469 } 470 471 472 /** 473 * Basic test of "requires static": 474 * m1 requires static m2 475 * m2 476 * resolve m1 477 */ 478 public void testRequiresStatic2() { 479 ModuleDescriptor descriptor1 = newBuilder("m1") 480 .requires(Set.of(Requires.Modifier.STATIC), "m2") 481 .build(); 482 483 ModuleDescriptor descriptor2 = newBuilder("m2") 484 .build(); 485 486 ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); 487 488 Configuration cf = resolve(finder, "m1"); 489 490 assertTrue(cf.modules().size() == 1); 491 492 ResolvedModule m1 = cf.findModule("m1").get(); 493 assertTrue(m1.reads().size() == 0); 494 } 495 496 497 /** 498 * Basic test of "requires static": 499 * m1 requires static m2 500 * m2 501 * resolve m1, m2 502 */ 503 public void testRequiresStatic3() { 504 ModuleDescriptor descriptor1 = newBuilder("m1") 505 .requires(Set.of(Requires.Modifier.STATIC), "m2") 506 .build(); 507 508 ModuleDescriptor descriptor2 = newBuilder("m2") 509 .build(); 510 511 ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); 512 513 Configuration cf = resolve(finder, "m1", "m2"); 514 515 assertTrue(cf.modules().size() == 2); 516 517 ResolvedModule m1 = cf.findModule("m1").get(); 518 ResolvedModule m2 = cf.findModule("m2").get(); 519 520 assertTrue(m1.reads().size() == 1); 521 assertTrue(m1.reads().contains(m2)); 522 523 assertTrue(m2.reads().size() == 0); 524 } 525 526 527 /** 528 * Basic test of "requires static": 529 * m1 requires m2, m3 530 * m2 requires static m2 531 * m3 532 */ 533 public void testRequiresStatic4() { 534 ModuleDescriptor descriptor1 = newBuilder("m1") 535 .requires("m2") 536 .requires("m3") 537 .build(); 538 539 ModuleDescriptor descriptor2 = newBuilder("m2") 540 .requires(Set.of(Requires.Modifier.STATIC), "m3") 541 .build(); 542 543 ModuleDescriptor descriptor3 = newBuilder("m3") 544 .build(); 545 546 ModuleFinder finder 547 = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); 548 549 Configuration cf = resolve(finder, "m1"); 550 551 assertTrue(cf.modules().size() == 3); 552 553 ResolvedModule m1 = cf.findModule("m1").get(); 554 ResolvedModule m2 = cf.findModule("m2").get(); 555 ResolvedModule m3 = cf.findModule("m3").get(); 556 557 assertTrue(m1.reads().size() == 2); 558 assertTrue(m1.reads().contains(m2)); 559 assertTrue(m1.reads().contains(m3)); 560 561 assertTrue(m2.reads().size() == 1); 562 assertTrue(m2.reads().contains(m3)); 563 564 assertTrue(m3.reads().size() == 0); 565 } 566 567 568 /** 569 * Basic test of "requires static": 570 * The test consists of three configurations: 571 * - Configuration cf1: m1, m2 572 * - Configuration cf2: m3 requires m1, requires static m2 573 */ 574 public void testRequiresStatic5() { 575 ModuleDescriptor descriptor1 = newBuilder("m1") 576 .build(); 577 578 ModuleDescriptor descriptor2 = newBuilder("m2") 579 .build(); 580 581 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); 582 583 Configuration cf1 = resolve(finder1, "m1", "m2"); 584 585 assertTrue(cf1.modules().size() == 2); 586 assertTrue(cf1.findModule("m1").isPresent()); 587 assertTrue(cf1.findModule("m2").isPresent()); 588 589 ModuleDescriptor descriptor3 = newBuilder("m3") 590 .requires("m1") 591 .requires(Set.of(Requires.Modifier.STATIC), "m2") 592 .build(); 593 594 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3); 595 596 Configuration cf2 = resolve(cf1, finder2, "m3"); 597 598 assertTrue(cf2.modules().size() == 1); 599 assertTrue(cf2.findModule("m3").isPresent()); 600 601 ResolvedModule m1 = cf1.findModule("m1").get(); 602 ResolvedModule m2 = cf1.findModule("m2").get(); 603 ResolvedModule m3 = cf2.findModule("m3").get(); 604 605 assertTrue(m3.reads().size() == 2); 606 assertTrue(m3.reads().contains(m1)); 607 assertTrue(m3.reads().contains(m2)); 608 } 609 610 611 /** 612 * Basic test of "requires static": 613 * The test consists of three configurations: 614 * - Configuration cf1: m1 615 * - Configuration cf2: m3 requires m1, requires static m2 616 */ 617 public void testRequiresStatic6() { 618 ModuleDescriptor descriptor1 = newBuilder("m1") 619 .build(); 620 621 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); 622 623 Configuration cf1 = resolve(finder1, "m1"); 624 625 assertTrue(cf1.modules().size() == 1); 626 assertTrue(cf1.findModule("m1").isPresent()); 627 628 ModuleDescriptor descriptor3 = newBuilder("m3") 629 .requires("m1") 630 .requires(Set.of(Requires.Modifier.STATIC), "m2") 631 .build(); 632 633 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3); 634 635 Configuration cf2 = resolve(cf1, finder2, "m3"); 636 637 assertTrue(cf2.modules().size() == 1); 638 assertTrue(cf2.findModule("m3").isPresent()); 639 640 ResolvedModule m1 = cf1.findModule("m1").get(); 641 ResolvedModule m3 = cf2.findModule("m3").get(); 642 643 assertTrue(m3.reads().size() == 1); 644 assertTrue(m3.reads().contains(m1)); 645 } 646 647 648 /** 649 * Basic test of "requires static": 650 * (m1 not observable) 651 * m2 requires transitive static m1 652 * m3 requires m2 653 */ 654 public void testRequiresStatic7() { 655 ModuleDescriptor descriptor1 = null; // not observable 656 657 ModuleDescriptor descriptor2 = newBuilder("m2") 658 .requires(Set.of(Requires.Modifier.TRANSITIVE, 659 Requires.Modifier.STATIC), 660 "m1") 661 .build(); 662 663 ModuleDescriptor descriptor3 = newBuilder("m3") 664 .requires("m2") 665 .build(); 666 667 ModuleFinder finder = ModuleUtils.finderOf(descriptor2, descriptor3); 668 669 Configuration cf = resolve(finder, "m3"); 670 671 assertTrue(cf.modules().size() == 2); 672 assertTrue(cf.findModule("m2").isPresent()); 673 assertTrue(cf.findModule("m3").isPresent()); 674 ResolvedModule m2 = cf.findModule("m2").get(); 675 ResolvedModule m3 = cf.findModule("m3").get(); 676 assertTrue(m2.reads().isEmpty()); 677 assertTrue(m3.reads().size() == 1); 678 assertTrue(m3.reads().contains(m2)); 679 } 680 681 682 /** 683 * Basic test of "requires static": 684 * - Configuration cf1: m2 requires transitive static m1 685 * - Configuration cf2: m3 requires m2 686 */ 687 public void testRequiresStatic8() { 688 ModuleDescriptor descriptor1 = null; // not observable 689 690 ModuleDescriptor descriptor2 = newBuilder("m2") 691 .requires(Set.of(Requires.Modifier.TRANSITIVE, 692 Requires.Modifier.STATIC), 693 "m1") 694 .build(); 695 696 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2); 697 698 Configuration cf1 = resolve(finder1, "m2"); 699 700 assertTrue(cf1.modules().size() == 1); 701 assertTrue(cf1.findModule("m2").isPresent()); 702 ResolvedModule m2 = cf1.findModule("m2").get(); 703 assertTrue(m2.reads().isEmpty()); 704 705 ModuleDescriptor descriptor3 = newBuilder("m3") 706 .requires("m2") 707 .build(); 708 709 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3); 710 711 Configuration cf2 = resolve(cf1, finder2, "m3"); 712 713 assertTrue(cf2.modules().size() == 1); 714 assertTrue(cf2.findModule("m3").isPresent()); 715 ResolvedModule m3 = cf2.findModule("m3").get(); 716 assertTrue(m3.reads().size() == 1); 717 assertTrue(m3.reads().contains(m2)); 718 } 719 720 721 /** 722 * Basic test of binding services 723 * m1 uses p.S 724 * m2 provides p.S 725 */ 726 public void testServiceBinding1() { 727 728 ModuleDescriptor descriptor1 = newBuilder("m1") 729 .exports("p") 730 .uses("p.S") 731 .build(); 732 733 ModuleDescriptor descriptor2 = newBuilder("m2") 734 .requires("m1") 735 .provides("p.S", List.of("q.T")) 736 .build(); 737 738 ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); 739 740 Configuration cf = resolveAndBind(finder, "m1"); 741 742 assertTrue(cf.modules().size() == 2); 743 assertTrue(cf.findModule("m1").isPresent()); 744 assertTrue(cf.findModule("m2").isPresent()); 745 assertTrue(cf.parents().size() == 1); 746 assertTrue(cf.parents().get(0) == Configuration.empty()); 747 748 ResolvedModule m1 = cf.findModule("m1").get(); 749 ResolvedModule m2 = cf.findModule("m2").get(); 750 751 assertTrue(m1.configuration() == cf); 752 assertTrue(m1.reads().size() == 0); 753 754 assertTrue(m2.configuration() == cf); 755 assertTrue(m2.reads().size() == 1); 756 assertTrue(m2.reads().contains(m1)); 757 } 758 759 760 /** 761 * Basic test of binding services 762 * m1 uses p.S1 763 * m2 provides p.S1, m2 uses p.S2 764 * m3 provides p.S2 765 */ 766 public void testServiceBinding2() { 767 768 ModuleDescriptor descriptor1 = newBuilder("m1") 769 .exports("p") 770 .uses("p.S1") 771 .build(); 772 773 ModuleDescriptor descriptor2 = newBuilder("m2") 774 .requires("m1") 775 .uses("p.S2") 776 .provides("p.S1", List.of("q.Service1Impl")) 777 .build(); 778 779 ModuleDescriptor descriptor3 = newBuilder("m3") 780 .requires("m1") 781 .provides("p.S2", List.of("q.Service2Impl")) 782 .build(); 783 784 ModuleFinder finder 785 = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); 786 787 Configuration cf = resolveAndBind(finder, "m1"); 788 789 assertTrue(cf.modules().size() == 3); 790 assertTrue(cf.findModule("m1").isPresent()); 791 assertTrue(cf.findModule("m2").isPresent()); 792 assertTrue(cf.findModule("m3").isPresent()); 793 assertTrue(cf.parents().size() == 1); 794 assertTrue(cf.parents().get(0) == Configuration.empty()); 795 796 ResolvedModule m1 = cf.findModule("m1").get(); 797 ResolvedModule m2 = cf.findModule("m2").get(); 798 ResolvedModule m3 = cf.findModule("m3").get(); 799 800 assertTrue(m1.configuration() == cf); 801 assertTrue(m1.reads().size() == 0); 802 803 assertTrue(m2.configuration() == cf); 804 assertTrue(m2.reads().size() == 1); 805 assertTrue(m2.reads().contains(m1)); 806 807 assertTrue(m3.configuration() == cf); 808 assertTrue(m3.reads().size() == 1); 809 assertTrue(m3.reads().contains(m1)); 810 } 811 812 813 /** 814 * Basic test of binding services with configurations. 815 * 816 * The test consists of two configurations: 817 * - Configuration cf1: m1 uses p.S 818 * - Configuration cf2: m2 provides p.S 819 */ 820 public void testServiceBindingWithConfigurations1() { 821 822 ModuleDescriptor descriptor1 = newBuilder("m1") 823 .exports("p") 824 .uses("p.S") 825 .build(); 826 827 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); 828 829 Configuration cf1 = resolve(finder1, "m1"); 830 831 assertTrue(cf1.modules().size() == 1); 832 assertTrue(cf1.findModule("m1").isPresent()); 833 834 ModuleDescriptor descriptor2 = newBuilder("m2") 835 .requires("m1") 836 .provides("p.S", List.of("q.T")) 837 .build(); 838 839 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); 840 841 Configuration cf2 = resolveAndBind(cf1, finder2); // no roots 842 843 assertTrue(cf2.parents().size() == 1); 844 assertTrue(cf2.parents().get(0) == cf1); 845 846 assertTrue(cf2.modules().size() == 1); 847 assertTrue(cf2.findModule("m2").isPresent()); 848 849 ResolvedModule m1 = cf1.findModule("m1").get(); 850 ResolvedModule m2 = cf2.findModule("m2").get(); 851 852 assertTrue(m2.reads().size() == 1); 853 assertTrue(m2.reads().contains(m1)); 854 } 855 856 857 /** 858 * Basic test of binding services with configurations. 859 * 860 * The test consists of two configurations: 861 * - Configuration cf1: m1 uses p.S && provides p.S, 862 * m2 provides p.S 863 * - Configuration cf2: m3 provides p.S 864 * m4 provides p.S 865 */ 866 public void testServiceBindingWithConfigurations2() { 867 868 ModuleDescriptor descriptor1 = newBuilder("m1") 869 .exports("p") 870 .uses("p.S") 871 .provides("p.S", List.of("p1.ServiceImpl")) 872 .build(); 873 874 ModuleDescriptor descriptor2 = newBuilder("m2") 875 .requires("m1") 876 .provides("p.S", List.of("p2.ServiceImpl")) 877 .build(); 878 879 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); 880 881 Configuration cf1 = resolveAndBind(finder1, "m1"); 882 883 assertTrue(cf1.modules().size() == 2); 884 assertTrue(cf1.findModule("m1").isPresent()); 885 assertTrue(cf1.findModule("m2").isPresent()); 886 887 888 ModuleDescriptor descriptor3 = newBuilder("m3") 889 .requires("m1") 890 .provides("p.S", List.of("p3.ServiceImpl")) 891 .build(); 892 893 ModuleDescriptor descriptor4 = newBuilder("m4") 894 .requires("m1") 895 .provides("p.S", List.of("p4.ServiceImpl")) 896 .build(); 897 898 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4); 899 900 Configuration cf2 = resolveAndBind(cf1, finder2); // no roots 901 902 assertTrue(cf2.parents().size() == 1); 903 assertTrue(cf2.parents().get(0) == cf1); 904 905 assertTrue(cf2.modules().size() == 2); 906 assertTrue(cf2.findModule("m3").isPresent()); 907 assertTrue(cf2.findModule("m4").isPresent()); 908 909 ResolvedModule m1 = cf2.findModule("m1").get(); // should find in parent 910 ResolvedModule m2 = cf2.findModule("m2").get(); 911 ResolvedModule m3 = cf2.findModule("m3").get(); 912 ResolvedModule m4 = cf2.findModule("m4").get(); 913 914 assertTrue(m1.reads().size() == 0); 915 916 assertTrue(m2.reads().size() == 1); 917 assertTrue(m2.reads().contains(m1)); 918 919 assertTrue(m3.reads().size() == 1); 920 assertTrue(m3.reads().contains(m1)); 921 922 assertTrue(m4.reads().size() == 1); 923 assertTrue(m4.reads().contains(m1)); 924 } 925 926 927 /** 928 * Basic test of binding services with configurations. 929 * 930 * Configuration cf1: p@1.0 provides p.S 931 * Test configuration cf2: m1 uses p.S, p@2.0 provides p.S 932 * Test configuration cf2: m1 uses p.S 933 */ 934 public void testServiceBindingWithConfigurations3() { 935 936 ModuleDescriptor service = newBuilder("s") 937 .exports("p") 938 .build(); 939 940 ModuleDescriptor provider_v1 = newBuilder("p") 941 .version("1.0") 942 .requires("s") 943 .provides("p.S", List.of("q.T")) 944 .build(); 945 946 ModuleFinder finder1 = ModuleUtils.finderOf(service, provider_v1); 947 948 Configuration cf1 = resolve(finder1, "p"); 949 950 assertTrue(cf1.modules().size() == 2); 951 assertTrue(cf1.findModule("s").isPresent()); 952 assertTrue(cf1.findModule("p").isPresent()); 953 954 // p@1.0 in cf1 955 ResolvedModule p = cf1.findModule("p").get(); 956 assertEquals(p.reference().descriptor(), provider_v1); 957 958 959 ModuleDescriptor descriptor1 = newBuilder("m1") 960 .requires("s") 961 .uses("p.S") 962 .build(); 963 964 ModuleDescriptor provider_v2 = newBuilder("p") 965 .version("2.0") 966 .requires("s") 967 .provides("p.S", List.of("q.T")) 968 .build(); 969 970 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, provider_v2); 971 972 973 // finder2 is the before ModuleFinder and so p@2.0 should be located 974 975 Configuration cf2 = resolveAndBind(cf1, finder2, "m1"); 976 977 assertTrue(cf2.parents().size() == 1); 978 assertTrue(cf2.parents().get(0) == cf1); 979 assertTrue(cf2.modules().size() == 2); 980 981 // p should be found in cf2 982 p = cf2.findModule("p").get(); 983 assertTrue(p.configuration() == cf2); 984 assertEquals(p.reference().descriptor(), provider_v2); 985 986 987 // finder2 is the after ModuleFinder and so p@2.0 should not be located 988 // as module p is in parent configuration. 989 990 cf2 = resolveAndBind(cf1, ModuleFinder.of(), finder2, "m1"); 991 992 assertTrue(cf2.parents().size() == 1); 993 assertTrue(cf2.parents().get(0) == cf1); 994 assertTrue(cf2.modules().size() == 1); 995 996 // p should be found in cf1 997 p = cf2.findModule("p").get(); 998 assertTrue(p.configuration() == cf1); 999 assertEquals(p.reference().descriptor(), provider_v1); 1000 } 1001 1002 1003 /** 1004 * Basic test with two module finders. 1005 * 1006 * Module m2 can be found by both the before and after finders. 1007 */ 1008 public void testWithTwoFinders1() { 1009 1010 ModuleDescriptor descriptor1 = newBuilder("m1") 1011 .requires("m2") 1012 .build(); 1013 1014 ModuleDescriptor descriptor2_v1 = newBuilder("m2") 1015 .version("1.0") 1016 .build(); 1017 1018 ModuleDescriptor descriptor2_v2 = newBuilder("m2") 1019 .version("2.0") 1020 .build(); 1021 1022 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2_v1); 1023 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor2_v2); 1024 1025 Configuration cf = resolve(finder1, finder2, "m1"); 1026 1027 assertTrue(cf.modules().size() == 2); 1028 assertTrue(cf.findModule("m1").isPresent()); 1029 assertTrue(cf.findModule("m2").isPresent()); 1030 1031 ResolvedModule m1 = cf.findModule("m1").get(); 1032 ResolvedModule m2 = cf.findModule("m2").get(); 1033 1034 assertEquals(m1.reference().descriptor(), descriptor1); 1035 assertEquals(m2.reference().descriptor(), descriptor2_v1); 1036 } 1037 1038 1039 /** 1040 * Basic test with two modules finders and service binding. 1041 * 1042 * The before and after ModuleFinders both locate a service provider module 1043 * named "m2" that provide implementations of the same service type. 1044 */ 1045 public void testWithTwoFinders2() { 1046 1047 ModuleDescriptor descriptor1 = newBuilder("m1") 1048 .exports("p") 1049 .uses("p.S") 1050 .build(); 1051 1052 ModuleDescriptor descriptor2_v1 = newBuilder("m2") 1053 .requires("m1") 1054 .provides("p.S", List.of("q.T")) 1055 .build(); 1056 1057 ModuleDescriptor descriptor2_v2 = newBuilder("m2") 1058 .requires("m1") 1059 .provides("p.S", List.of("q.T")) 1060 .build(); 1061 1062 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2_v1); 1063 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2_v2); 1064 1065 Configuration cf = resolveAndBind(finder1, finder2, "m1"); 1066 1067 assertTrue(cf.modules().size() == 2); 1068 assertTrue(cf.findModule("m1").isPresent()); 1069 assertTrue(cf.findModule("m2").isPresent()); 1070 1071 ResolvedModule m1 = cf.findModule("m1").get(); 1072 ResolvedModule m2 = cf.findModule("m2").get(); 1073 1074 assertEquals(m1.reference().descriptor(), descriptor1); 1075 assertEquals(m2.reference().descriptor(), descriptor2_v1); 1076 } 1077 1078 1079 /** 1080 * Basic test for resolving a module that is located in the parent 1081 * configuration. 1082 */ 1083 public void testResolvedInParent1() { 1084 1085 ModuleDescriptor descriptor1 = newBuilder("m1") 1086 .build(); 1087 1088 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); 1089 1090 Configuration cf1 = resolve(finder, "m1"); 1091 1092 assertTrue(cf1.modules().size() == 1); 1093 assertTrue(cf1.findModule("m1").isPresent()); 1094 1095 Configuration cf2 = resolve(cf1, finder, "m1"); 1096 1097 assertTrue(cf2.modules().size() == 1); 1098 } 1099 1100 1101 /** 1102 * Basic test for resolving a module that has a dependency on a module 1103 * in the parent configuration. 1104 */ 1105 public void testResolvedInParent2() { 1106 1107 ModuleDescriptor descriptor1 = newBuilder("m1").build(); 1108 1109 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1); 1110 1111 Configuration cf1 = resolve(finder1, "m1"); 1112 1113 assertTrue(cf1.modules().size() == 1); 1114 assertTrue(cf1.findModule("m1").isPresent()); 1115 1116 1117 ModuleDescriptor descriptor2 = newBuilder("m2") 1118 .requires("m1") 1119 .build(); 1120 1121 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2); 1122 1123 Configuration cf2 = resolve(cf1, ModuleFinder.of(), finder2, "m2"); 1124 1125 assertTrue(cf2.modules().size() == 1); 1126 assertTrue(cf2.findModule("m2").isPresent()); 1127 1128 ResolvedModule m1 = cf2.findModule("m1").get(); // find in parent 1129 ResolvedModule m2 = cf2.findModule("m2").get(); 1130 1131 assertTrue(m1.reads().size() == 0); 1132 assertTrue(m2.reads().size() == 1); 1133 assertTrue(m2.reads().contains(m1)); 1134 } 1135 1136 1137 /** 1138 * Basic test of resolving a module that depends on modules in two parent 1139 * configurations. 1140 * 1141 * The test consists of three configurations: 1142 * - Configuration cf1: m1 1143 * - Configuration cf2: m2 1144 * - Configuration cf3(cf1,cf2): m3 requires m1, m2 1145 */ 1146 public void testResolvedInMultipleParents1() { 1147 1148 // Configuration cf1: m1 1149 ModuleDescriptor descriptor1 = newBuilder("m1").build(); 1150 Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1"); 1151 assertEquals(cf1.parents(), List.of(Configuration.empty())); 1152 assertTrue(cf1.findModule("m1").isPresent()); 1153 ResolvedModule m1 = cf1.findModule("m1").get(); 1154 assertTrue(m1.configuration() == cf1); 1155 1156 // Configuration cf2: m2 1157 ModuleDescriptor descriptor2 = newBuilder("m2").build(); 1158 Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2"); 1159 assertEquals(cf2.parents(), List.of(Configuration.empty())); 1160 assertTrue(cf2.findModule("m2").isPresent()); 1161 ResolvedModule m2 = cf2.findModule("m2").get(); 1162 assertTrue(m2.configuration() == cf2); 1163 1164 // Configuration cf3(cf1,cf2): m3 requires m1 and m2 1165 ModuleDescriptor descriptor3 = newBuilder("m3") 1166 .requires("m1") 1167 .requires("m2") 1168 .build(); 1169 ModuleFinder finder = ModuleUtils.finderOf(descriptor3); 1170 Configuration cf3 = Configuration.resolve( 1171 finder, 1172 List.of(cf1, cf2), // parents 1173 ModuleFinder.of(), 1174 Set.of("m3")); 1175 assertEquals(cf3.parents(), List.of(cf1, cf2)); 1176 assertTrue(cf3.findModule("m3").isPresent()); 1177 ResolvedModule m3 = cf3.findModule("m3").get(); 1178 assertTrue(m3.configuration() == cf3); 1179 1180 // check readability 1181 assertTrue(m1.reads().isEmpty()); 1182 assertTrue(m2.reads().isEmpty()); 1183 assertEquals(m3.reads(), Set.of(m1, m2)); 1184 } 1185 1186 1187 /** 1188 * Basic test of resolving a module that depends on modules in three parent 1189 * configurations arranged in a diamond (two direct parents). 1190 * 1191 * The test consists of four configurations: 1192 * - Configuration cf1: m1 1193 * - Configuration cf2(cf1): m2 requires m1 1194 * - Configuration cf3(cf3): m3 requires m1 1195 * - Configuration cf4(cf2,cf3): m4 requires m1,m2,m3 1196 */ 1197 public void testResolvedInMultipleParents2() { 1198 // Configuration cf1: m1 1199 ModuleDescriptor descriptor1 = newBuilder("m1").build(); 1200 Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1"); 1201 assertEquals(cf1.parents(), List.of(Configuration.empty())); 1202 assertTrue(cf1.findModule("m1").isPresent()); 1203 ResolvedModule m1 = cf1.findModule("m1").get(); 1204 assertTrue(m1.configuration() == cf1); 1205 1206 // Configuration cf2(cf1): m2 requires m1 1207 ModuleDescriptor descriptor2 = newBuilder("m2") 1208 .requires("m1") 1209 .build(); 1210 Configuration cf2 = Configuration.resolve( 1211 ModuleUtils.finderOf(descriptor2), 1212 List.of(cf1), // parents 1213 ModuleFinder.of(), 1214 Set.of("m2")); 1215 assertEquals(cf2.parents(), List.of(cf1)); 1216 assertTrue(cf2.findModule("m2").isPresent()); 1217 ResolvedModule m2 = cf2.findModule("m2").get(); 1218 assertTrue(m2.configuration() == cf2); 1219 1220 // Configuration cf3(cf1): m3 requires m1 1221 ModuleDescriptor descriptor3 = newBuilder("m3") 1222 .requires("m1") 1223 .build(); 1224 Configuration cf3 = Configuration.resolve( 1225 ModuleUtils.finderOf(descriptor3), 1226 List.of(cf1), // parents 1227 ModuleFinder.of(), 1228 Set.of("m3")); 1229 assertEquals(cf3.parents(), List.of(cf1)); 1230 assertTrue(cf3.findModule("m3").isPresent()); 1231 ResolvedModule m3 = cf3.findModule("m3").get(); 1232 assertTrue(m3.configuration() == cf3); 1233 1234 // Configuration cf4(cf2,cf3): m4 requires m1,m2,m3 1235 ModuleDescriptor descriptor4 = newBuilder("m4") 1236 .requires("m1") 1237 .requires("m2") 1238 .requires("m3") 1239 .build(); 1240 Configuration cf4 = Configuration.resolve( 1241 ModuleUtils.finderOf(descriptor4), 1242 List.of(cf2, cf3), // parents 1243 ModuleFinder.of(), 1244 Set.of("m4")); 1245 assertEquals(cf4.parents(), List.of(cf2, cf3)); 1246 assertTrue(cf4.findModule("m4").isPresent()); 1247 ResolvedModule m4 = cf4.findModule("m4").get(); 1248 assertTrue(m4.configuration() == cf4); 1249 1250 // check readability 1251 assertTrue(m1.reads().isEmpty()); 1252 assertEquals(m2.reads(), Set.of(m1)); 1253 assertEquals(m3.reads(), Set.of(m1)); 1254 assertEquals(m4.reads(), Set.of(m1, m2, m3)); 1255 } 1256 1257 1258 /** 1259 * Basic test of resolving a module that depends on modules in three parent 1260 * configurations arranged in a diamond (two direct parents). 1261 * 1262 * The test consists of four configurations: 1263 * - Configuration cf1: m1@1 1264 * - Configuration cf2: m1@2, m2@2 1265 * - Configuration cf3: m1@3, m2@3, m3@3 1266 * - Configuration cf4(cf1,cf2,cf3): m4 requires m1,m2,m3 1267 */ 1268 public void testResolvedInMultipleParents3() { 1269 ModuleDescriptor descriptor1, descriptor2, descriptor3; 1270 1271 // Configuration cf1: m1@1 1272 descriptor1 = newBuilder("m1").version("1").build(); 1273 Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1"); 1274 assertEquals(cf1.parents(), List.of(Configuration.empty())); 1275 1276 // Configuration cf2: m1@2, m2@2 1277 descriptor1 = newBuilder("m1").version("2").build(); 1278 descriptor2 = newBuilder("m2").version("2").build(); 1279 Configuration cf2 = resolve( 1280 ModuleUtils.finderOf(descriptor1, descriptor2), 1281 "m1", "m2"); 1282 assertEquals(cf2.parents(), List.of(Configuration.empty())); 1283 1284 // Configuration cf3: m1@3, m2@3, m3@3 1285 descriptor1 = newBuilder("m1").version("3").build(); 1286 descriptor2 = newBuilder("m2").version("3").build(); 1287 descriptor3 = newBuilder("m3").version("3").build(); 1288 Configuration cf3 = resolve( 1289 ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3), 1290 "m1", "m2", "m3"); 1291 assertEquals(cf3.parents(), List.of(Configuration.empty())); 1292 1293 // Configuration cf4(cf1,cf2,cf3): m4 requires m1,m2,m3 1294 ModuleDescriptor descriptor4 = newBuilder("m4") 1295 .requires("m1") 1296 .requires("m2") 1297 .requires("m3") 1298 .build(); 1299 Configuration cf4 = Configuration.resolve( 1300 ModuleUtils.finderOf(descriptor4), 1301 List.of(cf1, cf2, cf3), // parents 1302 ModuleFinder.of(), 1303 Set.of("m4")); 1304 assertEquals(cf4.parents(), List.of(cf1, cf2, cf3)); 1305 1306 assertTrue(cf1.findModule("m1").isPresent()); 1307 assertTrue(cf2.findModule("m1").isPresent()); 1308 assertTrue(cf2.findModule("m2").isPresent()); 1309 assertTrue(cf3.findModule("m1").isPresent()); 1310 assertTrue(cf3.findModule("m2").isPresent()); 1311 assertTrue(cf3.findModule("m3").isPresent()); 1312 assertTrue(cf4.findModule("m4").isPresent()); 1313 1314 ResolvedModule m1_1 = cf1.findModule("m1").get(); 1315 ResolvedModule m1_2 = cf2.findModule("m1").get(); 1316 ResolvedModule m2_2 = cf2.findModule("m2").get(); 1317 ResolvedModule m1_3 = cf3.findModule("m1").get(); 1318 ResolvedModule m2_3 = cf3.findModule("m2").get(); 1319 ResolvedModule m3_3 = cf3.findModule("m3").get(); 1320 ResolvedModule m4 = cf4.findModule("m4").get(); 1321 1322 assertTrue(m1_1.configuration() == cf1); 1323 assertTrue(m1_2.configuration() == cf2); 1324 assertTrue(m2_2.configuration() == cf2); 1325 assertTrue(m1_3.configuration() == cf3); 1326 assertTrue(m2_3.configuration() == cf3); 1327 assertTrue(m3_3.configuration() == cf3); 1328 assertTrue(m4.configuration() == cf4); 1329 1330 // check readability 1331 assertTrue(m1_1.reads().isEmpty()); 1332 assertTrue(m1_2.reads().isEmpty()); 1333 assertTrue(m2_2.reads().isEmpty()); 1334 assertTrue(m1_3.reads().isEmpty()); 1335 assertTrue(m2_3.reads().isEmpty()); 1336 assertTrue(m3_3.reads().isEmpty()); 1337 assertEquals(m4.reads(), Set.of(m1_1, m2_2, m3_3)); 1338 } 1339 1340 1341 /** 1342 * Basic test of using the beforeFinder to override a module in a parent 1343 * configuration. 1344 */ 1345 public void testOverriding1() { 1346 ModuleDescriptor descriptor1 = newBuilder("m1").build(); 1347 1348 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); 1349 1350 Configuration cf1 = resolve(finder, "m1"); 1351 assertTrue(cf1.modules().size() == 1); 1352 assertTrue(cf1.findModule("m1").isPresent()); 1353 1354 Configuration cf2 = resolve(cf1, finder, "m1"); 1355 assertTrue(cf2.modules().size() == 1); 1356 assertTrue(cf2.findModule("m1").isPresent()); 1357 } 1358 1359 /** 1360 * Basic test of using the beforeFinder to override a module in a parent 1361 * configuration. 1362 */ 1363 public void testOverriding2() { 1364 ModuleDescriptor descriptor1 = newBuilder("m1").build(); 1365 Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1"); 1366 assertTrue(cf1.modules().size() == 1); 1367 assertTrue(cf1.findModule("m1").isPresent()); 1368 1369 ModuleDescriptor descriptor2 = newBuilder("m2").build(); 1370 Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2"); 1371 assertTrue(cf2.modules().size() == 1); 1372 assertTrue(cf2.findModule("m2").isPresent()); 1373 1374 ModuleDescriptor descriptor3 = newBuilder("m3").build(); 1375 Configuration cf3 = resolve(ModuleUtils.finderOf(descriptor3), "m3"); 1376 assertTrue(cf3.modules().size() == 1); 1377 assertTrue(cf3.findModule("m3").isPresent()); 1378 1379 // override m2, m1 and m3 should be found in parent configurations 1380 ModuleFinder finder = ModuleUtils.finderOf(descriptor2); 1381 Configuration cf4 = Configuration.resolve( 1382 finder, 1383 List.of(cf1, cf2, cf3), 1384 ModuleFinder.of(), 1385 Set.of("m1", "m2", "m3")); 1386 assertTrue(cf4.modules().size() == 1); 1387 assertTrue(cf4.findModule("m2").isPresent()); 1388 ResolvedModule m2 = cf4.findModule("m2").get(); 1389 assertTrue(m2.configuration() == cf4); 1390 } 1391 1392 1393 /** 1394 * Basic test of using the beforeFinder to override a module in the parent 1395 * configuration but where implied readability in the picture so that the 1396 * module in the parent is read. 1397 * 1398 * The test consists of two configurations: 1399 * - Configuration cf1: m1, m2 requires transitive m1 1400 * - Configuration cf2: m1, m3 requires m2 1401 */ 1402 public void testOverriding3() { 1403 1404 ModuleDescriptor descriptor1 = newBuilder("m1") 1405 .build(); 1406 1407 ModuleDescriptor descriptor2 = newBuilder("m2") 1408 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") 1409 .build(); 1410 1411 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); 1412 1413 Configuration cf1 = resolve(finder1, "m2"); 1414 1415 assertTrue(cf1.modules().size() == 2); 1416 assertTrue(cf1.findModule("m1").isPresent()); 1417 assertTrue(cf1.findModule("m2").isPresent()); 1418 1419 // cf2: m3 requires m2, m1 1420 1421 ModuleDescriptor descriptor3 = newBuilder("m3") 1422 .requires("m2") 1423 .build(); 1424 1425 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3); 1426 1427 Configuration cf2 = resolve(cf1, finder2, "m1", "m3"); 1428 1429 assertTrue(cf2.parents().size() == 1); 1430 assertTrue(cf2.parents().get(0) == cf1); 1431 1432 assertTrue(cf2.modules().size() == 2); 1433 assertTrue(cf2.findModule("m1").isPresent()); 1434 assertTrue(cf2.findModule("m3").isPresent()); 1435 1436 ResolvedModule m1_1 = cf1.findModule("m1").get(); 1437 ResolvedModule m1_2 = cf2.findModule("m1").get(); 1438 ResolvedModule m2 = cf1.findModule("m2").get(); 1439 ResolvedModule m3 = cf2.findModule("m3").get(); 1440 1441 assertTrue(m1_1.configuration() == cf1); 1442 assertTrue(m1_2.configuration() == cf2); 1443 assertTrue(m3.configuration() == cf2); 1444 1445 1446 // check that m3 reads cf1/m1 and cf2/m2 1447 assertTrue(m3.reads().size() == 2); 1448 assertTrue(m3.reads().contains(m1_1)); 1449 assertTrue(m3.reads().contains(m2)); 1450 } 1451 1452 1453 /** 1454 * Root module not found 1455 */ 1456 @Test(expectedExceptions = { FindException.class }) 1457 public void testRootNotFound() { 1458 resolve(ModuleFinder.of(), "m1"); 1459 } 1460 1461 1462 /** 1463 * Direct dependency not found 1464 */ 1465 @Test(expectedExceptions = { FindException.class }) 1466 public void testDirectDependencyNotFound() { 1467 ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build(); 1468 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); 1469 resolve(finder, "m1"); 1470 } 1471 1472 1473 /** 1474 * Transitive dependency not found 1475 */ 1476 @Test(expectedExceptions = { FindException.class }) 1477 public void testTransitiveDependencyNotFound() { 1478 ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build(); 1479 ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build(); 1480 ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); 1481 resolve(finder, "m1"); 1482 } 1483 1484 1485 /** 1486 * Service provider dependency not found 1487 */ 1488 @Test(expectedExceptions = { FindException.class }) 1489 public void testServiceProviderDependencyNotFound() { 1490 1491 // service provider dependency (on m3) not found 1492 1493 ModuleDescriptor descriptor1 = newBuilder("m1") 1494 .exports("p") 1495 .uses("p.S") 1496 .build(); 1497 1498 ModuleDescriptor descriptor2 = newBuilder("m2") 1499 .requires("m1") 1500 .requires("m3") 1501 .provides("p.S", List.of("q.T")) 1502 .build(); 1503 1504 ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); 1505 1506 // should throw ResolutionException because m3 is not found 1507 Configuration cf = resolveAndBind(finder, "m1"); 1508 } 1509 1510 1511 /** 1512 * Simple cycle. 1513 */ 1514 @Test(expectedExceptions = { ResolutionException.class }) 1515 public void testSimpleCycle() { 1516 ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build(); 1517 ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build(); 1518 ModuleDescriptor descriptor3 = newBuilder("m3").requires("m1").build(); 1519 ModuleFinder finder 1520 = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); 1521 resolve(finder, "m1"); 1522 } 1523 1524 /** 1525 * Basic test for detecting cycles involving a service provider module 1526 */ 1527 @Test(expectedExceptions = { ResolutionException.class }) 1528 public void testCycleInProvider() { 1529 1530 ModuleDescriptor descriptor1 = newBuilder("m1") 1531 .exports("p") 1532 .uses("p.S") 1533 .build(); 1534 ModuleDescriptor descriptor2 = newBuilder("m2") 1535 .requires("m1") 1536 .requires("m3") 1537 .provides("p.S", List.of("q.T")) 1538 .build(); 1539 ModuleDescriptor descriptor3 = newBuilder("m3") 1540 .requires("m2") 1541 .build(); 1542 1543 ModuleFinder finder 1544 = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); 1545 1546 // should throw ResolutionException because of the m2 <--> m3 cycle 1547 resolveAndBind(finder, "m1"); 1548 } 1549 1550 1551 /** 1552 * Basic test to detect reading a module with the same name as itself 1553 * 1554 * The test consists of three configurations: 1555 * - Configuration cf1: m1, m2 requires transitive m1 1556 * - Configuration cf2: m1 requires m2 1557 */ 1558 @Test(expectedExceptions = { ResolutionException.class }) 1559 public void testReadModuleWithSameNameAsSelf() { 1560 ModuleDescriptor descriptor1_v1 = newBuilder("m1") 1561 .build(); 1562 1563 ModuleDescriptor descriptor2 = newBuilder("m2") 1564 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") 1565 .build(); 1566 1567 ModuleDescriptor descriptor1_v2 = newBuilder("m1") 1568 .requires("m2") 1569 .build(); 1570 1571 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1_v1, descriptor2); 1572 Configuration cf1 = resolve(finder1, "m2"); 1573 assertTrue(cf1.modules().size() == 2); 1574 1575 // resolve should throw ResolutionException 1576 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1_v2); 1577 resolve(cf1, finder2, "m1"); 1578 } 1579 1580 1581 /** 1582 * Basic test to detect reading two modules with the same name 1583 * 1584 * The test consists of three configurations: 1585 * - Configuration cf1: m1, m2 requires transitive m1 1586 * - Configuration cf2: m1, m3 requires transitive m1 1587 * - Configuration cf3(cf1,cf2): m4 requires m2, m3 1588 */ 1589 @Test(expectedExceptions = { ResolutionException.class }) 1590 public void testReadTwoModuleWithSameName() { 1591 ModuleDescriptor descriptor1 = newBuilder("m1") 1592 .build(); 1593 1594 ModuleDescriptor descriptor2 = newBuilder("m2") 1595 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") 1596 .build(); 1597 1598 ModuleDescriptor descriptor3 = newBuilder("m3") 1599 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1") 1600 .build(); 1601 1602 ModuleDescriptor descriptor4 = newBuilder("m4") 1603 .requires("m2") 1604 .requires("m3") 1605 .build(); 1606 1607 ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2); 1608 Configuration cf1 = resolve(finder1, "m2"); 1609 assertTrue(cf1.modules().size() == 2); 1610 1611 ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3); 1612 Configuration cf2 = resolve(finder2, "m3"); 1613 assertTrue(cf2.modules().size() == 2); 1614 1615 // should throw ResolutionException as m4 will read modules named "m1". 1616 ModuleFinder finder3 = ModuleUtils.finderOf(descriptor4); 1617 Configuration.resolve(finder3, List.of(cf1, cf2), ModuleFinder.of(), Set.of("m4")); 1618 } 1619 1620 1621 /** 1622 * Test two modules exporting package p to a module that reads both. 1623 */ 1624 @Test(expectedExceptions = { ResolutionException.class }) 1625 public void testPackageSuppliedByTwoOthers() { 1626 1627 ModuleDescriptor descriptor1 = newBuilder("m1") 1628 .requires("m2") 1629 .requires("m3") 1630 .build(); 1631 1632 ModuleDescriptor descriptor2 = newBuilder("m2") 1633 .exports("p") 1634 .build(); 1635 1636 ModuleDescriptor descriptor3 = newBuilder("m3") 1637 .exports("p", Set.of("m1")) 1638 .build(); 1639 1640 ModuleFinder finder 1641 = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3); 1642 1643 // m2 and m3 export package p to module m1 1644 resolve(finder, "m1"); 1645 } 1646 1647 1648 /** 1649 * Test the scenario where a module contains a package p and reads 1650 * a module that exports package p. 1651 */ 1652 @Test(expectedExceptions = { ResolutionException.class }) 1653 public void testPackageSuppliedBySelfAndOther() { 1654 1655 ModuleDescriptor descriptor1 = newBuilder("m1") 1656 .requires("m2") 1657 .packages(Set.of("p")) 1658 .build(); 1659 1660 ModuleDescriptor descriptor2 = newBuilder("m2") 1661 .exports("p") 1662 .build(); 1663 1664 ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); 1665 1666 // m1 contains package p, module m2 exports package p to m1 1667 resolve(finder, "m1"); 1668 } 1669 1670 1671 /** 1672 * Test the scenario where a module contains a package p and reads 1673 * a module that also contains a package p. 1674 */ 1675 public void testContainsPackageInSelfAndOther() { 1676 ModuleDescriptor descriptor1 = newBuilder("m1") 1677 .requires("m2") 1678 .packages(Set.of("p")) 1679 .build(); 1680 1681 ModuleDescriptor descriptor2 = newBuilder("m2") 1682 .packages(Set.of("p")) 1683 .build(); 1684 1685 ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); 1686 1687 Configuration cf = resolve(finder, "m1"); 1688 1689 assertTrue(cf.modules().size() == 2); 1690 assertTrue(cf.findModule("m1").isPresent()); 1691 assertTrue(cf.findModule("m2").isPresent()); 1692 1693 // m1 reads m2, m2 reads nothing 1694 ResolvedModule m1 = cf.findModule("m1").get(); 1695 ResolvedModule m2 = cf.findModule("m2").get(); 1696 assertTrue(m1.reads().size() == 1); 1697 assertTrue(m1.reads().contains(m2)); 1698 assertTrue(m2.reads().size() == 0); 1699 } 1700 1701 1702 /** 1703 * Test the scenario where a module that exports a package that is also 1704 * exported by a module that it reads in a parent layer. 1705 */ 1706 @Test(expectedExceptions = { ResolutionException.class }) 1707 public void testExportSamePackageAsBootLayer() { 1708 ModuleDescriptor descriptor = newBuilder("m1") 1709 .requires("java.base") 1710 .exports("java.lang") 1711 .build(); 1712 1713 ModuleFinder finder = ModuleUtils.finderOf(descriptor); 1714 1715 Configuration bootConfiguration = ModuleLayer.boot().configuration(); 1716 1717 // m1 contains package java.lang, java.base exports package java.lang to m1 1718 resolve(bootConfiguration, finder, "m1"); 1719 } 1720 1721 1722 /** 1723 * Test "uses p.S" where p is contained in the same module. 1724 */ 1725 public void testContainsService1() { 1726 ModuleDescriptor descriptor1 = newBuilder("m1") 1727 .packages(Set.of("p")) 1728 .uses("p.S") 1729 .build(); 1730 1731 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); 1732 1733 Configuration cf = resolve(finder, "m1"); 1734 1735 assertTrue(cf.modules().size() == 1); 1736 assertTrue(cf.findModule("m1").isPresent()); 1737 } 1738 1739 1740 /** 1741 * Test "uses p.S" where p is contained in a different module. 1742 */ 1743 @Test(expectedExceptions = { ResolutionException.class }) 1744 public void testContainsService2() { 1745 ModuleDescriptor descriptor1 = newBuilder("m1") 1746 .packages(Set.of("p")) 1747 .build(); 1748 1749 ModuleDescriptor descriptor2 = newBuilder("m2") 1750 .requires("m1") 1751 .uses("p.S") 1752 .build(); 1753 1754 ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); 1755 1756 // m2 does not read a module that exports p 1757 resolve(finder, "m2"); 1758 } 1759 1760 1761 /** 1762 * Test "provides p.S" where p is contained in the same module. 1763 */ 1764 public void testContainsService3() { 1765 ModuleDescriptor descriptor1 = newBuilder("m1") 1766 .packages(Set.of("p", "q")) 1767 .provides("p.S", List.of("q.S1")) 1768 .build(); 1769 1770 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); 1771 1772 Configuration cf = resolve(finder, "m1"); 1773 1774 assertTrue(cf.modules().size() == 1); 1775 assertTrue(cf.findModule("m1").isPresent()); 1776 } 1777 1778 1779 /** 1780 * Test "provides p.S" where p is contained in a different module. 1781 */ 1782 @Test(expectedExceptions = { ResolutionException.class }) 1783 public void testContainsService4() { 1784 ModuleDescriptor descriptor1 = newBuilder("m1") 1785 .packages(Set.of("p")) 1786 .build(); 1787 1788 ModuleDescriptor descriptor2 = newBuilder("m2") 1789 .requires("m1") 1790 .provides("p.S", List.of("q.S1")) 1791 .build(); 1792 1793 ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2); 1794 1795 // m2 does not read a module that exports p 1796 resolve(finder, "m2"); 1797 } 1798 1799 1800 /** 1801 * Test "uses p.S" where p is not exported to the module. 1802 */ 1803 @Test(expectedExceptions = { ResolutionException.class }) 1804 public void testServiceTypePackageNotExported1() { 1805 ModuleDescriptor descriptor1 = newBuilder("m1") 1806 .uses("p.S") 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 "provides p.S" where p is not exported to the module. 1818 */ 1819 @Test(expectedExceptions = { ResolutionException.class }) 1820 public void testServiceTypePackageNotExported2() { 1821 ModuleDescriptor descriptor1 = newBuilder("m1") 1822 .provides("p.S", List.of("q.T")) 1823 .build(); 1824 1825 ModuleFinder finder = ModuleUtils.finderOf(descriptor1); 1826 1827 // m1 does not read a module that exports p 1828 resolve(finder, "m1"); 1829 } 1830 1831 1832 /** 1833 * Test the empty configuration. 1834 */ 1835 public void testEmptyConfiguration() { 1836 Configuration cf = Configuration.empty(); 1837 1838 assertTrue(cf.parents().isEmpty()); 1839 1840 assertTrue(cf.modules().isEmpty()); 1841 assertFalse(cf.findModule("java.base").isPresent()); 1842 } 1843 1844 1845 // platform specific modules 1846 1847 @DataProvider(name = "platformmatch") 1848 public Object[][] createPlatformMatches() { 1849 return new Object[][]{ 1850 1851 { "", "" }, 1852 { "linux-arm", "" }, 1853 { "linux-arm", "linux-arm" }, 1854 1855 }; 1856 1857 }; 1858 1859 @DataProvider(name = "platformmismatch") 1860 public Object[][] createBad() { 1861 return new Object[][] { 1862 1863 { "linux-x64", "linux-arm" }, 1864 { "linux-x64", "windows-x64" }, 1865 1866 }; 1867 } 1868 1869 /** 1870 * Test creating a configuration containing platform specific modules. 1871 */ 1872 @Test(dataProvider = "platformmatch") 1873 public void testPlatformMatch(String s1, String s2) throws IOException { 1874 1875 ModuleDescriptor base = ModuleDescriptor.newModule("java.base").build(); 1876 Path system = writeModule(base, null); 1877 1878 ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1") 1879 .requires("m2") 1880 .build(); 1881 Path dir1 = writeModule(descriptor1, s1); 1882 1883 ModuleDescriptor descriptor2 = ModuleDescriptor.newModule("m2").build(); 1884 Path dir2 = writeModule(descriptor2, s2); 1885 1886 ModuleFinder finder = ModuleFinder.of(system, dir1, dir2); 1887 1888 Configuration cf = resolve(finder, "m1"); 1889 1890 assertTrue(cf.modules().size() == 3); 1891 assertTrue(cf.findModule("java.base").isPresent()); 1892 assertTrue(cf.findModule("m1").isPresent()); 1893 assertTrue(cf.findModule("m2").isPresent()); 1894 } 1895 1896 /** 1897 * Test attempting to create a configuration with modules for different 1898 * platforms. 1899 */ 1900 @Test(dataProvider = "platformmismatch", 1901 expectedExceptions = FindException.class ) 1902 public void testPlatformMisMatch(String s1, String s2) throws IOException { 1903 testPlatformMatch(s1, s2); 1904 } 1905 1906 // no parents 1907 1908 @Test(expectedExceptions = { IllegalArgumentException.class }) 1909 public void testResolveRequiresWithNoParents() { 1910 ModuleFinder empty = ModuleFinder.of(); 1911 Configuration.resolve(empty, List.of(), empty, Set.of()); 1912 } 1913 1914 @Test(expectedExceptions = { IllegalArgumentException.class }) 1915 public void testResolveRequiresAndUsesWithNoParents() { 1916 ModuleFinder empty = ModuleFinder.of(); 1917 Configuration.resolveAndBind(empty, List.of(), empty, Set.of()); 1918 } 1919 1920 1921 // parents with modules for specific platforms 1922 @Test(dataProvider = "platformmatch") 1923 public void testResolveRequiresWithCompatibleParents(String s1, String s2) 1924 throws IOException 1925 { 1926 ModuleDescriptor base = ModuleDescriptor.newModule("java.base").build(); 1927 Path system = writeModule(base, null); 1928 1929 ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1").build(); 1930 Path dir1 = writeModule(descriptor1, s1); 1931 1932 ModuleDescriptor descriptor2 = ModuleDescriptor.newModule("m2").build(); 1933 Path dir2 = writeModule(descriptor2, s2); 1934 1935 ModuleFinder finder1 = ModuleFinder.of(system, dir1); 1936 Configuration cf1 = resolve(finder1, "m1"); 1937 1938 ModuleFinder finder2 = ModuleFinder.of(system, dir2); 1939 Configuration cf2 = resolve(finder2, "m2"); 1940 1941 Configuration cf3 = Configuration.resolve(ModuleFinder.of(), 1942 List.of(cf1, cf2), 1943 ModuleFinder.of(), 1944 Set.of()); 1945 assertTrue(cf3.parents().size() == 2); 1946 } 1947 1948 1949 @Test(dataProvider = "platformmismatch", 1950 expectedExceptions = IllegalArgumentException.class ) 1951 public void testResolveRequiresWithConflictingParents(String s1, String s2) 1952 throws IOException 1953 { 1954 testResolveRequiresWithCompatibleParents(s1, s2); 1955 } 1956 1957 1958 // null handling 1959 1960 // finder1, finder2, roots 1961 1962 1963 @Test(expectedExceptions = { NullPointerException.class }) 1964 public void testResolveRequiresWithNull1() { 1965 resolve((ModuleFinder)null, ModuleFinder.of()); 1966 } 1967 1968 @Test(expectedExceptions = { NullPointerException.class }) 1969 public void testResolveRequiresWithNull2() { 1970 resolve(ModuleFinder.of(), (ModuleFinder)null); 1971 } 1972 1973 @Test(expectedExceptions = { NullPointerException.class }) 1974 public void testResolveRequiresWithNull3() { 1975 Configuration empty = Configuration.empty(); 1976 Configuration.resolve(null, List.of(empty), ModuleFinder.of(), Set.of()); 1977 } 1978 1979 @Test(expectedExceptions = { NullPointerException.class }) 1980 public void testResolveRequiresWithNull4() { 1981 ModuleFinder empty = ModuleFinder.of(); 1982 Configuration.resolve(empty, null, empty, Set.of()); 1983 } 1984 1985 @Test(expectedExceptions = { NullPointerException.class }) 1986 public void testResolveRequiresWithNull5() { 1987 Configuration cf = ModuleLayer.boot().configuration(); 1988 Configuration.resolve(ModuleFinder.of(), List.of(cf), null, Set.of()); 1989 } 1990 1991 @Test(expectedExceptions = { NullPointerException.class }) 1992 public void testResolveRequiresWithNull6() { 1993 ModuleFinder empty = ModuleFinder.of(); 1994 Configuration cf = ModuleLayer.boot().configuration(); 1995 Configuration.resolve(empty, List.of(cf), empty, null); 1996 } 1997 1998 @Test(expectedExceptions = { NullPointerException.class }) 1999 public void testResolveRequiresAndUsesWithNull1() { 2000 resolveAndBind((ModuleFinder) null, ModuleFinder.of()); 2001 } 2002 2003 @Test(expectedExceptions = { NullPointerException.class }) 2004 public void testResolveRequiresAndUsesWithNull2() { 2005 resolveAndBind(ModuleFinder.of(), (ModuleFinder) null); 2006 } 2007 2008 @Test(expectedExceptions = { NullPointerException.class }) 2009 public void testResolveRequiresAndUsesWithNull3() { 2010 Configuration empty = Configuration.empty(); 2011 Configuration.resolveAndBind(null, List.of(empty), ModuleFinder.of(), Set.of()); 2012 } 2013 2014 @Test(expectedExceptions = { NullPointerException.class }) 2015 public void testResolveRequiresAndUsesWithNull4() { 2016 ModuleFinder empty = ModuleFinder.of(); 2017 Configuration.resolveAndBind(empty, null, empty, Set.of()); 2018 } 2019 2020 @Test(expectedExceptions = { NullPointerException.class }) 2021 public void testResolveRequiresAndUsesWithNull5() { 2022 Configuration cf = ModuleLayer.boot().configuration(); 2023 Configuration.resolveAndBind(ModuleFinder.of(), List.of(cf), null, Set.of()); 2024 } 2025 2026 @Test(expectedExceptions = { NullPointerException.class }) 2027 public void testResolveRequiresAndUsesWithNull6() { 2028 ModuleFinder empty = ModuleFinder.of(); 2029 Configuration cf = ModuleLayer.boot().configuration(); 2030 Configuration.resolveAndBind(empty, List.of(cf), empty, null); 2031 } 2032 2033 @Test(expectedExceptions = { NullPointerException.class }) 2034 public void testFindModuleWithNull() { 2035 Configuration.empty().findModule(null); 2036 } 2037 2038 // unmodifiable collections 2039 2040 @DataProvider(name = "configurations") 2041 public Object[][] configurations() { 2042 // empty, boot, and custom configurations 2043 return new Object[][] { 2044 { Configuration.empty(), null }, 2045 { ModuleLayer.boot().configuration(), null }, 2046 { resolve(ModuleFinder.of()), null }, 2047 }; 2048 } 2049 2050 @Test(dataProvider = "configurations", 2051 expectedExceptions = { UnsupportedOperationException.class }) 2052 public void testUnmodifiableParents1(Configuration cf, Object ignore) { 2053 cf.parents().add(Configuration.empty()); 2054 } 2055 2056 @Test(dataProvider = "configurations", 2057 expectedExceptions = { UnsupportedOperationException.class }) 2058 public void testUnmodifiableParents2(Configuration cf, Object ignore) { 2059 cf.parents().remove(Configuration.empty()); 2060 } 2061 2062 @Test(dataProvider = "configurations", 2063 expectedExceptions = { UnsupportedOperationException.class }) 2064 public void testUnmodifiableModules1(Configuration cf, Object ignore) { 2065 ResolvedModule module = ModuleLayer.boot() 2066 .configuration() 2067 .findModule("java.base") 2068 .orElseThrow(); 2069 cf.modules().add(module); 2070 } 2071 2072 @Test(dataProvider = "configurations", 2073 expectedExceptions = { UnsupportedOperationException.class }) 2074 public void testUnmodifiableModules2(Configuration cf, Object ignore) { 2075 ResolvedModule module = ModuleLayer.boot() 2076 .configuration() 2077 .findModule("java.base") 2078 .orElseThrow(); 2079 cf.modules().remove(module); 2080 } 2081 2082 /** 2083 * Invokes parent.resolve(...) 2084 */ 2085 private Configuration resolve(Configuration parent, 2086 ModuleFinder before, 2087 ModuleFinder after, 2088 String... roots) { 2089 return parent.resolve(before, after, Set.of(roots)); 2090 } 2091 2092 private Configuration resolve(Configuration parent, 2093 ModuleFinder before, 2094 String... roots) { 2095 return resolve(parent, before, ModuleFinder.of(), roots); 2096 } 2097 2098 private Configuration resolve(ModuleFinder before, 2099 ModuleFinder after, 2100 String... roots) { 2101 return resolve(Configuration.empty(), before, after, roots); 2102 } 2103 2104 private Configuration resolve(ModuleFinder before, 2105 String... roots) { 2106 return resolve(Configuration.empty(), before, roots); 2107 } 2108 2109 2110 /** 2111 * Invokes parent.resolveAndBind(...) 2112 */ 2113 private Configuration resolveAndBind(Configuration parent, 2114 ModuleFinder before, 2115 ModuleFinder after, 2116 String... roots) { 2117 return parent.resolveAndBind(before, after, Set.of(roots)); 2118 } 2119 2120 private Configuration resolveAndBind(Configuration parent, 2121 ModuleFinder before, 2122 String... roots) { 2123 return resolveAndBind(parent, before, ModuleFinder.of(), roots); 2124 } 2125 2126 private Configuration resolveAndBind(ModuleFinder before, 2127 ModuleFinder after, 2128 String... roots) { 2129 return resolveAndBind(Configuration.empty(), before, after, roots); 2130 } 2131 2132 private Configuration resolveAndBind(ModuleFinder before, 2133 String... roots) { 2134 return resolveAndBind(Configuration.empty(), before, roots); 2135 } 2136 2137 2138 /** 2139 * Writes a module-info.class. If {@code targetPlatform} is not null then 2140 * it includes the ModuleTarget class file attribute with the target platform. 2141 */ 2142 static Path writeModule(ModuleDescriptor descriptor, String targetPlatform) 2143 throws IOException 2144 { 2145 ModuleTarget target; 2146 if (targetPlatform != null) { 2147 target = new ModuleTarget(targetPlatform); 2148 } else { 2149 target = null; 2150 } 2151 String name = descriptor.name(); 2152 Path dir = Files.createTempDirectory(Paths.get(""), name); 2153 Path mi = dir.resolve("module-info.class"); 2154 try (OutputStream out = Files.newOutputStream(mi)) { 2155 ModuleInfoWriter.write(descriptor, target, out); 2156 } 2157 return dir; 2158 } 2159 }