1 /*
   2  * Copyright (c) 2013, 2016, 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/java.lang.module:open
  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.lang.reflect.Constructor;
  45 import java.lang.reflect.Module;
  46 import java.nio.ByteBuffer;
  47 import java.util.Collections;
  48 import java.util.EnumSet;
  49 import java.util.HashSet;
  50 import java.util.List;
  51 import java.util.Map;
  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.module.ModuleInfoWriter;
  58 import org.testng.annotations.DataProvider;
  59 import org.testng.annotations.Test;
  60 import static org.testng.Assert.*;
  61 
  62 @Test
  63 public class ModuleDescriptorTest {
  64 
  65     @DataProvider(name = "invalidjavaidentifiers")
  66     public Object[][] invalidJavaIdentifiers() {
  67         return new Object[][]{
  68 
  69             { null,         null },
  70             { ".foo",       null },
  71             { "foo.",       null },
  72             { "[foo]",      null },
  73 
  74         };
  75     }
  76 
  77 
  78     // requires
  79 
  80     private Requires requires(Set<Modifier> mods, String mn) {
  81         return ModuleDescriptor.module("m")
  82             .requires(mods, mn)
  83             .build()
  84             .requires()
  85             .iterator()
  86             .next();
  87     }
  88 
  89     private Requires requires(String mn) {
  90         return requires(Collections.emptySet(), mn);
  91     }
  92 
  93     public void testRequiresWithRequires() {
  94         Requires r1 = requires("foo");
  95         ModuleDescriptor descriptor = ModuleDescriptor.module("m").requires(r1).build();
  96         Requires r2 = descriptor.requires().iterator().next();
  97         assertEquals(r1, r2);
  98     }
  99 
 100     public void testRequiresWithNoModifiers() {
 101         Requires r = requires(EnumSet.noneOf(Requires.Modifier.class), "foo");
 102         assertEquals(r, r);
 103         assertTrue(r.compareTo(r) == 0);
 104         assertTrue(r.modifiers().isEmpty());
 105         assertEquals(r.name(), "foo");
 106     }
 107 
 108     public void testRequiresWithOneModifier() {
 109         Requires r = requires(EnumSet.of(TRANSITIVE), "foo");
 110         assertEquals(r, r);
 111         assertTrue(r.compareTo(r) == 0);
 112         assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE));
 113         assertEquals(r.name(), "foo");
 114     }
 115 
 116     public void testRequiresWithTwoModifiers() {
 117         Requires r = requires(EnumSet.of(TRANSITIVE, SYNTHETIC), "foo");
 118         assertEquals(r, r);
 119         assertTrue(r.compareTo(r) == 0);
 120         assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, SYNTHETIC));
 121         assertEquals(r.name(), "foo");
 122     }
 123 
 124     public void testRequiresWithAllModifiers() {
 125         Requires r = requires(EnumSet.allOf(Modifier.class), "foo");
 126         assertEquals(r, r);
 127         assertTrue(r.compareTo(r) == 0);
 128         assertEquals(r.modifiers(), EnumSet.of(TRANSITIVE, STATIC, SYNTHETIC, MANDATED));
 129         assertEquals(r.name(), "foo");
 130     }
 131 
 132     @Test(expectedExceptions = IllegalStateException.class)
 133     public void testRequiresWithDuplicatesRequires() {
 134         Requires r = requires("foo");
 135         ModuleDescriptor.module("m").requires(r).requires(r);
 136     }
 137 
 138     @Test(expectedExceptions = IllegalArgumentException.class)
 139     public void testRequiresSelfWithRequires() {
 140         Requires r = requires("foo");
 141         ModuleDescriptor.module("foo").requires(r);
 142     }
 143 
 144     @Test(expectedExceptions = IllegalArgumentException.class)
 145     public void testRequiresSelfWithNoModifier() {
 146         ModuleDescriptor.module("m").requires("m");
 147     }
 148 
 149     @Test(expectedExceptions = IllegalArgumentException.class)
 150     public void testRequiresSelfWithOneModifier() {
 151         ModuleDescriptor.module("m").requires(Set.of(TRANSITIVE), "m");
 152     }
 153 
 154     @Test(expectedExceptions = IllegalArgumentException.class)
 155     public void testRequiresSelfWithAllModifiers() {
 156         ModuleDescriptor.module("m").requires(EnumSet.allOf(Modifier.class), "m");
 157     }
 158 
 159     @Test(dataProvider = "invalidjavaidentifiers",
 160           expectedExceptions = IllegalArgumentException.class )
 161     public void testRequiresWithBadModuleName(String mn, String ignore) {
 162         requires(EnumSet.noneOf(Modifier.class), mn);
 163     }
 164 
 165     @Test(expectedExceptions = NullPointerException.class)
 166     public void testRequiresWithNullRequires() {
 167         ModuleDescriptor.module("m").requires((Requires) null);
 168     }
 169 
 170     public void testRequiresCompare() {
 171         Requires r1 = requires(EnumSet.noneOf(Modifier.class), "foo");
 172         Requires r2 = requires(EnumSet.noneOf(Modifier.class), "bar");
 173         int n = "foo".compareTo("bar");
 174         assertTrue(r1.compareTo(r2) == n);
 175         assertTrue(r2.compareTo(r1) == -n);
 176     }
 177 
 178     public void testRequiresCompareWithDifferentModifiers() {
 179         Requires r1 = requires(EnumSet.of(TRANSITIVE), "foo");
 180         Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo");
 181         int n = Integer.compare(1 << TRANSITIVE.ordinal(), 1 << SYNTHETIC.ordinal());
 182         assertTrue(r1.compareTo(r2) == n);
 183         assertTrue(r2.compareTo(r1) == -n);
 184     }
 185 
 186     public void testRequiresCompareWithSameModifiers() {
 187         Requires r1 = requires(EnumSet.of(SYNTHETIC), "foo");
 188         Requires r2 = requires(EnumSet.of(SYNTHETIC), "foo");
 189         assertTrue(r1.compareTo(r2) == 0);
 190         assertTrue(r2.compareTo(r1) == 0);
 191     }
 192 
 193     public void testRequiresEqualsAndHashCode() {
 194         Requires r1 = requires("foo");
 195         Requires r2 = requires("foo");
 196         assertEquals(r1, r2);
 197         assertTrue(r1.hashCode() == r2.hashCode());
 198 
 199         r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
 200         r2 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
 201         assertEquals(r1, r2);
 202         assertTrue(r1.hashCode() == r2.hashCode());
 203 
 204         r1 = requires("foo");
 205         r2 = requires("bar");
 206         assertNotEquals(r1, r2);
 207 
 208         r1 = requires(EnumSet.allOf(Requires.Modifier.class), "foo");
 209         r2 = requires(Set.of(), "foo");
 210         assertNotEquals(r1, r2);
 211     }
 212 
 213     public void testRequiresToString() {
 214         Requires r = requires(EnumSet.noneOf(Modifier.class), "foo");
 215         assertTrue(r.toString().contains("foo"));
 216     }
 217 
 218 
 219     // exports
 220 
 221     private Exports exports(Set<Exports.Modifier> mods, String pn) {
 222         return ModuleDescriptor.module("foo")
 223             .exports(mods, pn)
 224             .build()
 225             .exports()
 226             .iterator()
 227             .next();
 228     }
 229 
 230     private Exports exports(String pn) {
 231         return exports(Set.of(), pn);
 232     }
 233 
 234     private Exports exports(Set<Exports.Modifier> mods, String pn, String target) {
 235         return ModuleDescriptor.module("foo")
 236             .exports(mods, pn, Set.of(target))
 237             .build()
 238             .exports()
 239             .iterator()
 240             .next();
 241     }
 242 
 243     private Exports exports(String pn, String target) {
 244         return exports(Set.of(), pn, target);
 245     }
 246 
 247 
 248     public void testExportsExports() {
 249         Exports e1 = exports("p");
 250         ModuleDescriptor descriptor = ModuleDescriptor.module("m").exports(e1).build();
 251         Exports e2 = descriptor.exports().iterator().next();
 252         assertEquals(e1, e2);
 253     }
 254 
 255     public void testExportsToAll() {
 256         Exports e = exports("p");
 257         assertEquals(e, e);
 258         assertTrue(e.modifiers().isEmpty());
 259         assertEquals(e.source(), "p");
 260         assertFalse(e.isQualified());
 261         assertTrue(e.targets().isEmpty());
 262     }
 263 
 264     public void testExportsToTarget() {
 265         Exports e = exports("p", "bar");
 266         assertEquals(e, e);
 267         assertTrue(e.modifiers().isEmpty());
 268         assertEquals(e.source(), "p");
 269         assertTrue(e.isQualified());
 270         assertTrue(e.targets().size() == 1);
 271         assertTrue(e.targets().contains("bar"));
 272     }
 273 
 274     public void testExportsToTargets() {
 275         Set<String> targets = new HashSet<>();
 276         targets.add("bar");
 277         targets.add("gus");
 278         Exports e
 279             = ModuleDescriptor.module("foo")
 280                 .exports("p", targets)
 281                 .build()
 282                 .exports()
 283                 .iterator()
 284                 .next();
 285         assertEquals(e, e);
 286         assertTrue(e.modifiers().isEmpty());
 287         assertEquals(e.source(), "p");
 288         assertTrue(e.isQualified());
 289         assertTrue(e.targets().size() == 2);
 290         assertTrue(e.targets().contains("bar"));
 291         assertTrue(e.targets().contains("gus"));
 292     }
 293 
 294     public void testExportsToAllWithModifier() {
 295         Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
 296         assertEquals(e, e);
 297         assertTrue(e.modifiers().size() == 1);
 298         assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
 299         assertEquals(e.source(), "p");
 300         assertFalse(e.isQualified());
 301         assertTrue(e.targets().isEmpty());
 302     }
 303 
 304     public void testExportsToTargetWithModifier() {
 305         Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p", "bar");
 306         assertEquals(e, e);
 307         assertTrue(e.modifiers().size() == 1);
 308         assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
 309         assertEquals(e.source(), "p");
 310         assertTrue(e.isQualified());
 311         assertTrue(e.targets().size() == 1);
 312         assertTrue(e.targets().contains("bar"));
 313     }
 314 
 315     @Test(expectedExceptions = IllegalStateException.class)
 316     public void testExportsWithDuplicate1() {
 317         Exports e = exports("p");
 318         ModuleDescriptor.module("foo").exports(e).exports(e);
 319     }
 320 
 321     @Test(expectedExceptions = IllegalStateException.class)
 322     public void testExportsWithDuplicate2() {
 323         ModuleDescriptor.module("foo").exports("p").exports("p");
 324     }
 325 
 326     @Test(expectedExceptions = IllegalStateException.class)
 327     public void testExportsOnContainedPackage() {
 328         ModuleDescriptor.module("foo").contains("p").exports("p");
 329     }
 330 
 331     @Test(expectedExceptions = IllegalStateException.class)
 332     public void testExportsToTargetOnContainedPackage() {
 333         ModuleDescriptor.module("foo").contains("p").exports("p", Set.of("bar"));
 334     }
 335 
 336     @Test(expectedExceptions = IllegalArgumentException.class )
 337     public void testExportsWithEmptySet() {
 338         ModuleDescriptor.module("foo").exports("p", Collections.emptySet());
 339     }
 340 
 341     @Test(dataProvider = "invalidjavaidentifiers",
 342           expectedExceptions = IllegalArgumentException.class )
 343     public void testExportsWithBadName(String pn, String ignore) {
 344         ModuleDescriptor.module("foo").exports(pn);
 345     }
 346 
 347     @Test(expectedExceptions = NullPointerException.class )
 348     public void testExportsWithNullExports() {
 349         ModuleDescriptor.module("foo").exports((Exports) null);
 350     }
 351 
 352     @Test(expectedExceptions = NullPointerException.class )
 353     public void testExportsWithNullTargets() {
 354         ModuleDescriptor.module("foo").exports("p", (Set<String>) null);
 355     }
 356 
 357     public void testExportsEqualsAndHashCode() {
 358         Exports e1, e2;
 359 
 360         e1 = exports("p");
 361         e2 = exports("p");
 362         assertEquals(e1, e2);
 363         assertTrue(e1.hashCode() == e2.hashCode());
 364 
 365         e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
 366         e2 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
 367         assertEquals(e1, e2);
 368         assertTrue(e1.hashCode() == e2.hashCode());
 369 
 370         e1 = exports("p");
 371         e2 = exports("q");
 372         assertNotEquals(e1, e2);
 373 
 374         e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
 375         e2 = exports(Set.of(), "p");
 376         assertNotEquals(e1, e2);
 377     }
 378 
 379     public void testExportsToString() {
 380         String s = ModuleDescriptor.module("foo")
 381             .exports("p1", Set.of("bar"))
 382             .build()
 383             .exports()
 384             .iterator()
 385             .next()
 386             .toString();
 387         assertTrue(s.contains("p1"));
 388         assertTrue(s.contains("bar"));
 389     }
 390 
 391 
 392     // opens
 393 
 394     private Opens opens(Set<Opens.Modifier> mods, String pn) {
 395         return ModuleDescriptor.module("foo")
 396                 .opens(mods, pn)
 397                 .build()
 398                 .opens()
 399                 .iterator()
 400                 .next();
 401     }
 402 
 403     private Opens opens(String pn) {
 404         return opens(Set.of(), pn);
 405     }
 406 
 407     private Opens opens(Set<Opens.Modifier> mods, String pn, String target) {
 408         return ModuleDescriptor.module("foo")
 409                 .opens(mods, pn, Set.of(target))
 410                 .build()
 411                 .opens()
 412                 .iterator()
 413                 .next();
 414     }
 415 
 416     private Opens opens(String pn, String target) {
 417         return opens(Set.of(), pn, target);
 418     }
 419 
 420     public void testOpensOpens() {
 421         Opens o1 = opens("p");
 422         ModuleDescriptor descriptor = ModuleDescriptor.module("m").opens(o1).build();
 423         Opens o2 = descriptor.opens().iterator().next();
 424         assertEquals(o1, o2);
 425     }
 426 
 427     public void testOpensToAll() {
 428         Opens o = opens("p");
 429         assertEquals(o, o);
 430         assertTrue(o.modifiers().isEmpty());
 431         assertEquals(o.source(), "p");
 432         assertFalse(o.isQualified());
 433         assertTrue(o.targets().isEmpty());
 434     }
 435 
 436 
 437     public void testOpensToTarget() {
 438         Opens o = opens("p", "bar");
 439         assertEquals(o, o);
 440         assertTrue(o.modifiers().isEmpty());
 441         assertEquals(o.source(), "p");
 442         assertTrue(o.isQualified());
 443         assertTrue(o.targets().size() == 1);
 444         assertTrue(o.targets().contains("bar"));
 445     }
 446 
 447     public void testOpensToTargets() {
 448         Set<String> targets = new HashSet<>();
 449         targets.add("bar");
 450         targets.add("gus");
 451         Opens o = ModuleDescriptor.module("foo")
 452                 .opens("p", targets)
 453                 .build()
 454                 .opens()
 455                 .iterator()
 456                 .next();
 457         assertEquals(o, o);
 458         assertTrue(o.modifiers().isEmpty());
 459         assertEquals(o.source(), "p");
 460         assertTrue(o.isQualified());
 461         assertTrue(o.targets().size() == 2);
 462         assertTrue(o.targets().contains("bar"));
 463         assertTrue(o.targets().contains("gus"));
 464     }
 465 
 466     /*
 467 
 468     public void testOpensToAllWithModifier() {
 469         Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
 470         assertEquals(e, e);
 471         assertTrue(e.modifiers().size() == 1);
 472         assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
 473         assertEquals(e.source(), "p");
 474         assertFalse(e.isQualified());
 475         assertTrue(e.targets().isEmpty());
 476     }
 477 
 478     public void testOpensToTargetWithModifier() {
 479         Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p", Set.of("bar"));
 480         assertEquals(e, e);
 481         assertTrue(e.modifiers().size() == 1);
 482         assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
 483         assertEquals(e.source(), "p");
 484         assertTrue(e.isQualified());
 485         assertTrue(e.targets().size() == 1);
 486         assertTrue(e.targets().contains("bar"));
 487     }
 488 
 489 
 490     */
 491 
 492     @Test(expectedExceptions = IllegalStateException.class)
 493     public void testOpensWithDuplicate1() {
 494         Opens o = opens("p");
 495         ModuleDescriptor.module("foo").opens(o).opens(o);
 496     }
 497 
 498     @Test(expectedExceptions = IllegalStateException.class)
 499     public void testOpensWithDuplicate2() {
 500         ModuleDescriptor.module("foo").opens("p").opens("p");
 501     }
 502 
 503     @Test(expectedExceptions = IllegalStateException.class)
 504     public void testOpensOnContainedPackage() {
 505         ModuleDescriptor.module("foo").contains("p").opens("p");
 506     }
 507 
 508     @Test(expectedExceptions = IllegalStateException.class)
 509     public void testOpensToTargetOnContainedPackage() {
 510         ModuleDescriptor.module("foo").contains("p").opens("p", Set.of("bar"));
 511     }
 512 
 513     @Test(expectedExceptions = IllegalArgumentException.class )
 514     public void testOpensWithEmptySet() {
 515         ModuleDescriptor.module("foo").opens("p", Collections.emptySet());
 516     }
 517 
 518     @Test(dataProvider = "invalidjavaidentifiers",
 519             expectedExceptions = IllegalArgumentException.class )
 520     public void testOpensWithBadName(String pn, String ignore) {
 521         ModuleDescriptor.module("foo").opens(pn);
 522     }
 523 
 524     @Test(expectedExceptions = NullPointerException.class )
 525     public void testOpensWithNullExports() {
 526         ModuleDescriptor.module("foo").opens((Opens) null);
 527     }
 528 
 529     @Test(expectedExceptions = NullPointerException.class )
 530     public void testOpensWithNullTargets() {
 531         ModuleDescriptor.module("foo").opens("p", (Set<String>) null);
 532     }
 533 
 534     public void testOpensEqualsAndHashCode() {
 535         Opens o1, o2;
 536 
 537         o1 = opens("p");
 538         o2 = opens("p");
 539         assertEquals(o1, o2);
 540         assertTrue(o1.hashCode() == o1.hashCode());
 541 
 542         o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
 543         o2 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
 544         assertEquals(o1, o2);
 545         assertTrue(o1.hashCode() == o2.hashCode());
 546 
 547         o1 = opens("p");
 548         o2 = opens("q");
 549         assertNotEquals(o1, o2);
 550 
 551         o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
 552         o2 = opens(Set.of(), "p");
 553         assertNotEquals(o1, o2);
 554     }
 555 
 556     public void testOpensToString() {
 557         String s = ModuleDescriptor.module("foo")
 558                 .opens("p1", Set.of("bar"))
 559                 .build()
 560                 .opens()
 561                 .iterator()
 562                 .next()
 563                 .toString();
 564         assertTrue(s.contains("p1"));
 565         assertTrue(s.contains("bar"));
 566     }
 567 
 568 
 569     // uses
 570 
 571     public void testUses() {
 572         Set<String> uses
 573             = ModuleDescriptor.module("foo")
 574                 .uses("p.S")
 575                 .uses("q.S")
 576                 .build()
 577                 .uses();
 578         assertTrue(uses.size() == 2);
 579         assertTrue(uses.contains("p.S"));
 580         assertTrue(uses.contains("q.S"));
 581     }
 582 
 583     @Test(expectedExceptions = IllegalStateException.class)
 584     public void testUsesWithDuplicate() {
 585         ModuleDescriptor.module("foo").uses("p.S").uses("p.S");
 586     }
 587 
 588     @Test(dataProvider = "invalidjavaidentifiers",
 589           expectedExceptions = IllegalArgumentException.class )
 590     public void testUsesWithBadName(String service, String ignore) {
 591         ModuleDescriptor.module("foo").uses(service);
 592     }
 593 
 594 
 595     // provides
 596 
 597     private Provides provides(String st, String pc) {
 598         return ModuleDescriptor.module("foo")
 599             .provides(st, pc)
 600             .build()
 601             .provides()
 602             .iterator()
 603             .next();
 604     }
 605 
 606     public void testProvidesWithProvides() {
 607         Provides p1 = provides("p.S", "q.S1");
 608         ModuleDescriptor descriptor = ModuleDescriptor.module("m")
 609                 .provides(p1)
 610                 .build();
 611         Provides p2 = descriptor.provides().iterator().next();
 612         assertEquals(p1, p2);
 613     }
 614 
 615 
 616     public void testProvides() {
 617         Set<Provides> set = ModuleDescriptor.module("foo")
 618                 .provides("p.S", List.of("q.P1", "q.P2"))
 619                 .build()
 620                 .provides();
 621         assertTrue(set.size() == 1);
 622 
 623         Provides p = set.iterator().next();
 624         assertEquals(p, p);
 625         assertEquals(p.service(), "p.S");
 626         assertTrue(p.providers().size() == 2);
 627         assertEquals(p.providers().get(0), "q.P1");
 628         assertEquals(p.providers().get(1), "q.P2");
 629     }
 630 
 631     @Test(expectedExceptions = IllegalStateException.class )
 632     public void testProvidesWithDuplicateProvides() {
 633         Provides p = provides("p.S", "q.S2");
 634         ModuleDescriptor.module("m").provides("p.S", "q.S1").provides(p);
 635     }
 636 
 637     @Test(expectedExceptions = IllegalArgumentException.class )
 638     public void testProvidesWithEmptySet() {
 639         ModuleDescriptor.module("foo").provides("p.Service", Collections.emptyList());
 640     }
 641 
 642     @Test(dataProvider = "invalidjavaidentifiers",
 643           expectedExceptions = IllegalArgumentException.class )
 644     public void testProvidesWithBadService(String service, String ignore) {
 645         ModuleDescriptor.module("foo").provides(service, "p.Provider");
 646     }
 647 
 648     @Test(dataProvider = "invalidjavaidentifiers",
 649           expectedExceptions = IllegalArgumentException.class )
 650     public void testProvidesWithBadProvider(String provider, String ignore) {
 651         ModuleDescriptor.module("foo").provides("p.Service", provider);
 652     }
 653 
 654     @Test(expectedExceptions = NullPointerException.class )
 655     public void testProvidesWithNullProvides() {
 656         ModuleDescriptor.module("foo").provides((Provides) null);
 657     }
 658 
 659     @Test(expectedExceptions = NullPointerException.class )
 660     public void testProvidesWithNullProviders() {
 661         ModuleDescriptor.module("foo").provides("p.S", (List<String>) null);
 662     }
 663 
 664     public void testProvidesEqualsAndHashCode() {
 665         Provides p1, p2;
 666 
 667         p1 = provides("p.S", "q.S1");
 668         p2 = provides("p.S", "q.S1");
 669         assertEquals(p1, p2);
 670         assertTrue(p1.hashCode() == p2.hashCode());
 671 
 672         p1 = provides("p.S", "q.S1");
 673         p2 = provides("p.S", "q.S2");
 674         assertNotEquals(p1, p2);
 675 
 676         p1 = provides("p.S", "q.S1");
 677         p2 = provides("p.S2", "q.S1");
 678         assertNotEquals(p1, p2);
 679     }
 680 
 681     // contains
 682 
 683     public void testContains() {
 684         Set<String> packages = ModuleDescriptor.module("foo")
 685                 .contains("p")
 686                 .contains("q")
 687                 .build()
 688                 .packages();
 689         assertTrue(packages.size() == 2);
 690         assertTrue(packages.contains("p"));
 691         assertTrue(packages.contains("q"));
 692     }
 693 
 694     public void testContainsWithEmptySet() {
 695         Set<String> packages = ModuleDescriptor.module("foo")
 696                 .contains(Collections.emptySet())
 697                 .build()
 698                 .packages();
 699         assertTrue(packages.size() == 0);
 700     }
 701 
 702     @Test(expectedExceptions = IllegalStateException.class)
 703     public void testContainsWithDuplicate() {
 704         ModuleDescriptor.module("foo").contains("p").contains("p");
 705     }
 706 
 707     @Test(expectedExceptions = IllegalStateException.class)
 708     public void testContainsWithExportedPackage() {
 709         ModuleDescriptor.module("foo").exports("p").contains("p");
 710     }
 711 
 712     @Test(dataProvider = "invalidjavaidentifiers",
 713           expectedExceptions = IllegalArgumentException.class )
 714     public void testContainsWithBadName(String pn, String ignore) {
 715         ModuleDescriptor.module("foo").contains(pn);
 716     }
 717 
 718 
 719     // packages
 720 
 721     public void testPackages() {
 722         Set<String> packages = ModuleDescriptor.module("foo")
 723                 .exports("p")
 724                 .contains("q")
 725                 .build()
 726                 .packages();
 727         assertTrue(packages.size() == 2);
 728         assertTrue(packages.contains("p"));
 729         assertTrue(packages.contains("q"));
 730     }
 731 
 732 
 733     // name
 734 
 735     public void testModuleName() {
 736         String mn = ModuleDescriptor.module("foo").build().name();
 737         assertEquals(mn, "foo");
 738     }
 739 
 740     @Test(dataProvider = "invalidjavaidentifiers",
 741           expectedExceptions = IllegalArgumentException.class )
 742     public void testBadModuleName(String mn, String ignore) {
 743         ModuleDescriptor.module(mn);
 744     }
 745 
 746 
 747     // version
 748 
 749     public void testVersion1() {
 750         Version v1 = Version.parse("1.0");
 751         Version v2 = ModuleDescriptor.module("foo")
 752                 .version(v1)
 753                 .build()
 754                 .version()
 755                 .get();
 756         assertEquals(v1, v2);
 757     }
 758 
 759     public void testVersion2() {
 760         String vs = "1.0";
 761         Version v1 = ModuleDescriptor.module("foo")
 762                 .version(vs)
 763                 .build()
 764                 .version()
 765                 .get();
 766         Version v2 = Version.parse(vs);
 767         assertEquals(v1, v2);
 768     }
 769 
 770     @Test(expectedExceptions = NullPointerException.class )
 771     public void testNullVersion1() {
 772         ModuleDescriptor.module("foo").version((Version) null);
 773     }
 774 
 775     @Test(expectedExceptions = IllegalArgumentException.class )
 776     public void testNullVersion2() {
 777         ModuleDescriptor.module("foo").version((String) null);
 778     }
 779 
 780     @Test(expectedExceptions = IllegalArgumentException.class )
 781     public void testEmptyVersion() {
 782         ModuleDescriptor.module("foo").version("");
 783     }
 784 
 785 
 786     // toNameAndVersion
 787 
 788     public void testToNameAndVersion() {
 789         ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
 790         assertEquals(md1.toNameAndVersion(), "foo");
 791 
 792         ModuleDescriptor md2 = ModuleDescriptor.module("foo").version("1.0").build();
 793         assertEquals(md2.toNameAndVersion(), "foo@1.0");
 794     }
 795 
 796 
 797     // open modules
 798 
 799     public void testOpenModules() {
 800         ModuleDescriptor descriptor = ModuleDescriptor.openModule("m")
 801                 .requires("java.base")
 802                 .contains("p")
 803                 .build();
 804         assertTrue(descriptor.isOpen());
 805         assertTrue(descriptor.packages().size() == 1);
 806         assertTrue(descriptor.packages().contains("p"));
 807         assertTrue(descriptor.exports().isEmpty());
 808     }
 809 
 810     @Test(expectedExceptions = IllegalStateException.class)
 811     public void testOpensOnWeakModule1() {
 812         ModuleDescriptor.openModule("foo").opens("p");
 813     }
 814 
 815     @Test(expectedExceptions = IllegalStateException.class)
 816     public void testOpensOnWeakModule2() {
 817         ModuleDescriptor.openModule("foo").opens("p", Set.of("bar"));
 818     }
 819 
 820     public void testIsOpen() {
 821         assertFalse(ModuleDescriptor.module("m").build().isOpen());
 822         assertFalse(ModuleDescriptor.automaticModule("m").build().isOpen());
 823         assertTrue(ModuleDescriptor.openModule("m").build().isOpen());
 824     }
 825 
 826 
 827     // automatic modules
 828 
 829     public void testIsAutomatic() {
 830         ModuleDescriptor descriptor1 = ModuleDescriptor.module("foo").build();
 831         assertFalse(descriptor1.isAutomatic());
 832 
 833         ModuleDescriptor descriptor2 = ModuleDescriptor.openModule("foo").build();
 834         assertFalse(descriptor2.isAutomatic());
 835 
 836         ModuleDescriptor descriptor3 = ModuleDescriptor.automaticModule("foo").build();
 837         assertTrue(descriptor3.isAutomatic());
 838     }
 839 
 840     // isSynthetic
 841     public void testIsSynthetic() {
 842         assertFalse(Object.class.getModule().getDescriptor().isSynthetic());
 843 
 844         ModuleDescriptor descriptor1 = ModuleDescriptor.module("foo").build();
 845         assertFalse(descriptor1.isSynthetic());
 846 
 847         ModuleDescriptor descriptor2 = ModuleDescriptor.openModule("foo").build();
 848         assertFalse(descriptor2.isSynthetic());
 849 
 850         ModuleDescriptor descriptor3 = ModuleDescriptor.automaticModule("foo").build();
 851         assertFalse(descriptor3.isSynthetic());
 852     }
 853 
 854 
 855     // mainClass
 856 
 857     public void testMainClass() {
 858         String mainClass
 859             = ModuleDescriptor.module("foo").mainClass("p.Main").build().mainClass().get();
 860         assertEquals(mainClass, "p.Main");
 861     }
 862 
 863     @Test(dataProvider = "invalidjavaidentifiers",
 864           expectedExceptions = IllegalArgumentException.class )
 865     public void testMainClassWithBadName(String mainClass, String ignore) {
 866         Builder builder = ModuleDescriptor.module("foo");
 867         builder.mainClass(mainClass);
 868     }
 869 
 870 
 871     // osName
 872 
 873     public void testOsName() {
 874         String osName = ModuleDescriptor.module("foo").osName("Linux").build().osName().get();
 875         assertEquals(osName, "Linux");
 876     }
 877 
 878     @Test(expectedExceptions = IllegalArgumentException.class)
 879     public void testNullOsName() {
 880         ModuleDescriptor.module("foo").osName(null);
 881     }
 882 
 883     @Test(expectedExceptions = IllegalArgumentException.class)
 884     public void testEmptyOsName() {
 885         ModuleDescriptor.module("foo").osName("");
 886     }
 887 
 888 
 889     // osArch
 890 
 891     public void testOsArch() {
 892         String osArch = ModuleDescriptor.module("foo").osName("arm").build().osName().get();
 893         assertEquals(osArch, "arm");
 894     }
 895 
 896     @Test(expectedExceptions = IllegalArgumentException.class)
 897     public void testNullOsArch() {
 898         ModuleDescriptor.module("foo").osArch(null);
 899     }
 900 
 901     @Test(expectedExceptions = IllegalArgumentException.class)
 902     public void testEmptyOsArch() {
 903         ModuleDescriptor.module("foo").osArch("");
 904     }
 905 
 906 
 907     // osVersion
 908 
 909     public void testOsVersion() {
 910         String osVersion = ModuleDescriptor.module("foo").osName("11.2").build().osName().get();
 911         assertEquals(osVersion, "11.2");
 912     }
 913 
 914     @Test(expectedExceptions = IllegalArgumentException.class)
 915     public void testNullOsVersion() {
 916         ModuleDescriptor.module("foo").osVersion(null);
 917     }
 918 
 919     @Test(expectedExceptions = IllegalArgumentException.class)
 920     public void testEmptyOsVersion() {
 921         ModuleDescriptor.module("foo").osVersion("");
 922     }
 923 
 924     // reads
 925 
 926     private static InputStream EMPTY_INPUT_STREAM = new InputStream() {
 927         @Override
 928         public int read() {
 929             return -1;
 930         }
 931     };
 932 
 933     private static InputStream FAILING_INPUT_STREAM = new InputStream() {
 934         @Override
 935         public int read() throws IOException {
 936             throw new IOException();
 937         }
 938     };
 939 
 940     // basic test reading module-info.class
 941     public void testRead1() throws Exception {
 942         Module base = Object.class.getModule();
 943 
 944         try (InputStream in = base.getResourceAsStream("module-info.class")) {
 945             ModuleDescriptor descriptor = ModuleDescriptor.read(in);
 946             assertTrue(in.read() == -1); // all bytes read
 947             assertEquals(descriptor.name(), "java.base");
 948         }
 949 
 950         try (InputStream in = base.getResourceAsStream("module-info.class")) {
 951             ByteBuffer bb = ByteBuffer.wrap(in.readAllBytes());
 952             ModuleDescriptor descriptor = ModuleDescriptor.read(bb);
 953             assertFalse(bb.hasRemaining()); // no more remaining bytes
 954             assertEquals(descriptor.name(), "java.base");
 955         }
 956     }
 957 
 958     /**
 959      * Test reading a module-info.class that has a module name, requires,
 960      * and qualified exports with module names that are not supported in the
 961      * Java Language.
 962      */
 963     public void testRead2() throws Exception {
 964         // use non-public constructor to create a Builder that is not strict
 965         Constructor<?> ctor = Builder.class.getDeclaredConstructor(String.class, boolean.class);
 966         ctor.setAccessible(true);
 967 
 968         Builder builder = (ModuleDescriptor.Builder) ctor.newInstance("m?1", false);
 969         ModuleDescriptor descriptor = builder
 970                 .requires("java.base")
 971                 .requires("-m1")
 972                 .exports("p", Set.of("m2-"))
 973                 .build();
 974 
 975         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 976         ModuleInfoWriter.write(descriptor, baos);
 977         ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
 978 
 979         descriptor = ModuleDescriptor.read(bb);
 980         assertEquals(descriptor.name(), "m?1");
 981 
 982         Set<String> requires = descriptor.requires()
 983                 .stream()
 984                 .map(Requires::name)
 985                 .collect(Collectors.toSet());
 986         assertTrue(requires.size() == 2);
 987         assertTrue(requires.contains("java.base"));
 988         assertTrue(requires.contains("-m1"));
 989 
 990         assertTrue(descriptor.exports().size() == 1);
 991         Exports e = descriptor.exports().iterator().next();
 992         assertTrue(e.targets().size() == 1);
 993         assertTrue(e.targets().contains("m2-"));
 994     }
 995 
 996     /**
 997      * Test ModuleDescriptor with a packager finder
 998      */
 999     public void testReadsWithPackageFinder() throws Exception {
1000         ModuleDescriptor descriptor = ModuleDescriptor.module("foo")
1001                 .requires("java.base")
1002                 .build();
1003 
1004         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1005         ModuleInfoWriter.write(descriptor, baos);
1006         ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
1007 
1008         descriptor = ModuleDescriptor.read(bb, () -> Set.of("p", "q"));
1009 
1010         assertTrue(descriptor.packages().size() == 2);
1011         assertTrue(descriptor.packages().contains("p"));
1012         assertTrue(descriptor.packages().contains("q"));
1013     }
1014 
1015     /**
1016      * Test ModuleDescriptor with a packager finder that doesn't return the
1017      * complete set of packages.
1018      */
1019     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1020     public void testReadsWithBadPackageFinder() throws Exception {
1021         ModuleDescriptor descriptor = ModuleDescriptor.module("foo")
1022                 .requires("java.base")
1023                 .exports("p")
1024                 .build();
1025 
1026         ByteArrayOutputStream baos = new ByteArrayOutputStream();
1027         ModuleInfoWriter.write(descriptor, baos);
1028         ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
1029 
1030         // package finder returns a set that doesn't include p
1031         ModuleDescriptor.read(bb, () -> Set.of("q"));
1032     }
1033 
1034     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1035     public void testReadFromEmptyInputStream() throws Exception {
1036         ModuleDescriptor.read(EMPTY_INPUT_STREAM);
1037     }
1038 
1039     @Test(expectedExceptions = IOException.class)
1040     public void testReadFromFailingInputStream() throws Exception {
1041         ModuleDescriptor.read(FAILING_INPUT_STREAM);
1042     }
1043 
1044     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1045     public void testReadFromEmptyBuffer() {
1046         ByteBuffer bb = ByteBuffer.allocate(0);
1047         ModuleDescriptor.read(bb);
1048     }
1049 
1050     // The requires table for java.base must be 0 length
1051     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1052     public void testReadOfJavaBaseWithRequires() {
1053         ModuleDescriptor descriptor
1054             = ModuleDescriptor.module("java.base")
1055                 .requires("other")
1056                 .build();
1057         ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1058         ModuleDescriptor.read(bb);
1059     }
1060 
1061     // The requires table must have an entry for java.base
1062     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1063     public void testReadWithEmptyRequires() {
1064         ModuleDescriptor descriptor = ModuleDescriptor.module("m1").build();
1065         ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1066         ModuleDescriptor.read(bb);
1067     }
1068 
1069     // The requires table must have an entry for java.base
1070     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
1071     public void testReadWithNoRequiresBase() {
1072         ModuleDescriptor descriptor
1073             = ModuleDescriptor.module("m1")
1074                 .requires("m2")
1075                 .build();
1076         ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
1077         ModuleDescriptor.read(bb);
1078     }
1079 
1080     public void testReadWithNull() throws Exception {
1081         Module base = Object.class.getModule();
1082 
1083         try {
1084             ModuleDescriptor.read((InputStream)null);
1085             assertTrue(false);
1086         } catch (NullPointerException expected) { }
1087 
1088 
1089         try (InputStream in = base.getResourceAsStream("module-info.class")) {
1090             try {
1091                 ModuleDescriptor.read(in, null);
1092                 assertTrue(false);
1093             } catch (NullPointerException expected) { }
1094         }
1095 
1096         try {
1097             ModuleDescriptor.read((ByteBuffer)null);
1098             assertTrue(false);
1099         } catch (NullPointerException expected) { }
1100 
1101 
1102         try (InputStream in = base.getResourceAsStream("module-info.class")) {
1103             ByteBuffer bb = ByteBuffer.wrap(in.readAllBytes());
1104             try {
1105                 ModuleDescriptor.read(bb, null);
1106                 assertTrue(false);
1107             } catch (NullPointerException expected) { }
1108         }
1109     }
1110 
1111 
1112     // equals/hashCode/compareTo/toString
1113 
1114     public void testEqualsAndHashCode() {
1115         ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
1116         ModuleDescriptor md2 = ModuleDescriptor.module("foo").build();
1117         assertEquals(md1, md1);
1118         assertEquals(md1.hashCode(), md2.hashCode());
1119     }
1120 
1121     public void testCompare() {
1122         ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
1123         ModuleDescriptor md2 = ModuleDescriptor.module("bar").build();
1124         int n = "foo".compareTo("bar");
1125         assertTrue(md1.compareTo(md2) == n);
1126         assertTrue(md2.compareTo(md1) == -n);
1127     }
1128 
1129     public void testToString() {
1130         String s = ModuleDescriptor.module("m1").requires("m2").exports("p1").build().toString();
1131         assertTrue(s.contains("m1"));
1132         assertTrue(s.contains("m2"));
1133         assertTrue(s.contains("p1"));
1134     }
1135 
1136 }