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