1 /* 2 * Copyright (c) 2013, 2024, 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 * @bug 8142968 8158456 8298875 27 * @modules java.base/jdk.internal.access 28 * java.base/jdk.internal.module 29 * @library /test/lib 30 * @build jdk.test.lib.util.ModuleInfoWriter 31 * @run testng ModuleDescriptorTest 32 * @summary Basic test for java.lang.module.ModuleDescriptor and its builder 33 */ 34 35 import java.io.ByteArrayOutputStream; 36 import java.io.IOException; 37 import java.io.InputStream; 38 import java.lang.module.InvalidModuleDescriptorException; 39 import java.lang.module.ModuleDescriptor; 40 import java.lang.module.ModuleDescriptor.Builder; 41 import java.lang.module.ModuleDescriptor.Exports; 42 import java.lang.module.ModuleDescriptor.Opens; 43 import java.lang.module.ModuleDescriptor.Requires; 44 import java.lang.module.ModuleDescriptor.Provides; 45 import java.lang.module.ModuleDescriptor.Requires.Modifier; 46 import java.lang.module.ModuleDescriptor.Version; 47 import java.nio.ByteBuffer; 48 import java.util.ArrayList; 49 import java.util.Collections; 50 import java.util.EnumSet; 51 import java.util.HashSet; 52 import java.util.Iterator; 53 import java.util.List; 54 import java.util.Objects; 55 import java.util.Set; 56 import java.util.stream.Collectors; 57 58 import static java.lang.module.ModuleDescriptor.Requires.Modifier.*; 59 60 import jdk.internal.access.JavaLangModuleAccess; 61 import jdk.internal.access.SharedSecrets; 62 import java.lang.classfile.ClassFile; 63 import java.lang.classfile.ClassFileVersion; 64 import java.lang.classfile.ClassTransform; 65 import java.lang.classfile.attribute.ModuleAttribute; 66 import java.lang.constant.PackageDesc; 67 import java.lang.constant.ModuleDesc; 68 import jdk.test.lib.util.ModuleInfoWriter; 69 import org.testng.annotations.DataProvider; 70 import org.testng.annotations.Test; 71 import static org.testng.Assert.*; 72 73 @Test 74 public class ModuleDescriptorTest { 75 private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess(); 76 77 @DataProvider(name = "invalidNames") 78 public Object[][] invalidNames() { 79 return new Object[][]{ 80 81 { null, null }, 82 { "1", null }, 83 { "1foo", null }, 84 { ".foo", null }, 85 { "foo.", null }, 86 { "[foo]", null }, 87 { "foo.1", null }, 88 { "1foo.bar", null }, 89 { "foo.1bar", null }, 90 { "foo.[bar]", null }, 91 { "foo..bar", null }, 92 { "foo.bar.1", null }, 93 { "foo.bar.1gus", null }, 94 { "foo.bar.[gus]", null }, 95 96 { "class", null }, 97 { "interface", null }, 98 { "true", null }, 99 { "false", null }, 100 { "null", null }, 101 102 { "x.class", null }, 103 { "x.interface", null }, 104 { "x.true", null }, 105 { "x.false", null }, 106 { "x.null", null }, 107 108 { "class.x", null }, 109 { "interface.x", null }, 110 { "true.x", null }, 111 { "false.x", null }, 112 { "null.x", null }, 113 114 { "x.class.x", null }, 115 { "x.interface.x", null }, 116 { "x.true.x", null }, 117 { "x.false.x", null }, 118 { "x.null.x", null }, 119 120 { "_", null }, 121 122 }; 123 } 124 125 126 // requires 127 128 private Requires requires(Set<Modifier> mods, String mn) { 129 return requires(mods, mn, null); 130 } 131 132 private Requires requires(Set<Modifier> mods, String mn, Version v) { 133 Builder builder = ModuleDescriptor.newModule("m"); 134 if (v == null) { 135 builder.requires(mods, mn); 136 } else { 137 builder.requires(mods, mn, v); 138 } 139 Set<Requires> requires = builder.build().requires(); 140 assertTrue(requires.size() == 2); 141 Iterator<Requires> iterator = requires.iterator(); 142 Requires r = iterator.next(); 143 if (r.name().equals("java.base")) { 144 r = iterator.next(); 145 } else { 146 Requires other = iterator.next(); 147 assertEquals(other.name(), "java.base"); 148 } 149 return r; 150 } 151 152 private Requires requires(String mn) { 153 return requires(Collections.emptySet(), mn); 154 } 155 156 public void testRequiresWithRequires() { 157 Requires r1 = requires("foo"); 158 ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").requires(r1).build(); 159 assertEquals(descriptor.requires().size(), 2); 160 var iterator = descriptor.requires().iterator(); 161 Requires r2 = iterator.next(); 162 if (r2.name().equals("java.base")) { 163 r2 = iterator.next(); 164 } 165 assertEquals(r1, r2); 166 } 167 168 public void testRequiresWithNoModifiers() { 169 Requires r = requires(EnumSet.noneOf(Requires.Modifier.class), "foo"); 170 assertEquals(r, r); 171 assertTrue(r.compareTo(r) == 0); 172 assertTrue(r.modifiers().isEmpty()); 173 assertEquals(r.name(), "foo"); 174 assertFalse(r.compiledVersion().isPresent()); 175 } 176 177 public void testRequiresWithOneModifier() { 178 Requires r = requires(EnumSet.of(TRANSITIVE), "foo"); 179 assertEquals(r, r); 180 assertTrue(r.compareTo(r) == 0); 181 assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE)); 182 assertEquals(r.name(), "foo"); 183 assertFalse(r.compiledVersion().isPresent()); 184 } 185 186 public void testRequiresWithTwoModifiers() { 187 Requires r = requires(EnumSet.of(TRANSITIVE, SYNTHETIC), "foo"); 188 assertEquals(r, r); 189 assertTrue(r.compareTo(r) == 0); 190 assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, SYNTHETIC)); 191 assertEquals(r.name(), "foo"); 192 assertFalse(r.compiledVersion().isPresent()); 193 } 194 195 public void testRequiresWithAllModifiers() { 196 Requires r = requires(EnumSet.allOf(Modifier.class), "foo"); 197 assertEquals(r, r); 198 assertTrue(r.compareTo(r) == 0); 199 assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, STATIC, SYNTHETIC, MANDATED)); 200 assertEquals(r.name(), "foo"); 201 assertFalse(r.compiledVersion().isPresent()); 202 } 203 204 public void testRequiresWithCompiledVersion() { 205 Version v = Version.parse("1.0"); 206 Requires r = requires(Set.of(), "foo", v); 207 assertEquals(r, r); 208 assertTrue(r.compareTo(r) == 0); 209 assertEquals(r.modifiers(), Set.of()); 210 assertEquals(r.name(), "foo"); 211 assertTrue(r.compiledVersion().isPresent()); 212 assertEquals(r.compiledVersion().get().toString(), "1.0"); 213 } 214 215 @Test(expectedExceptions = IllegalStateException.class) 216 public void testRequiresWithDuplicatesRequires() { 217 Requires r = requires("foo"); 218 ModuleDescriptor.newModule("m").requires(r).requires(r); 219 } 220 221 @Test(expectedExceptions = IllegalArgumentException.class) 222 public void testRequiresSelfWithRequires() { 223 Requires r = requires("foo"); 224 ModuleDescriptor.newModule("foo").requires(r); 225 } 226 227 @Test(expectedExceptions = IllegalArgumentException.class) 228 public void testRequiresSelfWithNoModifier() { 229 ModuleDescriptor.newModule("m").requires("m"); 230 } 231 232 @Test(expectedExceptions = IllegalArgumentException.class) 233 public void testRequiresSelfWithOneModifier() { 234 ModuleDescriptor.newModule("m").requires(Set.of(TRANSITIVE), "m"); 235 } 236 237 @Test(expectedExceptions = IllegalArgumentException.class) 238 public void testRequiresSelfWithAllModifiers() { 239 ModuleDescriptor.newModule("m").requires(EnumSet.allOf(Modifier.class), "m"); 240 } 241 242 @Test(dataProvider = "invalidNames", 243 expectedExceptions = IllegalArgumentException.class ) 244 public void testRequiresWithBadModuleName(String mn, String ignore) { 245 requires(EnumSet.noneOf(Modifier.class), mn); 246 } 247 248 @Test(expectedExceptions = NullPointerException.class) 249 public void testRequiresWithNullRequires() { 250 ModuleDescriptor.newModule("m").requires((Requires) null); 251 } 252 253 @Test(expectedExceptions = NullPointerException.class) 254 public void testRequiresWithNullModifiers() { 255 ModuleDescriptor.newModule("m").requires(null, "foo"); 256 } 257 258 @Test(expectedExceptions = NullPointerException.class) 259 public void testRequiresWithNullVersion() { 260 ModuleDescriptor.newModule("m").requires(Set.of(), "foo", null); 261 } 262 263 public void testRequiresCompare() { 264 Requires r1 = requires(EnumSet.noneOf(Modifier.class), "foo"); 265 Requires r2 = requires(EnumSet.noneOf(Modifier.class), "bar"); 266 int n = "foo".compareTo("bar"); 267 assertTrue(r1.compareTo(r2) == n); 268 assertTrue(r2.compareTo(r1) == -n); 269 } 270 271 public void testRequiresCompareWithDifferentModifiers() { 272 Requires r1 = requires(EnumSet.of(TRANSITIVE), "foo"); 273 Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo"); 274 int n = Integer.compare(1 << TRANSITIVE.ordinal(), 1 << SYNTHETIC.ordinal()); 275 assertTrue(r1.compareTo(r2) == n); 276 assertTrue(r2.compareTo(r1) == -n); 277 } 278 279 public void testRequiresCompareWithSameModifiers() { 280 Requires r1 = requires(EnumSet.of(SYNTHETIC), "foo"); 281 Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo"); 282 assertTrue(r1.compareTo(r2) == 0); 283 assertTrue(r2.compareTo(r1) == 0); 284 } 285 286 public void testRequiresCompareWithSameCompiledVersion() { 287 Requires r1 = requires(Set.of(), "foo", Version.parse("2.0")); 288 Requires r2 = requires(Set.of(), "foo", Version.parse("2.0")); 289 assertTrue(r1.compareTo(r2) == 0); 290 assertTrue(r2.compareTo(r1) == 0); 291 } 292 293 public void testRequiresCompareWithDifferentCompiledVersion() { 294 Requires r1 = requires(Set.of(), "foo", Version.parse("1.0")); 295 Requires r2 = requires(Set.of(), "foo", Version.parse("2.0")); 296 assertTrue(r1.compareTo(r2) < 0); 297 assertTrue(r2.compareTo(r1) > 0); 298 } 299 300 public void testRequiresEqualsAndHashCode() { 301 Requires r1 = requires("foo"); 302 Requires r2 = requires("foo"); 303 assertEquals(r1, r2); 304 assertTrue(r1.hashCode() == r2.hashCode()); 305 306 r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo"); 307 r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo"); 308 assertEquals(r1, r2); 309 assertTrue(r1.hashCode() == r2.hashCode()); 310 311 r1 = requires("foo"); 312 r2 = requires("bar"); 313 assertNotEquals(r1, r2); 314 315 r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo"); 316 r2 = requires(Set.of(), "foo"); 317 assertNotEquals(r1, r2); 318 319 Version v1 = Version.parse("1.0"); 320 r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1); 321 r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1); 322 assertEquals(r1, r2); 323 assertTrue(r1.hashCode() == r2.hashCode()); 324 325 Version v2 = Version.parse("2.0"); 326 r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v1); 327 r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo", v2); 328 assertNotEquals(r1, r2); 329 } 330 331 public void testRequiresToString() { 332 Requires r = requires(EnumSet.noneOf(Modifier.class), "foo"); 333 assertTrue(r.toString().contains("foo")); 334 } 335 336 337 // exports 338 339 private Exports exports(Set<Exports.Modifier> mods, String pn) { 340 return ModuleDescriptor.newModule("foo") 341 .exports(mods, pn) 342 .build() 343 .exports() 344 .iterator() 345 .next(); 346 } 347 348 private Exports exports(String pn) { 349 return exports(Set.of(), pn); 350 } 351 352 private Exports exports(Set<Exports.Modifier> mods, String pn, String target) { 353 return ModuleDescriptor.newModule("foo") 354 .exports(mods, pn, Set.of(target)) 355 .build() 356 .exports() 357 .iterator() 358 .next(); 359 } 360 361 private Exports exports(String pn, String target) { 362 return exports(Set.of(), pn, target); 363 } 364 365 366 public void testExportsExports() { 367 Exports e1 = exports("p"); 368 ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").exports(e1).build(); 369 Exports e2 = descriptor.exports().iterator().next(); 370 assertEquals(e1, e2); 371 } 372 373 public void testExportsToAll() { 374 Exports e = exports("p"); 375 assertEquals(e, e); 376 assertTrue(e.modifiers().isEmpty()); 377 assertEquals(e.source(), "p"); 378 assertFalse(e.isQualified()); 379 assertTrue(e.targets().isEmpty()); 380 } 381 382 public void testExportsToTarget() { 383 Exports e = exports("p", "bar"); 384 assertEquals(e, e); 385 assertTrue(e.modifiers().isEmpty()); 386 assertEquals(e.source(), "p"); 387 assertTrue(e.isQualified()); 388 assertTrue(e.targets().size() == 1); 389 assertTrue(e.targets().contains("bar")); 390 } 391 392 public void testExportsToTargets() { 393 Set<String> targets = new HashSet<>(); 394 targets.add("bar"); 395 targets.add("gus"); 396 Exports e 397 = ModuleDescriptor.newModule("foo") 398 .exports("p", targets) 399 .build() 400 .exports() 401 .iterator() 402 .next(); 403 assertEquals(e, e); 404 assertTrue(e.modifiers().isEmpty()); 405 assertEquals(e.source(), "p"); 406 assertTrue(e.isQualified()); 407 assertTrue(e.targets().size() == 2); 408 assertTrue(e.targets().contains("bar")); 409 assertTrue(e.targets().contains("gus")); 410 } 411 412 public void testExportsToAllWithModifier() { 413 Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p"); 414 assertEquals(e, e); 415 assertTrue(e.modifiers().size() == 1); 416 assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC)); 417 assertEquals(e.source(), "p"); 418 assertFalse(e.isQualified()); 419 assertTrue(e.targets().isEmpty()); 420 } 421 422 public void testExportsToTargetWithModifier() { 423 Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p", "bar"); 424 assertEquals(e, e); 425 assertTrue(e.modifiers().size() == 1); 426 assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC)); 427 assertEquals(e.source(), "p"); 428 assertTrue(e.isQualified()); 429 assertTrue(e.targets().size() == 1); 430 assertTrue(e.targets().contains("bar")); 431 } 432 433 @Test(expectedExceptions = IllegalStateException.class) 434 public void testExportsWithDuplicate1() { 435 Exports e = exports("p"); 436 ModuleDescriptor.newModule("foo").exports(e).exports(e); 437 } 438 439 @Test(expectedExceptions = IllegalStateException.class) 440 public void testExportsWithDuplicate2() { 441 ModuleDescriptor.newModule("foo").exports("p").exports("p"); 442 } 443 444 @Test(expectedExceptions = IllegalArgumentException.class ) 445 public void testExportsWithEmptySet() { 446 ModuleDescriptor.newModule("foo").exports("p", Collections.emptySet()); 447 } 448 449 @Test(dataProvider = "invalidNames", 450 expectedExceptions = IllegalArgumentException.class ) 451 public void testExportsWithBadName(String pn, String ignore) { 452 ModuleDescriptor.newModule("foo").exports(pn); 453 } 454 455 @Test(expectedExceptions = NullPointerException.class ) 456 public void testExportsWithNullExports() { 457 ModuleDescriptor.newModule("foo").exports((Exports) null); 458 } 459 460 @Test(expectedExceptions = NullPointerException.class ) 461 public void testExportsWithNullTargets() { 462 ModuleDescriptor.newModule("foo").exports("p", (Set<String>) null); 463 } 464 465 public void testExportsCompare() { 466 Exports e1 = exports("p"); 467 Exports e2 = exports("p"); 468 assertEquals(e1, e2); 469 assertTrue(e1.hashCode() == e2.hashCode()); 470 assertTrue(e1.compareTo(e2) == 0); 471 assertTrue(e2.compareTo(e1) == 0); 472 } 473 474 public void testExportsCompareWithSameModifiers() { 475 Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p"); 476 Exports e2 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p"); 477 assertEquals(e1, e2); 478 assertTrue(e1.hashCode() == e2.hashCode()); 479 assertTrue(e1.compareTo(e2) == 0); 480 assertTrue(e2.compareTo(e1) == 0); 481 } 482 483 public void testExportsCompareWithDifferentModifiers() { 484 Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p"); 485 Exports e2 = exports("p"); 486 assertNotEquals(e1, e2); 487 assertTrue(e1.compareTo(e2) == 1); 488 assertTrue(e2.compareTo(e1) == -1); 489 } 490 491 public void testExportsCompareWithSameTargets() { 492 Exports e1 = exports("p", "x"); 493 Exports e2 = exports("p", "x"); 494 assertEquals(e1, e2); 495 assertTrue(e1.hashCode() == e2.hashCode()); 496 assertTrue(e1.compareTo(e2) == 0); 497 assertTrue(e2.compareTo(e1) == 0); 498 } 499 500 public void testExportsCompareWithDifferentTargets() { 501 Exports e1 = exports("p", "y"); 502 Exports e2 = exports("p", "x"); 503 assertNotEquals(e1, e2); 504 assertTrue(e1.compareTo(e2) == 1); 505 assertTrue(e2.compareTo(e1) == -1); 506 } 507 508 public void testExportsToString() { 509 String s = ModuleDescriptor.newModule("foo") 510 .exports("p1", Set.of("bar")) 511 .build() 512 .exports() 513 .iterator() 514 .next() 515 .toString(); 516 assertTrue(s.contains("p1")); 517 assertTrue(s.contains("bar")); 518 } 519 520 521 // opens 522 523 private Opens opens(Set<Opens.Modifier> mods, String pn) { 524 return ModuleDescriptor.newModule("foo") 525 .opens(mods, pn) 526 .build() 527 .opens() 528 .iterator() 529 .next(); 530 } 531 532 private Opens opens(String pn) { 533 return opens(Set.of(), pn); 534 } 535 536 private Opens opens(Set<Opens.Modifier> mods, String pn, String target) { 537 return ModuleDescriptor.newModule("foo") 538 .opens(mods, pn, Set.of(target)) 539 .build() 540 .opens() 541 .iterator() 542 .next(); 543 } 544 545 private Opens opens(String pn, String target) { 546 return opens(Set.of(), pn, target); 547 } 548 549 public void testOpensOpens() { 550 Opens o1 = opens("p"); 551 ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").opens(o1).build(); 552 Opens o2 = descriptor.opens().iterator().next(); 553 assertEquals(o1, o2); 554 } 555 556 public void testOpensToAll() { 557 Opens o = opens("p"); 558 assertEquals(o, o); 559 assertTrue(o.modifiers().isEmpty()); 560 assertEquals(o.source(), "p"); 561 assertFalse(o.isQualified()); 562 assertTrue(o.targets().isEmpty()); 563 } 564 565 566 public void testOpensToTarget() { 567 Opens o = opens("p", "bar"); 568 assertEquals(o, o); 569 assertTrue(o.modifiers().isEmpty()); 570 assertEquals(o.source(), "p"); 571 assertTrue(o.isQualified()); 572 assertTrue(o.targets().size() == 1); 573 assertTrue(o.targets().contains("bar")); 574 } 575 576 public void testOpensToTargets() { 577 Set<String> targets = new HashSet<>(); 578 targets.add("bar"); 579 targets.add("gus"); 580 Opens o = ModuleDescriptor.newModule("foo") 581 .opens("p", targets) 582 .build() 583 .opens() 584 .iterator() 585 .next(); 586 assertEquals(o, o); 587 assertTrue(o.modifiers().isEmpty()); 588 assertEquals(o.source(), "p"); 589 assertTrue(o.isQualified()); 590 assertTrue(o.targets().size() == 2); 591 assertTrue(o.targets().contains("bar")); 592 assertTrue(o.targets().contains("gus")); 593 } 594 595 @Test(expectedExceptions = IllegalStateException.class) 596 public void testOpensWithDuplicate1() { 597 Opens o = opens("p"); 598 ModuleDescriptor.newModule("foo").opens(o).opens(o); 599 } 600 601 @Test(expectedExceptions = IllegalStateException.class) 602 public void testOpensWithDuplicate2() { 603 ModuleDescriptor.newModule("foo").opens("p").opens("p"); 604 } 605 606 @Test(expectedExceptions = IllegalArgumentException.class ) 607 public void testOpensWithEmptySet() { 608 ModuleDescriptor.newModule("foo").opens("p", Collections.emptySet()); 609 } 610 611 @Test(dataProvider = "invalidNames", 612 expectedExceptions = IllegalArgumentException.class ) 613 public void testOpensWithBadName(String pn, String ignore) { 614 ModuleDescriptor.newModule("foo").opens(pn); 615 } 616 617 @Test(expectedExceptions = NullPointerException.class ) 618 public void testOpensWithNullExports() { 619 ModuleDescriptor.newModule("foo").opens((Opens) null); 620 } 621 622 @Test(expectedExceptions = NullPointerException.class ) 623 public void testOpensWithNullTargets() { 624 ModuleDescriptor.newModule("foo").opens("p", (Set<String>) null); 625 } 626 627 public void testOpensCompare() { 628 Opens o1 = opens("p"); 629 Opens o2 = opens("p"); 630 assertEquals(o1, o2); 631 assertTrue(o1.hashCode() == o2.hashCode()); 632 assertTrue(o1.compareTo(o2) == 0); 633 assertTrue(o2.compareTo(o1) == 0); 634 } 635 636 public void testOpensCompareWithSameModifiers() { 637 Opens o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p"); 638 Opens o2 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p"); 639 assertEquals(o1, o2); 640 assertTrue(o1.hashCode() == o2.hashCode()); 641 assertTrue(o1.compareTo(o2) == 0); 642 assertTrue(o2.compareTo(o1) == 0); 643 } 644 645 public void testOpensCompareWithDifferentModifiers() { 646 Opens o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p"); 647 Opens o2 = opens("p"); 648 assertNotEquals(o1, o2); 649 assertTrue(o1.compareTo(o2) == 1); 650 assertTrue(o2.compareTo(o1) == -1); 651 } 652 653 public void testOpensCompareWithSameTargets() { 654 Opens o1 = opens("p", "x"); 655 Opens o2 = opens("p", "x"); 656 assertEquals(o1, o2); 657 assertTrue(o1.hashCode() == o2.hashCode()); 658 assertTrue(o1.compareTo(o2) == 0); 659 assertTrue(o2.compareTo(o1) == 0); 660 } 661 662 public void testOpensCompareWithDifferentTargets() { 663 Opens o1 = opens("p", "y"); 664 Opens o2 = opens("p", "x"); 665 assertNotEquals(o1, o2); 666 assertTrue(o1.compareTo(o2) == 1); 667 assertTrue(o2.compareTo(o1) == -1); 668 } 669 670 public void testOpensToString() { 671 String s = ModuleDescriptor.newModule("foo") 672 .opens("p1", Set.of("bar")) 673 .build() 674 .opens() 675 .iterator() 676 .next() 677 .toString(); 678 assertTrue(s.contains("p1")); 679 assertTrue(s.contains("bar")); 680 } 681 682 683 // uses 684 685 public void testUses() { 686 Set<String> uses 687 = ModuleDescriptor.newModule("foo") 688 .uses("p.S") 689 .uses("q.S") 690 .build() 691 .uses(); 692 assertTrue(uses.size() == 2); 693 assertTrue(uses.contains("p.S")); 694 assertTrue(uses.contains("q.S")); 695 } 696 697 @Test(expectedExceptions = IllegalStateException.class) 698 public void testUsesWithDuplicate() { 699 ModuleDescriptor.newModule("foo").uses("p.S").uses("p.S"); 700 } 701 702 @Test(expectedExceptions = IllegalArgumentException.class) 703 public void testUsesWithSimpleIdentifier() { 704 ModuleDescriptor.newModule("foo").uses("S"); 705 } 706 707 @Test(dataProvider = "invalidNames", 708 expectedExceptions = IllegalArgumentException.class ) 709 public void testUsesWithBadName(String service, String ignore) { 710 ModuleDescriptor.newModule("foo").uses(service); 711 } 712 713 714 // provides 715 716 private Provides provides(String st, String pc) { 717 return ModuleDescriptor.newModule("foo") 718 .provides(st, List.of(pc)) 719 .build() 720 .provides() 721 .iterator() 722 .next(); 723 } 724 725 private Provides provides(String st, List<String> pns) { 726 return ModuleDescriptor.newModule("foo") 727 .provides(st, pns) 728 .build() 729 .provides() 730 .iterator() 731 .next(); 732 } 733 734 public void testProvidesWithProvides() { 735 Provides p1 = provides("p.S", "q.S1"); 736 ModuleDescriptor descriptor = ModuleDescriptor.newModule("m") 737 .provides(p1) 738 .build(); 739 Provides p2 = descriptor.provides().iterator().next(); 740 assertEquals(p1, p2); 741 } 742 743 744 public void testProvides() { 745 Set<Provides> set = ModuleDescriptor.newModule("foo") 746 .provides("p.S", List.of("q.P1", "q.P2")) 747 .build() 748 .provides(); 749 assertTrue(set.size() == 1); 750 751 Provides p = set.iterator().next(); 752 assertEquals(p, p); 753 assertEquals(p.service(), "p.S"); 754 assertTrue(p.providers().size() == 2); 755 assertEquals(p.providers().get(0), "q.P1"); 756 assertEquals(p.providers().get(1), "q.P2"); 757 } 758 759 @Test(expectedExceptions = IllegalStateException.class ) 760 public void testProvidesWithDuplicateProvides() { 761 Provides p = provides("p.S", "q.S2"); 762 ModuleDescriptor.newModule("m").provides("p.S", List.of("q.S1")).provides(p); 763 } 764 765 @Test(expectedExceptions = IllegalArgumentException.class ) 766 public void testProvidesWithEmptySet() { 767 ModuleDescriptor.newModule("foo").provides("p.Service", Collections.emptyList()); 768 } 769 770 @Test(expectedExceptions = IllegalArgumentException.class ) 771 public void testProvidesWithSimpleIdentifier1() { 772 ModuleDescriptor.newModule("foo").provides("S", List.of("q.P")); 773 } 774 775 @Test(expectedExceptions = IllegalArgumentException.class ) 776 public void testProvidesWithSimpleIdentifier2() { 777 ModuleDescriptor.newModule("foo").provides("p.S", List.of("P")); 778 } 779 780 @Test(dataProvider = "invalidNames", 781 expectedExceptions = IllegalArgumentException.class ) 782 public void testProvidesWithBadService(String service, String ignore) { 783 ModuleDescriptor.newModule("foo").provides(service, List.of("p.Provider")); 784 } 785 786 @Test(dataProvider = "invalidNames", 787 expectedExceptions = IllegalArgumentException.class ) 788 public void testProvidesWithBadProvider(String provider, String ignore) { 789 List<String> names = new ArrayList<>(); // allows nulls 790 names.add(provider); 791 ModuleDescriptor.newModule("foo").provides("p.Service", names); 792 } 793 794 @Test(expectedExceptions = NullPointerException.class ) 795 public void testProvidesWithNullProvides() { 796 ModuleDescriptor.newModule("foo").provides((Provides) null); 797 } 798 799 @Test(expectedExceptions = NullPointerException.class ) 800 public void testProvidesWithNullProviders() { 801 ModuleDescriptor.newModule("foo").provides("p.S", (List<String>) null); 802 } 803 804 public void testProvidesCompare() { 805 Provides p1 = provides("p.S", "q.S1"); 806 Provides p2 = provides("p.S", "q.S1"); 807 assertEquals(p1, p2); 808 assertTrue(p1.hashCode() == p2.hashCode()); 809 assertTrue(p1.compareTo(p2) == 0); 810 assertTrue(p2.compareTo(p1) == 0); 811 } 812 813 public void testProvidesCompareWithDifferentService() { 814 Provides p1 = provides("p.S2", "q.S1"); 815 Provides p2 = provides("p.S1", "q.S1"); 816 assertNotEquals(p1, p2); 817 assertTrue(p1.compareTo(p2) == 1); 818 assertTrue(p2.compareTo(p1) == -1); 819 } 820 821 public void testProvidesCompareWithDifferentProviders1() { 822 Provides p1 = provides("p.S", "q.S2"); 823 Provides p2 = provides("p.S", "q.S1"); 824 assertNotEquals(p1, p2); 825 assertTrue(p1.compareTo(p2) == 1); 826 assertTrue(p2.compareTo(p1) == -1); 827 } 828 829 public void testProvidesCompareWithDifferentProviders2() { 830 Provides p1 = provides("p.S", List.of("q.S1", "q.S2")); 831 Provides p2 = provides("p.S", "q.S1"); 832 assertNotEquals(p1, p2); 833 assertTrue(p1.compareTo(p2) == 1); 834 assertTrue(p2.compareTo(p1) == -1); 835 } 836 837 // packages 838 839 public void testPackages1() { 840 Set<String> packages = ModuleDescriptor.newModule("foo") 841 .packages(Set.of("p", "q")) 842 .build() 843 .packages(); 844 assertTrue(packages.size() == 2); 845 assertTrue(packages.contains("p")); 846 assertTrue(packages.contains("q")); 847 } 848 849 public void testPackages2() { 850 Set<String> packages = ModuleDescriptor.newModule("foo") 851 .packages(Set.of("p")) 852 .packages(Set.of("q")) 853 .build() 854 .packages(); 855 assertTrue(packages.size() == 2); 856 assertTrue(packages.contains("p")); 857 assertTrue(packages.contains("q")); 858 } 859 860 861 public void testPackagesWithEmptySet() { 862 Set<String> packages = ModuleDescriptor.newModule("foo") 863 .packages(Collections.emptySet()) 864 .build() 865 .packages(); 866 assertTrue(packages.size() == 0); 867 } 868 869 public void testPackagesDuplicate() { 870 Set<String> packages = ModuleDescriptor.newModule("foo") 871 .packages(Set.of("p")) 872 .packages(Set.of("p")) 873 .build() 874 .packages(); 875 assertTrue(packages.size() == 1); 876 assertTrue(packages.contains("p")); 877 } 878 879 public void testPackagesAndExportsPackage1() { 880 Set<String> packages = ModuleDescriptor.newModule("foo") 881 .packages(Set.of("p")) 882 .exports("p") 883 .build() 884 .packages(); 885 assertTrue(packages.size() == 1); 886 assertTrue(packages.contains("p")); 887 } 888 889 public void testPackagesAndExportsPackage2() { 890 Set<String> packages = ModuleDescriptor.newModule("foo") 891 .exports("p") 892 .packages(Set.of("p")) 893 .build() 894 .packages(); 895 assertTrue(packages.size() == 1); 896 assertTrue(packages.contains("p")); 897 } 898 899 public void testPackagesAndOpensPackage1() { 900 Set<String> packages = ModuleDescriptor.newModule("foo") 901 .packages(Set.of("p")) 902 .opens("p") 903 .build() 904 .packages(); 905 assertTrue(packages.size() == 1); 906 assertTrue(packages.contains("p")); 907 } 908 909 public void testPackagesAndOpensPackage2() { 910 Set<String> packages = ModuleDescriptor.newModule("foo") 911 .opens("p") 912 .packages(Set.of("p")) 913 .build() 914 .packages(); 915 assertTrue(packages.size() == 1); 916 assertTrue(packages.contains("p")); 917 } 918 919 public void testPackagesAndProvides1() { 920 Set<String> packages = ModuleDescriptor.newModule("foo") 921 .packages(Set.of("p")) 922 .provides("q.S", List.of("p.T")) 923 .build() 924 .packages(); 925 assertTrue(packages.size() == 1); 926 assertTrue(packages.contains("p")); 927 } 928 929 public void testPackagesAndProvides2() { 930 Set<String> packages = ModuleDescriptor.newModule("foo") 931 .provides("q.S", List.of("p.T")) 932 .packages(Set.of("p")) 933 .build() 934 .packages(); 935 assertTrue(packages.size() == 1); 936 assertTrue(packages.contains("p")); 937 } 938 939 public void testPackagesAndMainClass1() { 940 Set<String> packages = ModuleDescriptor.newModule("foo") 941 .packages(Set.of("p")) 942 .mainClass("p.Main") 943 .build() 944 .packages(); 945 assertTrue(packages.size() == 1); 946 assertTrue(packages.contains("p")); 947 } 948 949 public void testPackagesAndMainClass2() { 950 Set<String> packages = ModuleDescriptor.newModule("foo") 951 .mainClass("p.Main") 952 .packages(Set.of("p")) 953 .build() 954 .packages(); 955 assertTrue(packages.size() == 1); 956 assertTrue(packages.contains("p")); 957 } 958 959 public void testPackagesAndAll() { 960 Set<String> packages = ModuleDescriptor.newModule("foo") 961 .exports("p1") 962 .opens("p2") 963 .packages(Set.of("p3")) 964 .provides("q.S", List.of("p4.T")) 965 .mainClass("p5.Main") 966 .build() 967 .packages(); 968 assertTrue(Objects.equals(packages, Set.of("p1", "p2", "p3", "p4", "p5"))); 969 } 970 971 @Test(dataProvider = "invalidNames", 972 expectedExceptions = IllegalArgumentException.class ) 973 public void testPackagesWithBadName(String pn, String ignore) { 974 Set<String> pkgs = new HashSet<>(); // allows nulls 975 pkgs.add(pn); 976 ModuleDescriptor.newModule("foo").packages(pkgs); 977 } 978 979 // name 980 981 public void testModuleName() { 982 String mn = ModuleDescriptor.newModule("foo").build().name(); 983 assertEquals(mn, "foo"); 984 } 985 986 @Test(dataProvider = "invalidNames", 987 expectedExceptions = IllegalArgumentException.class ) 988 public void testBadModuleName(String mn, String ignore) { 989 ModuleDescriptor.newModule(mn); 990 } 991 992 993 // version 994 995 public void testVersion1() { 996 Version v1 = Version.parse("1.0"); 997 Version v2 = ModuleDescriptor.newModule("foo") 998 .version(v1) 999 .build() 1000 .version() 1001 .get(); 1002 assertEquals(v1, v2); 1003 } 1004 1005 public void testVersion2() { 1006 String vs = "1.0"; 1007 Version v1 = ModuleDescriptor.newModule("foo") 1008 .version(vs) 1009 .build() 1010 .version() 1011 .get(); 1012 Version v2 = Version.parse(vs); 1013 assertEquals(v1, v2); 1014 } 1015 1016 @Test(expectedExceptions = NullPointerException.class ) 1017 public void testNullVersion1() { 1018 ModuleDescriptor.newModule("foo").version((Version) null); 1019 } 1020 1021 @Test(expectedExceptions = IllegalArgumentException.class ) 1022 public void testNullVersion2() { 1023 ModuleDescriptor.newModule("foo").version((String) null); 1024 } 1025 1026 @Test(expectedExceptions = IllegalArgumentException.class ) 1027 public void testEmptyVersion() { 1028 ModuleDescriptor.newModule("foo").version(""); 1029 } 1030 1031 1032 @DataProvider(name = "unparseableVersions") 1033 public Object[][] unparseableVersions() { 1034 return new Object[][]{ 1035 1036 { null, "A1" }, // no version < unparseable 1037 { "A1", "A2" }, // unparseable < unparseable 1038 { "A1", "1.0" }, // unparseable < parseable 1039 1040 }; 1041 } 1042 1043 /** 1044 * Basic test for unparseable module versions 1045 */ 1046 @Test(dataProvider = "unparseableVersions") 1047 public void testUnparseableModuleVersion(String vs1, String vs2) { 1048 ModuleDescriptor descriptor1 = newModule("m", vs1); 1049 ModuleDescriptor descriptor2 = newModule("m", vs2); 1050 1051 if (vs1 != null && !isParsableVersion(vs1)) { 1052 assertFalse(descriptor1.version().isPresent()); 1053 assertTrue(descriptor1.rawVersion().isPresent()); 1054 assertEquals(descriptor1.rawVersion().get(), vs1); 1055 } 1056 1057 if (vs2 != null && !isParsableVersion(vs2)) { 1058 assertFalse(descriptor2.version().isPresent()); 1059 assertTrue(descriptor2.rawVersion().isPresent()); 1060 assertEquals(descriptor2.rawVersion().get(), vs2); 1061 } 1062 1063 assertFalse(descriptor1.equals(descriptor2)); 1064 assertFalse(descriptor2.equals(descriptor1)); 1065 assertTrue(descriptor1.compareTo(descriptor2) == -1); 1066 assertTrue(descriptor2.compareTo(descriptor1) == 1); 1067 } 1068 1069 /** 1070 * Basic test for requiring a module with an unparseable version recorded 1071 * at compile version. 1072 */ 1073 @Test(dataProvider = "unparseableVersions") 1074 public void testUnparseableCompiledVersion(String vs1, String vs2) { 1075 Requires r1 = newRequires("m", vs1); 1076 Requires r2 = newRequires("m", vs2); 1077 1078 if (vs1 != null && !isParsableVersion(vs1)) { 1079 assertFalse(r1.compiledVersion().isPresent()); 1080 assertTrue(r1.rawCompiledVersion().isPresent()); 1081 assertEquals(r1.rawCompiledVersion().get(), vs1); 1082 } 1083 1084 if (vs2 != null && !isParsableVersion(vs2)) { 1085 assertFalse(r2.compiledVersion().isPresent()); 1086 assertTrue(r2.rawCompiledVersion().isPresent()); 1087 assertEquals(r2.rawCompiledVersion().get(), vs2); 1088 } 1089 1090 assertFalse(r1.equals(r2)); 1091 assertFalse(r2.equals(r1)); 1092 assertTrue(r1.compareTo(r2) == -1); 1093 assertTrue(r2.compareTo(r1) == 1); 1094 } 1095 1096 private ModuleDescriptor newModule(String name, String vs) { 1097 Builder builder = JLMA.newModuleBuilder(name, false, Set.of()); 1098 if (vs != null) 1099 builder.version(vs); 1100 builder.requires("java.base"); 1101 ByteBuffer bb = ModuleInfoWriter.toByteBuffer(builder.build()); 1102 return ModuleDescriptor.read(bb); 1103 } 1104 1105 private Requires newRequires(String name, String vs) { 1106 Builder builder = JLMA.newModuleBuilder("foo", false, Set.of()); 1107 if (vs == null) { 1108 builder.requires(name); 1109 } else { 1110 JLMA.requires(builder, Set.of(), name, vs); 1111 } 1112 Set<ModuleDescriptor.Requires> requires = builder.build().requires(); 1113 Iterator<ModuleDescriptor.Requires> iterator = requires.iterator(); 1114 ModuleDescriptor.Requires r = iterator.next(); 1115 if (r.name().equals("java.base")) { 1116 r = iterator.next(); 1117 } 1118 return r; 1119 } 1120 1121 private boolean isParsableVersion(String vs) { 1122 try { 1123 Version.parse(vs); 1124 return true; 1125 } catch (IllegalArgumentException e) { 1126 return false; 1127 } 1128 } 1129 1130 1131 // toNameAndVersion 1132 1133 public void testToNameAndVersion() { 1134 ModuleDescriptor md1 = ModuleDescriptor.newModule("foo").build(); 1135 assertEquals(md1.toNameAndVersion(), "foo"); 1136 1137 ModuleDescriptor md2 = ModuleDescriptor.newModule("foo").version("1.0").build(); 1138 assertEquals(md2.toNameAndVersion(), "foo@1.0"); 1139 } 1140 1141 1142 // open modules 1143 1144 public void testOpenModule() { 1145 ModuleDescriptor descriptor = ModuleDescriptor.newOpenModule("foo") 1146 .requires("bar") 1147 .exports("p") 1148 .provides("p.Service", List.of("q.ServiceImpl")) 1149 .build(); 1150 1151 // modifiers 1152 assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.OPEN)); 1153 assertTrue(descriptor.isOpen()); 1154 1155 // requires 1156 assertTrue(descriptor.requires().size() == 2); 1157 Set<String> names = descriptor.requires() 1158 .stream() 1159 .map(Requires::name) 1160 .collect(Collectors.toSet()); 1161 assertEquals(names, Set.of("bar", "java.base")); 1162 1163 // packages 1164 assertEquals(descriptor.packages(), Set.of("p", "q")); 1165 1166 // exports 1167 assertTrue(descriptor.exports().size() == 1); 1168 names = descriptor.exports() 1169 .stream() 1170 .map(Exports::source) 1171 .collect(Collectors.toSet()); 1172 assertEquals(names, Set.of("p")); 1173 1174 // opens 1175 assertTrue(descriptor.opens().isEmpty()); 1176 } 1177 1178 @Test(expectedExceptions = IllegalStateException.class) 1179 public void testOpensOnOpenModule1() { 1180 ModuleDescriptor.newOpenModule("foo").opens("p"); 1181 } 1182 1183 @Test(expectedExceptions = IllegalStateException.class) 1184 public void testOpensOnOpenModule2() { 1185 ModuleDescriptor.newOpenModule("foo").opens("p", Set.of("bar")); 1186 } 1187 1188 public void testIsOpen() { 1189 assertFalse(ModuleDescriptor.newModule("m").build().isOpen()); 1190 assertFalse(ModuleDescriptor.newAutomaticModule("m").build().isOpen()); 1191 assertTrue(ModuleDescriptor.newOpenModule("m").build().isOpen()); 1192 } 1193 1194 1195 // automatic modules 1196 1197 public void testAutomaticModule() { 1198 ModuleDescriptor descriptor = ModuleDescriptor.newAutomaticModule("foo") 1199 .packages(Set.of("p")) 1200 .provides("p.Service", List.of("q.ServiceImpl")) 1201 .build(); 1202 1203 // modifiers 1204 assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.AUTOMATIC)); 1205 assertTrue(descriptor.isAutomatic()); 1206 1207 // requires 1208 assertTrue(descriptor.requires().size() == 1); 1209 Set<String> names = descriptor.requires() 1210 .stream() 1211 .map(Requires::name) 1212 .collect(Collectors.toSet()); 1213 assertEquals(names, Set.of("java.base")); 1214 1215 // packages 1216 assertEquals(descriptor.packages(), Set.of("p", "q")); 1217 assertTrue(descriptor.exports().isEmpty()); 1218 assertTrue(descriptor.opens().isEmpty()); 1219 } 1220 1221 @Test(expectedExceptions = IllegalStateException.class) 1222 public void testRequiresOnAutomaticModule() { 1223 ModuleDescriptor.newAutomaticModule("foo").requires("java.base"); 1224 } 1225 1226 @Test(expectedExceptions = IllegalStateException.class) 1227 public void testExportsOnAutomaticModule1() { 1228 ModuleDescriptor.newAutomaticModule("foo").exports("p"); 1229 } 1230 1231 @Test(expectedExceptions = IllegalStateException.class) 1232 public void testExportsOnAutomaticModule2() { 1233 ModuleDescriptor.newAutomaticModule("foo").exports("p", Set.of("bar")); 1234 } 1235 1236 @Test(expectedExceptions = IllegalStateException.class) 1237 public void testOpensOnAutomaticModule1() { 1238 ModuleDescriptor.newAutomaticModule("foo").opens("p"); 1239 } 1240 1241 @Test(expectedExceptions = IllegalStateException.class) 1242 public void testOpensOnAutomaticModule2() { 1243 ModuleDescriptor.newAutomaticModule("foo").opens("p", Set.of("bar")); 1244 } 1245 1246 @Test(expectedExceptions = IllegalStateException.class) 1247 public void testUsesOnAutomaticModule() { 1248 ModuleDescriptor.newAutomaticModule("foo").uses("p.Service"); 1249 } 1250 1251 public void testIsAutomatic() { 1252 ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("foo").build(); 1253 assertFalse(descriptor1.isAutomatic()); 1254 1255 ModuleDescriptor descriptor2 = ModuleDescriptor.newOpenModule("foo").build(); 1256 assertFalse(descriptor2.isAutomatic()); 1257 1258 ModuleDescriptor descriptor3 = ModuleDescriptor.newAutomaticModule("foo").build(); 1259 assertTrue(descriptor3.isAutomatic()); 1260 } 1261 1262 1263 // newModule with modifiers 1264 1265 public void testNewModuleToBuildAutomaticModule() { 1266 Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.AUTOMATIC); 1267 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build(); 1268 assertTrue(descriptor.modifiers().equals(ms)); 1269 assertTrue(descriptor.isAutomatic()); 1270 } 1271 1272 public void testNewModuleToBuildOpenModule() { 1273 Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.OPEN); 1274 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build(); 1275 assertTrue(descriptor.modifiers().equals(ms)); 1276 assertTrue(descriptor.isOpen()); 1277 1278 ms = Set.of(ModuleDescriptor.Modifier.OPEN, ModuleDescriptor.Modifier.SYNTHETIC); 1279 descriptor = ModuleDescriptor.newModule("foo", ms).build(); 1280 assertTrue(descriptor.modifiers().equals(ms)); 1281 assertTrue(descriptor.isOpen()); 1282 } 1283 1284 @Test(expectedExceptions = IllegalArgumentException.class) 1285 public void testNewModuleToBuildAutomaticAndOpenModule() { 1286 Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.AUTOMATIC, 1287 ModuleDescriptor.Modifier.OPEN); 1288 ModuleDescriptor.newModule("foo", ms); 1289 } 1290 1291 1292 // mainClass 1293 1294 public void testMainClass() { 1295 String mainClass 1296 = ModuleDescriptor.newModule("foo").mainClass("p.Main").build().mainClass().get(); 1297 assertEquals(mainClass, "p.Main"); 1298 } 1299 1300 @Test(expectedExceptions = IllegalArgumentException.class) 1301 public void testMainClassWithSimpleIdentifier() { 1302 ModuleDescriptor.newModule("foo").mainClass("Main"); 1303 } 1304 1305 @Test(dataProvider = "invalidNames", 1306 expectedExceptions = IllegalArgumentException.class ) 1307 public void testMainClassWithBadName(String mainClass, String ignore) { 1308 Builder builder = ModuleDescriptor.newModule("foo"); 1309 builder.mainClass(mainClass); 1310 } 1311 1312 1313 // reads 1314 1315 private static InputStream EMPTY_INPUT_STREAM = new InputStream() { 1316 @Override 1317 public int read() { 1318 return -1; 1319 } 1320 }; 1321 1322 private static InputStream FAILING_INPUT_STREAM = new InputStream() { 1323 @Override 1324 public int read() throws IOException { 1325 throw new IOException(); 1326 } 1327 }; 1328 1329 /** 1330 * Basic test reading module-info.class 1331 */ 1332 public void testRead() throws Exception { 1333 Module base = Object.class.getModule(); 1334 1335 try (InputStream in = base.getResourceAsStream("module-info.class")) { 1336 ModuleDescriptor descriptor = ModuleDescriptor.read(in); 1337 assertTrue(in.read() == -1); // all bytes read 1338 assertEquals(descriptor.name(), "java.base"); 1339 } 1340 1341 try (InputStream in = base.getResourceAsStream("module-info.class")) { 1342 ByteBuffer bb = ByteBuffer.wrap(in.readAllBytes()); 1343 ModuleDescriptor descriptor = ModuleDescriptor.read(bb); 1344 assertFalse(bb.hasRemaining()); // no more remaining bytes 1345 assertEquals(descriptor.name(), "java.base"); 1346 } 1347 } 1348 1349 /** 1350 * Test ModuleDescriptor with a packager finder 1351 */ 1352 public void testReadsWithPackageFinder() throws Exception { 1353 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo") 1354 .requires("java.base") 1355 .build(); 1356 1357 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1358 ModuleInfoWriter.write(descriptor, baos); 1359 ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray()); 1360 1361 descriptor = ModuleDescriptor.read(bb, () -> Set.of("p", "q")); 1362 1363 assertTrue(descriptor.packages().size() == 2); 1364 assertTrue(descriptor.packages().contains("p")); 1365 assertTrue(descriptor.packages().contains("q")); 1366 } 1367 1368 /** 1369 * Test ModuleDescriptor with a packager finder that doesn't return the 1370 * complete set of packages. 1371 */ 1372 public void testReadsWithBadPackageFinder() throws Exception { 1373 ByteBuffer bb = ByteBuffer.wrap(ClassFile.of().buildModule( 1374 ModuleAttribute.of( 1375 ModuleDesc.of("foo"), 1376 mb -> mb.requires(ModuleDesc.of("java.base"), 0, null) 1377 .exports(PackageDesc.of("p"), 0)))); 1378 1379 // package finder returns a set that doesn't include p 1380 assertThrows(InvalidModuleDescriptorException.class, 1381 () -> ModuleDescriptor.read(bb, () -> Set.of("q"))); 1382 } 1383 1384 @Test(expectedExceptions = InvalidModuleDescriptorException.class) 1385 public void testReadFromEmptyInputStream() throws Exception { 1386 ModuleDescriptor.read(EMPTY_INPUT_STREAM); 1387 } 1388 1389 @Test(expectedExceptions = IOException.class) 1390 public void testReadFromFailingInputStream() throws Exception { 1391 ModuleDescriptor.read(FAILING_INPUT_STREAM); 1392 } 1393 1394 @Test(expectedExceptions = InvalidModuleDescriptorException.class) 1395 public void testReadFromEmptyBuffer() { 1396 ByteBuffer bb = ByteBuffer.allocate(0); 1397 ModuleDescriptor.read(bb); 1398 } 1399 1400 /** 1401 * Test ModuleDescriptor.read reading a module-info for java.base that has a non-0 1402 * length requires table. 1403 */ 1404 public void testReadOfJavaBaseWithRequires() { 1405 ModuleDescriptor descriptor = ModuleDescriptor.newModule("java.base") 1406 .requires("other") 1407 .build(); 1408 ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor); 1409 assertThrows(InvalidModuleDescriptorException.class, 1410 () -> ModuleDescriptor.read(bb)); 1411 } 1412 1413 /** 1414 * Test ModuleDescriptor.read reading a module-info with a zero length requires table 1415 * (no entry for java.base). 1416 */ 1417 public void testReadWithEmptyRequires() { 1418 // use non-strict builder to create module that does not require java.base 1419 ModuleDescriptor descriptor = JLMA.newModuleBuilder("m", false, Set.of()).build(); 1420 ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor); 1421 assertThrows(InvalidModuleDescriptorException.class, 1422 () -> ModuleDescriptor.read(bb)); 1423 } 1424 1425 /** 1426 * Test ModuleDescriptor.read reading a module-info with a non-zero length requires 1427 * table that does not have entry for java.base. 1428 */ 1429 public void testReadWithNoRequiresBase() { 1430 // use non-strict builder to create module that does not require java.base 1431 ModuleDescriptor descriptor = JLMA.newModuleBuilder("m1", false, Set.of()) 1432 .requires("m2") 1433 .build(); 1434 ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor); 1435 assertThrows(InvalidModuleDescriptorException.class, 1436 () -> ModuleDescriptor.read(bb)); 1437 } 1438 1439 /** 1440 * Test ModuleDescriptor.read reading a module-info with a requires entry for 1441 * java.base with the ACC_SYNTHETIC flag set. 1442 */ 1443 public void testReadWithSynethticRequiresBase() { 1444 ModuleDescriptor descriptor = ModuleDescriptor.newModule("m") 1445 .requires(Set.of(SYNTHETIC), "java.base") 1446 .build(); 1447 ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor); 1448 assertThrows(InvalidModuleDescriptorException.class, 1449 () -> ModuleDescriptor.read(bb)); 1450 } 1451 1452 /** 1453 * Test ModuleDescriptor.read with a null parameter. 1454 */ 1455 public void testReadWithNull() throws Exception { 1456 Module base = Object.class.getModule(); 1457 1458 assertThrows(NullPointerException.class, 1459 () -> ModuleDescriptor.read((InputStream) null)); 1460 assertThrows(NullPointerException.class, 1461 () -> ModuleDescriptor.read((ByteBuffer) null)); 1462 1463 try (InputStream in = base.getResourceAsStream("module-info.class")) { 1464 assertThrows(NullPointerException.class, 1465 () -> ModuleDescriptor.read(in, null)); 1466 1467 ByteBuffer bb = ByteBuffer.wrap(in.readAllBytes()); 1468 assertThrows(NullPointerException.class, 1469 () -> ModuleDescriptor.read(bb, null)); 1470 } 1471 } 1472 1473 1474 // equals/hashCode/compareTo/toString 1475 1476 public void testEqualsAndHashCode() { 1477 ModuleDescriptor md1 = ModuleDescriptor.newModule("m").build(); 1478 ModuleDescriptor md2 = ModuleDescriptor.newModule("m").build(); 1479 assertEquals(md1, md1); 1480 assertEquals(md1.hashCode(), md2.hashCode()); 1481 assertTrue(md1.compareTo(md2) == 0); 1482 assertTrue(md2.compareTo(md1) == 0); 1483 } 1484 1485 @DataProvider(name = "sortedModuleDescriptors") 1486 public Object[][] sortedModuleDescriptors() { 1487 return new Object[][]{ 1488 1489 { ModuleDescriptor.newModule("m2").build(), 1490 ModuleDescriptor.newModule("m1").build() 1491 }, 1492 1493 { ModuleDescriptor.newModule("m").version("2").build(), 1494 ModuleDescriptor.newModule("m").version("1").build() 1495 }, 1496 1497 { ModuleDescriptor.newModule("m").version("1").build(), 1498 ModuleDescriptor.newModule("m").build() 1499 }, 1500 1501 { ModuleDescriptor.newOpenModule("m").build(), 1502 ModuleDescriptor.newModule("m").build() 1503 }, 1504 1505 }; 1506 } 1507 1508 @Test(dataProvider = "sortedModuleDescriptors") 1509 public void testCompare(ModuleDescriptor md1, ModuleDescriptor md2) { 1510 assertNotEquals(md1, md2); 1511 assertTrue(md1.compareTo(md2) == 1); 1512 assertTrue(md2.compareTo(md1) == -1); 1513 } 1514 1515 public void testToString() { 1516 String s = ModuleDescriptor.newModule("m1") 1517 .requires("m2") 1518 .exports("p1") 1519 .build() 1520 .toString(); 1521 assertTrue(s.contains("m1")); 1522 assertTrue(s.contains("m2")); 1523 assertTrue(s.contains("p1")); 1524 } 1525 1526 @Test(expectedExceptions = InvalidModuleDescriptorException.class) 1527 public void testRequiresTransitiveJavaBaseNotPermitted1() throws Exception { 1528 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo") 1529 .requires(Set.of(Modifier.TRANSITIVE), "java.base") 1530 .build(); 1531 1532 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1533 ModuleInfoWriter.write(descriptor, baos); 1534 ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray()); 1535 1536 ModuleDescriptor.read(bb, () -> Set.of("p", "q")); 1537 } 1538 1539 @Test(expectedExceptions = InvalidModuleDescriptorException.class) 1540 public void testRequiresTransitiveJavaBaseNotPermitted2() throws Exception { 1541 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo") 1542 .requires(Set.of(Modifier.TRANSITIVE), "java.base") 1543 .build(); 1544 1545 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1546 ModuleInfoWriter.write(descriptor, baos); 1547 byte[] bytecode = baos.toByteArray(); 1548 ByteBuffer bb = ByteBuffer.wrap(bytecode); 1549 setClassFileVersion(bb, ClassFile.JAVA_21_VERSION, -1); 1550 1551 ModuleDescriptor.read(bb, () -> Set.of("p", "q")); 1552 } 1553 1554 public void testRequiresTransitiveJavaBasePermitted() throws Exception { 1555 ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo") 1556 .requires(Set.of(Modifier.TRANSITIVE), "java.base") 1557 .build(); 1558 1559 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1560 ModuleInfoWriter.write(descriptor, baos); 1561 byte[] bytecode = baos.toByteArray(); 1562 ByteBuffer bb = ByteBuffer.wrap(bytecode); 1563 setClassFileVersion(bb, -1, ClassFile.PREVIEW_MINOR_VERSION); 1564 1565 descriptor = ModuleDescriptor.read(bb, () -> Set.of("p", "q")); 1566 1567 assertEquals(descriptor.requires().size(), 1); 1568 Requires javaBase = descriptor.requires().iterator().next(); 1569 assertEquals(javaBase.name(), "java.base"); 1570 assertEquals(javaBase.modifiers(), Set.of(Modifier.TRANSITIVE)); 1571 } 1572 1573 /**Change the classfile versions of the provided classfile to the provided 1574 * values. 1575 * 1576 * @param bytecode the classfile content to modify 1577 * @param major the major classfile version to set, 1578 * -1 if the existing version should be kept 1579 * @param minor the minor classfile version to set, 1580 * -1 if the existing version should be kept 1581 */ 1582 private void setClassFileVersion(ByteBuffer bb, int major, int minor) { 1583 if (minor != (-1)) { 1584 bb.putShort(4, (short) minor); 1585 } 1586 if (major != (-1)) { 1587 bb.putShort(6, (short) major); 1588 } 1589 } 1590 }