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