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