< prev index next >

test/java/lang/reflect/Layer/BasicLayerTest.java

Print this page


   1 /*
   2  * Copyright (c) 2014, 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  * @library /lib/testlibrary

  27  * @build BasicLayerTest ModuleUtils
  28  * @compile layertest/Test.java
  29  * @run testng BasicLayerTest
  30  * @summary Basic tests for java.lang.reflect.Layer
  31  */
  32 
  33 import java.lang.module.Configuration;
  34 import java.lang.module.ModuleDescriptor;
  35 import java.lang.module.ModuleDescriptor.Requires;
  36 import java.lang.module.ModuleFinder;
  37 import java.lang.reflect.Layer;
  38 import java.lang.reflect.LayerInstantiationException;
  39 import java.lang.reflect.Module;
  40 import java.util.HashMap;
  41 import java.util.Map;
  42 import java.util.Optional;
  43 import java.util.Set;
  44 import java.util.stream.Collectors;
  45 

  46 import org.testng.annotations.Test;
  47 import static org.testng.Assert.*;
  48 
  49 @Test
  50 public class BasicLayerTest {
  51 
  52     /**









  53      * Exercise Layer.empty()
  54      */
  55     public void testEmpty() {
  56         Layer emptyLayer = Layer.empty();
  57 
  58         assertTrue(emptyLayer.parents().isEmpty());
  59 
  60         assertTrue(emptyLayer.configuration() == Configuration.empty());
  61 
  62         assertTrue(emptyLayer.modules().isEmpty());
  63 
  64         assertFalse(emptyLayer.findModule("java.base").isPresent());
  65 
  66         try {
  67             emptyLayer.findLoader("java.base");
  68             assertTrue(false);
  69         } catch (IllegalArgumentException expected) { }
  70     }
  71 
  72 


  92         assertEquals(count, modules.size()); // module names are unique
  93 
  94         // findModule
  95         Module base = Object.class.getModule();
  96         assertTrue(bootLayer.findModule("java.base").get() == base);
  97         assertTrue(base.getLayer() == bootLayer);
  98 
  99         // findLoader
 100         assertTrue(bootLayer.findLoader("java.base") == null);
 101 
 102         // parents
 103         assertTrue(bootLayer.parents().size() == 1);
 104         assertTrue(bootLayer.parents().get(0) == Layer.empty());
 105     }
 106 
 107 
 108     /**
 109      * Exercise Layer defineModules, created with empty layer as parent
 110      */
 111     public void testLayerOnEmpty() {
 112         ModuleDescriptor descriptor1
 113             = ModuleDescriptor.module("m1")
 114                 .requires("m2")
 115                 .exports("p1")
 116                 .build();
 117 
 118         ModuleDescriptor descriptor2
 119             = ModuleDescriptor.module("m2")
 120                 .requires("m3")
 121                 .build();
 122 
 123         ModuleDescriptor descriptor3
 124             = ModuleDescriptor.module("m3")
 125                 .build();
 126 
 127         ModuleFinder finder
 128             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 129 
 130         Configuration cf = resolveRequires(finder, "m1");
 131 
 132         // map each module to its own class loader for this test
 133         ClassLoader loader1 = new ClassLoader() { };
 134         ClassLoader loader2 = new ClassLoader() { };
 135         ClassLoader loader3 = new ClassLoader() { };
 136         Map<String, ClassLoader> map = new HashMap<>();
 137         map.put("m1", loader1);
 138         map.put("m2", loader2);
 139         map.put("m3", loader3);
 140 
 141         Layer layer = Layer.empty().defineModules(cf, map::get);
 142 
 143         // configuration
 144         assertTrue(layer.configuration() == cf);
 145         assertTrue(layer.configuration().modules().size() == 3);
 146 
 147         // modules
 148         Set<Module> modules = layer.modules();
 149         assertTrue(modules.size() == 3);
 150         Set<String> names = modules.stream()


 174 
 175         // findLoader
 176         assertTrue(layer.findLoader("m1") == loader1);
 177         assertTrue(layer.findLoader("m2") == loader2);
 178         assertTrue(layer.findLoader("m3") == loader3);
 179         try {
 180             ClassLoader loader = layer.findLoader("godot");
 181             assertTrue(false);
 182         } catch (IllegalArgumentException ignore) { }
 183 
 184         // parents
 185         assertTrue(layer.parents().size() == 1);
 186         assertTrue(layer.parents().get(0) == Layer.empty());
 187     }
 188 
 189 
 190     /**
 191      * Exercise Layer defineModules, created with boot layer as parent
 192      */
 193     public void testLayerOnBoot() {
 194         ModuleDescriptor descriptor1
 195             = ModuleDescriptor.module("m1")
 196                 .requires("m2")
 197                 .requires("java.base")
 198                 .exports("p1")
 199                 .build();
 200 
 201         ModuleDescriptor descriptor2
 202             = ModuleDescriptor.module("m2")
 203                 .requires("java.base")
 204                 .build();
 205 
 206         ModuleFinder finder
 207             = ModuleUtils.finderOf(descriptor1, descriptor2);
 208 
 209         Configuration parent = Layer.boot().configuration();
 210         Configuration cf = resolveRequires(parent, finder, "m1");
 211 
 212         ClassLoader loader = new ClassLoader() { };
 213 
 214         Layer layer = Layer.boot().defineModules(cf, mn -> loader);
 215 
 216         // configuration
 217         assertTrue(layer.configuration() == cf);
 218         assertTrue(layer.configuration().modules().size() == 2);
 219 
 220         // modules
 221         Set<Module> modules = layer.modules();
 222         assertTrue(modules.size() == 2);
 223         Set<String> names = modules.stream()
 224             .map(Module::getName)
 225             .collect(Collectors.toSet());
 226         assertTrue(names.contains("m1"));
 227         assertTrue(names.contains("m2"));
 228 
 229         // findModule
 230         Module m1 = layer.findModule("m1").get();


 239         assertTrue(modules.contains(m2));
 240         assertTrue(layer.findModule("java.base").get() == Object.class.getModule());
 241         assertFalse(layer.findModule("godot").isPresent());
 242 
 243         // findLoader
 244         assertTrue(layer.findLoader("m1") == loader);
 245         assertTrue(layer.findLoader("m2") == loader);
 246         assertTrue(layer.findLoader("java.base") == null);
 247 
 248         // parents
 249         assertTrue(layer.parents().size() == 1);
 250         assertTrue(layer.parents().get(0) == Layer.boot());
 251     }
 252 
 253 
 254     /**
 255      * Exercise Layer defineModules with a configuration of two modules that
 256      * have the same module-private package.
 257      */
 258     public void testPackageContainedInSelfAndOther() {
 259         ModuleDescriptor descriptor1
 260             =  ModuleDescriptor.module("m1")
 261                 .requires("m2")
 262                 .contains("p")
 263                 .build();
 264 
 265         ModuleDescriptor descriptor2
 266             = ModuleDescriptor.module("m2")
 267                 .contains("p")
 268                 .build();
 269 
 270         ModuleFinder finder
 271             = ModuleUtils.finderOf(descriptor1, descriptor2);
 272 
 273         Configuration cf = resolveRequires(finder, "m1");
 274         assertTrue(cf.modules().size() == 2);
 275 
 276         // one loader per module, should be okay
 277         Layer.empty().defineModules(cf, mn -> new ClassLoader() { });
 278 
 279         // same class loader
 280         try {
 281             ClassLoader loader = new ClassLoader() { };
 282             Layer.empty().defineModules(cf, mn -> loader);
 283             assertTrue(false);
 284         } catch (LayerInstantiationException expected) { }
 285     }
 286 
 287 
 288     /**
 289      * Exercise Layer defineModules with a configuration that is a partitioned
 290      * graph. The same package is exported in both partitions.
 291      */
 292     public void testSameExportInPartitionedGraph() {
 293 
 294         // m1 reads m2, m2 exports p to m1
 295         ModuleDescriptor descriptor1
 296             =  ModuleDescriptor.module("m1")
 297                 .requires("m2")
 298                 .build();
 299         ModuleDescriptor descriptor2
 300             =  ModuleDescriptor.module("m2")
 301                 .exports("p", Set.of("m1"))
 302                 .build();
 303 
 304         // m3 reads m4, m4 exports p to m3
 305         ModuleDescriptor descriptor3
 306             =  ModuleDescriptor.module("m3")
 307                 .requires("m4")
 308                 .build();
 309         ModuleDescriptor descriptor4
 310             =  ModuleDescriptor.module("m4")
 311                 .exports("p", Set.of("m3"))
 312                 .build();
 313 
 314         ModuleFinder finder
 315             = ModuleUtils.finderOf(descriptor1,
 316                                    descriptor2,
 317                                    descriptor3,
 318                                    descriptor4);
 319 
 320         Configuration cf = resolveRequires(finder, "m1", "m3");
 321         assertTrue(cf.modules().size() == 4);
 322 
 323         // one loader per module
 324         Layer.empty().defineModules(cf, mn -> new ClassLoader() { });
 325 
 326         // m1 & m2 in one loader, m3 & m4 in another loader
 327         ClassLoader loader1 = new ClassLoader() { };
 328         ClassLoader loader2 = new ClassLoader() { };
 329         Map<String, ClassLoader> map = new HashMap<>();
 330         map.put("m1", loader1);
 331         map.put("m2", loader1);
 332         map.put("m3", loader2);
 333         map.put("m4", loader2);
 334         Layer.empty().defineModules(cf, map::get);
 335 
 336         // same loader
 337         try {
 338             ClassLoader loader = new ClassLoader() { };
 339             Layer.empty().defineModules(cf, mn -> loader);
 340             assertTrue(false);
 341         } catch (LayerInstantiationException expected) { }
 342     }
 343 
 344 
 345     /**
 346      * Exercise Layer defineModules with a configuration with a module that
 347      * contains a package that is the same name as a non-exported package in
 348      * a parent layer.
 349      */
 350     public void testContainsSamePackageAsBootLayer() {
 351 
 352         // check assumption that java.base contains sun.launcher
 353         ModuleDescriptor base = Object.class.getModule().getDescriptor();
 354         assertTrue(base.packages().contains("sun.launcher"));
 355 
 356         ModuleDescriptor descriptor
 357             = ModuleDescriptor.module("m1")
 358                .requires("java.base")
 359                .contains("sun.launcher")
 360                .build();
 361 
 362         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 363 
 364         Configuration parent = Layer.boot().configuration();
 365         Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
 366         assertTrue(cf.modules().size() == 1);
 367 
 368         ClassLoader loader = new ClassLoader() { };
 369         Layer layer = Layer.boot().defineModules(cf, mn -> loader);
 370         assertTrue(layer.modules().size() == 1);
 371    }
 372 
 373 
 374     /**
 375      * Test layers with implied readability.
 376      *
 377      * The test consists of three configurations:
 378      * - Configuration/layer1: m1, m2 requires transitive m1
 379      * - Configuration/layer2: m3 requires m1
 380      */
 381     public void testImpliedReadabilityWithLayers1() {
 382 
 383         // cf1: m1 and m2, m2 requires transitive m1
 384 
 385         ModuleDescriptor descriptor1
 386             = ModuleDescriptor.module("m1")
 387                 .build();
 388 
 389         ModuleDescriptor descriptor2
 390             = ModuleDescriptor.module("m2")
 391                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 392                 .build();
 393 
 394         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 395 
 396         Configuration cf1 = resolveRequires(finder1, "m2");
 397 
 398         ClassLoader cl1 = new ClassLoader() { };
 399         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
 400 
 401 
 402         // cf2: m3, m3 requires m2
 403 
 404         ModuleDescriptor descriptor3
 405             = ModuleDescriptor.module("m3")
 406                 .requires("m2")
 407                 .build();
 408 
 409         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 410 
 411         Configuration cf2 = resolveRequires(cf1, finder2, "m3");
 412 
 413         ClassLoader cl2 = new ClassLoader() { };
 414         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
 415 
 416         assertTrue(layer1.parents().size() == 1);
 417         assertTrue(layer1.parents().get(0) == Layer.empty());
 418 
 419         assertTrue(layer2.parents().size() == 1);
 420         assertTrue(layer2.parents().get(0) == layer1);
 421 
 422         Module m1 = layer2.findModule("m1").get();
 423         Module m2 = layer2.findModule("m2").get();
 424         Module m3 = layer2.findModule("m3").get();
 425 
 426         assertTrue(m1.getLayer() == layer1);
 427         assertTrue(m2.getLayer() == layer1);
 428         assertTrue(m3.getLayer() == layer2);
 429 
 430         assertTrue(m1.getClassLoader() == cl1);
 431         assertTrue(m2.getClassLoader() == cl1);


 439         assertTrue(m2.canRead(m2));
 440         assertFalse(m2.canRead(m3));
 441 
 442         assertTrue(m3.canRead(m1));
 443         assertTrue(m3.canRead(m2));
 444         assertTrue(m3.canRead(m3));
 445     }
 446 
 447 
 448     /**
 449      * Test layers with implied readability.
 450      *
 451      * The test consists of three configurations:
 452      * - Configuration/layer1: m1
 453      * - Configuration/layer2: m2 requires transitive m3, m3 requires m2
 454      */
 455     public void testImpliedReadabilityWithLayers2() {
 456 
 457         // cf1: m1
 458 
 459         ModuleDescriptor descriptor1
 460             = ModuleDescriptor.module("m1")
 461                 .build();
 462 
 463         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 464 
 465         Configuration cf1 = resolveRequires(finder1, "m1");
 466 
 467         ClassLoader cl1 = new ClassLoader() { };
 468         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
 469 
 470 
 471         // cf2: m2, m3: m2 requires transitive m1, m3 requires m2
 472 
 473         ModuleDescriptor descriptor2
 474             = ModuleDescriptor.module("m2")
 475                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 476                 .build();
 477 
 478         ModuleDescriptor descriptor3
 479             = ModuleDescriptor.module("m3")
 480                 .requires("m2")
 481                 .build();
 482 
 483         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3);
 484 
 485         Configuration cf2 = resolveRequires(cf1, finder2, "m3");
 486 
 487         ClassLoader cl2 = new ClassLoader() { };
 488         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
 489 
 490         assertTrue(layer1.parents().size() == 1);
 491         assertTrue(layer1.parents().get(0) == Layer.empty());
 492 
 493         assertTrue(layer2.parents().size() == 1);
 494         assertTrue(layer2.parents().get(0) == layer1);
 495 
 496         Module m1 = layer2.findModule("m1").get();
 497         Module m2 = layer2.findModule("m2").get();
 498         Module m3 = layer2.findModule("m3").get();
 499 
 500         assertTrue(m1.getLayer() == layer1);
 501         assertTrue(m2.getLayer() == layer2);
 502         assertTrue(m3.getLayer() == layer2);
 503 
 504         assertTrue(m1.canRead(m1));
 505         assertFalse(m1.canRead(m2));


 510         assertFalse(m2.canRead(m3));
 511 
 512         assertTrue(m3.canRead(m1));
 513         assertTrue(m3.canRead(m2));
 514         assertTrue(m3.canRead(m3));
 515     }
 516 
 517 
 518     /**
 519      * Test layers with implied readability.
 520      *
 521      * The test consists of three configurations:
 522      * - Configuration/layer1: m1
 523      * - Configuration/layer2: m2 requires transitive m1
 524      * - Configuration/layer3: m3 requires m1
 525      */
 526     public void testImpliedReadabilityWithLayers3() {
 527 
 528         // cf1: m1
 529 
 530         ModuleDescriptor descriptor1
 531             = ModuleDescriptor.module("m1")
 532                 .build();
 533 
 534         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 535 
 536         Configuration cf1 = resolveRequires(finder1, "m1");
 537 
 538         ClassLoader cl1 = new ClassLoader() { };
 539         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
 540 
 541 
 542         // cf2: m2 requires transitive m1
 543 
 544         ModuleDescriptor descriptor2
 545             = ModuleDescriptor.module("m2")
 546                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 547                 .build();
 548 
 549         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
 550 
 551         Configuration cf2 = resolveRequires(cf1, finder2, "m2");
 552 
 553         ClassLoader cl2 = new ClassLoader() { };
 554         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
 555 
 556 
 557         // cf3: m3 requires m2
 558 
 559         ModuleDescriptor descriptor3
 560             = ModuleDescriptor.module("m3")
 561                 .requires("m2")
 562                 .build();
 563 
 564         ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3);
 565 
 566         Configuration cf3 = resolveRequires(cf2, finder3, "m3");
 567 
 568         ClassLoader cl3 = new ClassLoader() { };
 569         Layer layer3 = layer2.defineModules(cf3, mn -> cl3);
 570 
 571         assertTrue(layer1.parents().size() == 1);
 572         assertTrue(layer1.parents().get(0) == Layer.empty());
 573 
 574         assertTrue(layer2.parents().size() == 1);
 575         assertTrue(layer2.parents().get(0) == layer1);
 576 
 577         assertTrue(layer3.parents().size() == 1);
 578         assertTrue(layer3.parents().get(0) == layer2);
 579 
 580         Module m1 = layer3.findModule("m1").get();
 581         Module m2 = layer3.findModule("m2").get();
 582         Module m3 = layer3.findModule("m3").get();
 583 
 584         assertTrue(m1.getLayer() == layer1);
 585         assertTrue(m2.getLayer() == layer2);
 586         assertTrue(m3.getLayer() == layer3);


 593         assertTrue(m2.canRead(m2));
 594         assertFalse(m2.canRead(m3));
 595 
 596         assertTrue(m3.canRead(m1));
 597         assertTrue(m3.canRead(m2));
 598         assertTrue(m3.canRead(m3));
 599     }
 600 
 601 
 602     /**
 603      * Test layers with implied readability.
 604      *
 605      * The test consists of two configurations:
 606      * - Configuration/layer1: m1, m2 requires transitive m1
 607      * - Configuration/layer2: m3 requires transitive m2, m4 requires m3
 608      */
 609     public void testImpliedReadabilityWithLayers4() {
 610 
 611         // cf1: m1, m2 requires transitive m1
 612 
 613         ModuleDescriptor descriptor1
 614             = ModuleDescriptor.module("m1")
 615                 .build();
 616 
 617         ModuleDescriptor descriptor2
 618             = ModuleDescriptor.module("m2")
 619                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 620                 .build();
 621 
 622         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 623 
 624         Configuration cf1 = resolveRequires(finder1, "m2");
 625 
 626         ClassLoader cl1 = new ClassLoader() { };
 627         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
 628 
 629 
 630         // cf2: m3 requires transitive m2, m4 requires m3
 631 
 632         ModuleDescriptor descriptor3
 633             = ModuleDescriptor.module("m3")
 634                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m2")
 635                 .build();
 636 
 637         ModuleDescriptor descriptor4
 638             = ModuleDescriptor.module("m4")
 639                 .requires("m3")
 640                 .build();
 641 
 642 
 643         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 644 
 645         Configuration cf2 = resolveRequires(cf1, finder2, "m3", "m4");
 646 
 647         ClassLoader cl2 = new ClassLoader() { };
 648         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
 649 
 650         assertTrue(layer1.parents().size() == 1);
 651         assertTrue(layer1.parents().get(0) == Layer.empty());
 652 
 653         assertTrue(layer2.parents().size() == 1);
 654         assertTrue(layer2.parents().get(0) == layer1);
 655 
 656         Module m1 = layer2.findModule("m1").get();
 657         Module m2 = layer2.findModule("m2").get();
 658         Module m3 = layer2.findModule("m3").get();
 659         Module m4 = layer2.findModule("m4").get();
 660 
 661         assertTrue(m1.getLayer() == layer1);
 662         assertTrue(m2.getLayer() == layer1);
 663         assertTrue(m3.getLayer() == layer2);
 664         assertTrue(m4.getLayer() == layer2);
 665 


 676         assertTrue(m3.canRead(m1));
 677         assertTrue(m3.canRead(m2));
 678         assertTrue(m3.canRead(m3));
 679         assertFalse(m3.canRead(m4));
 680 
 681         assertTrue(m4.canRead(m1));
 682         assertTrue(m4.canRead(m2));
 683         assertTrue(m4.canRead(m3));
 684         assertTrue(m4.canRead(m4));
 685     }
 686 
 687 
 688     /**
 689      * Attempt to use Layer defineModules to create a layer with a module
 690      * defined to a class loader that already has a module of the same name
 691      * defined to the class loader.
 692      */
 693     @Test(expectedExceptions = { LayerInstantiationException.class })
 694     public void testModuleAlreadyDefinedToLoader() {
 695 
 696         ModuleDescriptor md
 697             = ModuleDescriptor.module("m")
 698                 .requires("java.base")
 699                 .build();
 700 
 701         ModuleFinder finder = ModuleUtils.finderOf(md);
 702 
 703         Configuration parent = Layer.boot().configuration();
 704 
 705         Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m"));
 706 
 707         ClassLoader loader = new ClassLoader() { };
 708 
 709         Layer.boot().defineModules(cf, mn -> loader);
 710 
 711         // should throw LayerInstantiationException as m1 already defined to loader
 712         Layer.boot().defineModules(cf, mn -> loader);
 713 
 714     }
 715 
 716 
 717     /**
 718      * Attempt to use Layer defineModules to create a Layer with a module
 719      * containing package {@code p} where the class loader already has a module
 720      * defined to it containing package {@code p}.
 721      */
 722     @Test(expectedExceptions = { LayerInstantiationException.class })
 723     public void testPackageAlreadyInNamedModule() {
 724 
 725         ModuleDescriptor md1
 726             = ModuleDescriptor.module("m1")
 727                 .contains("p")
 728                 .requires("java.base")
 729                 .build();
 730 
 731         ModuleDescriptor md2
 732             = ModuleDescriptor.module("m2")
 733                 .contains("p")
 734                 .requires("java.base")
 735                 .build();
 736 
 737         ModuleFinder finder = ModuleUtils.finderOf(md1, md2);
 738 
 739         ClassLoader loader = new ClassLoader() { };
 740 
 741         // define m1 containing package p to class loader
 742 
 743         Configuration parent = Layer.boot().configuration();
 744 
 745         Configuration cf1 = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
 746 
 747         Layer layer1 = Layer.boot().defineModules(cf1, mn -> loader);
 748 
 749         // attempt to define m2 containing package p to class loader
 750 
 751         Configuration cf2 = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m2"));
 752 
 753         // should throw exception because p already in m1
 754         Layer layer2 = Layer.boot().defineModules(cf2, mn -> loader);
 755 
 756     }
 757 
 758 
 759     /**
 760      * Attempt to use Layer defineModules to create a Layer with a module
 761      * containing a package in which a type is already loaded by the class
 762      * loader.
 763      */
 764     @Test(expectedExceptions = { LayerInstantiationException.class })
 765     public void testPackageAlreadyInUnnamedModule() throws Exception {
 766 
 767         Class<?> c = layertest.Test.class;
 768         assertFalse(c.getModule().isNamed());  // in unnamed module
 769 
 770         ModuleDescriptor md
 771             = ModuleDescriptor.module("m")
 772                 .contains(c.getPackageName())
 773                 .requires("java.base")
 774                 .build();
 775 
 776         ModuleFinder finder = ModuleUtils.finderOf(md);
 777 
 778         Configuration parent = Layer.boot().configuration();
 779         Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m"));
 780 
 781         Layer.boot().defineModules(cf, mn -> c.getClassLoader());
 782     }
 783 
 784 
 785     /**
 786      * Attempt to create a Layer with a module named "java.base".
 787      */
 788     public void testLayerWithJavaBase() {
 789         ModuleDescriptor descriptor
 790             = ModuleDescriptor.module("java.base")
 791                 .exports("java.lang")
 792                 .build();
 793 
 794         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 795 
 796         Configuration cf = Layer.boot()
 797             .configuration()
 798             .resolveRequires(finder, ModuleFinder.of(), Set.of("java.base"));
 799         assertTrue(cf.modules().size() == 1);
 800 
 801         ClassLoader scl = ClassLoader.getSystemClassLoader();
 802 
 803         try {
 804             Layer.boot().defineModules(cf, mn -> new ClassLoader() { });
 805             assertTrue(false);
 806         } catch (LayerInstantiationException e) { }
 807 
 808         try {
 809             Layer.boot().defineModulesWithOneLoader(cf, scl);
 810             assertTrue(false);
 811         } catch (LayerInstantiationException e) { }
 812 
 813         try {
 814             Layer.boot().defineModulesWithManyLoaders(cf, scl);
 815             assertTrue(false);
 816         } catch (LayerInstantiationException e) { }
 817     }
 818 
 819 
 820     /**
 821      * Attempt to create a Layer with a module containing a "java." package.
 822      * This should only be allowed when the module is defined to the platform
 823      * class loader.
 824      */
 825     @Test(enabled = false)
 826     public void testLayerWithJavaPackage() {
 827         ModuleDescriptor descriptor
 828             = ModuleDescriptor.module("foo")
 829                 .contains("java.foo")
 830                 .build();
 831 
 832         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 833 
 834         Configuration cf = Layer.boot()
 835                 .configuration()
 836                 .resolveRequires(finder, ModuleFinder.of(), Set.of("foo"));
 837         assertTrue(cf.modules().size() == 1);
 838 
 839         ClassLoader pcl = ClassLoader.getPlatformClassLoader();
 840         ClassLoader scl = ClassLoader.getSystemClassLoader();
 841 
 842         try {
 843             Layer.boot().defineModules(cf, mn -> new ClassLoader() { });
 844             assertTrue(false);
 845         } catch (LayerInstantiationException e) { }
 846 
 847         try {
 848             Layer.boot().defineModulesWithOneLoader(cf, scl);
 849             assertTrue(false);
 850         } catch (LayerInstantiationException e) { }
 851 
 852         try {
 853             Layer.boot().defineModulesWithManyLoaders(cf, scl);
 854             assertTrue(false);
 855         } catch (LayerInstantiationException e) { }
 856 
 857         // create layer with module defined to platform class loader
 858         Layer layer = Layer.boot().defineModules(cf, mn -> pcl);
 859         Optional<Module> om = layer.findModule("foo");
 860         assertTrue(om.isPresent());
 861         Module foo = om.get();
 862         assertTrue(foo.getClassLoader() == pcl);
 863         assertTrue(foo.getPackages().length == 1);
 864         assertTrue(foo.getPackages()[0].equals("java.foo"));
 865     }
 866 
 867 
 868     /**
 869      * Attempt to create a Layer with a module defined to the boot loader
 870      */
 871     @Test(expectedExceptions = { LayerInstantiationException.class })
 872     public void testLayerWithBootLoader() {
 873         ModuleDescriptor descriptor
 874             = ModuleDescriptor.module("m1")
 875                 .build();
 876 
 877         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 878 
 879         Configuration cf = Layer.boot()
 880             .configuration()
 881             .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
 882         assertTrue(cf.modules().size() == 1);
 883 
 884         Layer.boot().defineModules(cf, mn -> null );
 885     }
 886 
 887 
 888     /**
 889      * Parent of configuration != configuration of parent Layer
 890      */
 891     @Test(expectedExceptions = { IllegalArgumentException.class })
 892     public void testIncorrectParent1() {
 893 
 894         ModuleDescriptor descriptor1
 895             = ModuleDescriptor.module("m1")
 896                 .requires("java.base")
 897                 .build();
 898 
 899         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 900 
 901         Configuration parent = Layer.boot().configuration();
 902         Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
 903 
 904         ClassLoader loader = new ClassLoader() { };
 905         Layer.empty().defineModules(cf, mn -> loader);
 906     }
 907 
 908 
 909     /**
 910      * Parent of configuration != configuration of parent Layer
 911      */
 912     @Test(expectedExceptions = { IllegalArgumentException.class })
 913     public void testIncorrectParent2() {
 914 
 915         ModuleDescriptor descriptor1
 916             = ModuleDescriptor.module("m1")
 917                 .build();
 918 
 919         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 920 
 921         Configuration cf = resolveRequires(finder, "m1");
 922 
 923         ClassLoader loader = new ClassLoader() { };
 924         Layer.boot().defineModules(cf, mn -> loader);
 925     }
 926 
 927 
 928     // null handling
 929 
 930     @Test(expectedExceptions = { NullPointerException.class })
 931     public void testCreateWithNull1() {
 932         ClassLoader loader = new ClassLoader() { };
 933         Layer.empty().defineModules(null, mn -> loader);
 934     }
 935 
 936     @Test(expectedExceptions = { NullPointerException.class })
 937     public void testCreateWithNull2() {
 938         Configuration cf = resolveRequires(Layer.boot().configuration(), ModuleFinder.of());
 939         Layer.boot().defineModules(cf, null);
 940     }
 941 
 942     @Test(expectedExceptions = { NullPointerException.class })
 943     public void testCreateWithNull3() {
 944         ClassLoader scl = ClassLoader.getSystemClassLoader();
 945         Layer.empty().defineModulesWithOneLoader(null, scl);
 946     }
 947 
 948     @Test(expectedExceptions = { NullPointerException.class })
 949     public void testCreateWithNull4() {
 950         ClassLoader scl = ClassLoader.getSystemClassLoader();
 951         Layer.empty().defineModulesWithManyLoaders(null, scl);
 952     }
 953 
 954     @Test(expectedExceptions = { NullPointerException.class })
 955     public void testFindModuleWithNull() {
 956         Layer.boot().findModule(null);
 957     }
 958 
 959     @Test(expectedExceptions = { NullPointerException.class })
 960     public void testFindLoaderWithNull() {
 961         Layer.boot().findLoader(null);
 962     }
 963 
 964 
 965     // immutable sets
 966 
 967     @Test(expectedExceptions = { UnsupportedOperationException.class })
 968     public void testImmutableSet() {
 969         Module base = Object.class.getModule();
 970         Layer.boot().modules().add(base);
 971     }
 972 
 973 
 974     /**
 975      * Resolve the given modules, by name, and returns the resulting
 976      * Configuration.
 977      */
 978     private static Configuration resolveRequires(Configuration cf,
 979                                                  ModuleFinder finder,
 980                                                  String... roots) {
 981         return cf.resolveRequires(finder, ModuleFinder.of(), Set.of(roots));
 982     }
 983 
 984     private static Configuration resolveRequires(ModuleFinder finder,
 985                                                  String... roots) {
 986         return resolveRequires(Configuration.empty(), finder, roots);
 987     }
 988 }
   1 /*
   2  * Copyright (c) 2014, 2017, 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  * @library /lib/testlibrary
  27  * @modules java.base/jdk.internal.misc
  28  * @build BasicLayerTest ModuleUtils
  29  * @compile layertest/Test.java
  30  * @run testng BasicLayerTest
  31  * @summary Basic tests for java.lang.reflect.Layer
  32  */
  33 
  34 import java.lang.module.Configuration;
  35 import java.lang.module.ModuleDescriptor;
  36 import java.lang.module.ModuleDescriptor.Requires;
  37 import java.lang.module.ModuleFinder;
  38 import java.lang.reflect.Layer;
  39 import java.lang.reflect.LayerInstantiationException;
  40 import java.lang.reflect.Module;
  41 import java.util.HashMap;
  42 import java.util.Map;
  43 import java.util.Optional;
  44 import java.util.Set;
  45 import java.util.stream.Collectors;
  46 
  47 import jdk.internal.misc.SharedSecrets;
  48 import org.testng.annotations.Test;
  49 import static org.testng.Assert.*;
  50 
  51 @Test
  52 public class BasicLayerTest {
  53 
  54     /**
  55      * Creates a "non-strict" builder for building a module. This allows the
  56      * test the create ModuleDescriptor objects that do not require java.base.
  57      */
  58     private static ModuleDescriptor.Builder newBuilder(String mn) {
  59         return SharedSecrets.getJavaLangModuleAccess()
  60                 .newModuleBuilder(mn, false, Set.of());
  61     }
  62 
  63     /**
  64      * Exercise Layer.empty()
  65      */
  66     public void testEmpty() {
  67         Layer emptyLayer = Layer.empty();
  68 
  69         assertTrue(emptyLayer.parents().isEmpty());
  70 
  71         assertTrue(emptyLayer.configuration() == Configuration.empty());
  72 
  73         assertTrue(emptyLayer.modules().isEmpty());
  74 
  75         assertFalse(emptyLayer.findModule("java.base").isPresent());
  76 
  77         try {
  78             emptyLayer.findLoader("java.base");
  79             assertTrue(false);
  80         } catch (IllegalArgumentException expected) { }
  81     }
  82 
  83 


 103         assertEquals(count, modules.size()); // module names are unique
 104 
 105         // findModule
 106         Module base = Object.class.getModule();
 107         assertTrue(bootLayer.findModule("java.base").get() == base);
 108         assertTrue(base.getLayer() == bootLayer);
 109 
 110         // findLoader
 111         assertTrue(bootLayer.findLoader("java.base") == null);
 112 
 113         // parents
 114         assertTrue(bootLayer.parents().size() == 1);
 115         assertTrue(bootLayer.parents().get(0) == Layer.empty());
 116     }
 117 
 118 
 119     /**
 120      * Exercise Layer defineModules, created with empty layer as parent
 121      */
 122     public void testLayerOnEmpty() {
 123         ModuleDescriptor descriptor1 = newBuilder("m1")

 124                 .requires("m2")
 125                 .exports("p1")
 126                 .build();
 127 
 128         ModuleDescriptor descriptor2 = newBuilder("m2")

 129                 .requires("m3")
 130                 .build();
 131 
 132         ModuleDescriptor descriptor3 = newBuilder("m3")

 133                 .build();
 134 
 135         ModuleFinder finder
 136             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 137 
 138         Configuration cf = resolve(finder, "m1");
 139 
 140         // map each module to its own class loader for this test
 141         ClassLoader loader1 = new ClassLoader() { };
 142         ClassLoader loader2 = new ClassLoader() { };
 143         ClassLoader loader3 = new ClassLoader() { };
 144         Map<String, ClassLoader> map = new HashMap<>();
 145         map.put("m1", loader1);
 146         map.put("m2", loader2);
 147         map.put("m3", loader3);
 148 
 149         Layer layer = Layer.empty().defineModules(cf, map::get);
 150 
 151         // configuration
 152         assertTrue(layer.configuration() == cf);
 153         assertTrue(layer.configuration().modules().size() == 3);
 154 
 155         // modules
 156         Set<Module> modules = layer.modules();
 157         assertTrue(modules.size() == 3);
 158         Set<String> names = modules.stream()


 182 
 183         // findLoader
 184         assertTrue(layer.findLoader("m1") == loader1);
 185         assertTrue(layer.findLoader("m2") == loader2);
 186         assertTrue(layer.findLoader("m3") == loader3);
 187         try {
 188             ClassLoader loader = layer.findLoader("godot");
 189             assertTrue(false);
 190         } catch (IllegalArgumentException ignore) { }
 191 
 192         // parents
 193         assertTrue(layer.parents().size() == 1);
 194         assertTrue(layer.parents().get(0) == Layer.empty());
 195     }
 196 
 197 
 198     /**
 199      * Exercise Layer defineModules, created with boot layer as parent
 200      */
 201     public void testLayerOnBoot() {
 202         ModuleDescriptor descriptor1 = newBuilder("m1")

 203                 .requires("m2")
 204                 .requires("java.base")
 205                 .exports("p1")
 206                 .build();
 207 
 208         ModuleDescriptor descriptor2 = newBuilder("m2")

 209                 .requires("java.base")
 210                 .build();
 211 
 212         ModuleFinder finder
 213             = ModuleUtils.finderOf(descriptor1, descriptor2);
 214 
 215         Configuration parent = Layer.boot().configuration();
 216         Configuration cf = resolve(parent, finder, "m1");
 217 
 218         ClassLoader loader = new ClassLoader() { };
 219 
 220         Layer layer = Layer.boot().defineModules(cf, mn -> loader);
 221 
 222         // configuration
 223         assertTrue(layer.configuration() == cf);
 224         assertTrue(layer.configuration().modules().size() == 2);
 225 
 226         // modules
 227         Set<Module> modules = layer.modules();
 228         assertTrue(modules.size() == 2);
 229         Set<String> names = modules.stream()
 230             .map(Module::getName)
 231             .collect(Collectors.toSet());
 232         assertTrue(names.contains("m1"));
 233         assertTrue(names.contains("m2"));
 234 
 235         // findModule
 236         Module m1 = layer.findModule("m1").get();


 245         assertTrue(modules.contains(m2));
 246         assertTrue(layer.findModule("java.base").get() == Object.class.getModule());
 247         assertFalse(layer.findModule("godot").isPresent());
 248 
 249         // findLoader
 250         assertTrue(layer.findLoader("m1") == loader);
 251         assertTrue(layer.findLoader("m2") == loader);
 252         assertTrue(layer.findLoader("java.base") == null);
 253 
 254         // parents
 255         assertTrue(layer.parents().size() == 1);
 256         assertTrue(layer.parents().get(0) == Layer.boot());
 257     }
 258 
 259 
 260     /**
 261      * Exercise Layer defineModules with a configuration of two modules that
 262      * have the same module-private package.
 263      */
 264     public void testPackageContainedInSelfAndOther() {
 265         ModuleDescriptor descriptor1 =  newBuilder("m1")

 266                 .requires("m2")
 267                 .packages(Set.of("p"))
 268                 .build();
 269 
 270         ModuleDescriptor descriptor2 = newBuilder("m2")
 271                 .packages(Set.of("p"))

 272                 .build();
 273 
 274         ModuleFinder finder
 275             = ModuleUtils.finderOf(descriptor1, descriptor2);
 276 
 277         Configuration cf = resolve(finder, "m1");
 278         assertTrue(cf.modules().size() == 2);
 279 
 280         // one loader per module, should be okay
 281         Layer.empty().defineModules(cf, mn -> new ClassLoader() { });
 282 
 283         // same class loader
 284         try {
 285             ClassLoader loader = new ClassLoader() { };
 286             Layer.empty().defineModules(cf, mn -> loader);
 287             assertTrue(false);
 288         } catch (LayerInstantiationException expected) { }
 289     }
 290 
 291 
 292     /**
 293      * Exercise Layer defineModules with a configuration that is a partitioned
 294      * graph. The same package is exported in both partitions.
 295      */
 296     public void testSameExportInPartitionedGraph() {
 297 
 298         // m1 reads m2, m2 exports p to m1
 299         ModuleDescriptor descriptor1 =  newBuilder("m1")

 300                 .requires("m2")
 301                 .build();
 302         ModuleDescriptor descriptor2 =  newBuilder("m2")

 303                 .exports("p", Set.of("m1"))
 304                 .build();
 305 
 306         // m3 reads m4, m4 exports p to m3
 307         ModuleDescriptor descriptor3 = newBuilder("m3")

 308                 .requires("m4")
 309                 .build();
 310         ModuleDescriptor descriptor4 = newBuilder("m4")

 311                 .exports("p", Set.of("m3"))
 312                 .build();
 313 
 314         ModuleFinder finder
 315             = ModuleUtils.finderOf(descriptor1,
 316                                    descriptor2,
 317                                    descriptor3,
 318                                    descriptor4);
 319 
 320         Configuration cf = resolve(finder, "m1", "m3");
 321         assertTrue(cf.modules().size() == 4);
 322 
 323         // one loader per module
 324         Layer.empty().defineModules(cf, mn -> new ClassLoader() { });
 325 
 326         // m1 & m2 in one loader, m3 & m4 in another loader
 327         ClassLoader loader1 = new ClassLoader() { };
 328         ClassLoader loader2 = new ClassLoader() { };
 329         Map<String, ClassLoader> map = new HashMap<>();
 330         map.put("m1", loader1);
 331         map.put("m2", loader1);
 332         map.put("m3", loader2);
 333         map.put("m4", loader2);
 334         Layer.empty().defineModules(cf, map::get);
 335 
 336         // same loader
 337         try {
 338             ClassLoader loader = new ClassLoader() { };
 339             Layer.empty().defineModules(cf, mn -> loader);
 340             assertTrue(false);
 341         } catch (LayerInstantiationException expected) { }
 342     }
 343 
 344 
 345     /**
 346      * Exercise Layer defineModules with a configuration with a module that
 347      * contains a package that is the same name as a non-exported package in
 348      * a parent layer.
 349      */
 350     public void testContainsSamePackageAsBootLayer() {
 351 
 352         // check assumption that java.base contains sun.launcher
 353         ModuleDescriptor base = Object.class.getModule().getDescriptor();
 354         assertTrue(base.packages().contains("sun.launcher"));
 355 
 356         ModuleDescriptor descriptor = newBuilder("m1")

 357                .requires("java.base")
 358                .packages(Set.of("sun.launcher"))
 359                .build();
 360 
 361         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 362 
 363         Configuration parent = Layer.boot().configuration();
 364         Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
 365         assertTrue(cf.modules().size() == 1);
 366 
 367         ClassLoader loader = new ClassLoader() { };
 368         Layer layer = Layer.boot().defineModules(cf, mn -> loader);
 369         assertTrue(layer.modules().size() == 1);
 370    }
 371 
 372 
 373     /**
 374      * Test layers with implied readability.
 375      *
 376      * The test consists of three configurations:
 377      * - Configuration/layer1: m1, m2 requires transitive m1
 378      * - Configuration/layer2: m3 requires m1
 379      */
 380     public void testImpliedReadabilityWithLayers1() {
 381 
 382         // cf1: m1 and m2, m2 requires transitive m1
 383 
 384         ModuleDescriptor descriptor1 = newBuilder("m1")

 385                 .build();
 386 
 387         ModuleDescriptor descriptor2 = newBuilder("m2")

 388                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 389                 .build();
 390 
 391         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 392 
 393         Configuration cf1 = resolve(finder1, "m2");
 394 
 395         ClassLoader cl1 = new ClassLoader() { };
 396         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
 397 
 398 
 399         // cf2: m3, m3 requires m2
 400 
 401         ModuleDescriptor descriptor3 = newBuilder("m3")

 402                 .requires("m2")
 403                 .build();
 404 
 405         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 406 
 407         Configuration cf2 = resolve(cf1, finder2, "m3");
 408 
 409         ClassLoader cl2 = new ClassLoader() { };
 410         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
 411 
 412         assertTrue(layer1.parents().size() == 1);
 413         assertTrue(layer1.parents().get(0) == Layer.empty());
 414 
 415         assertTrue(layer2.parents().size() == 1);
 416         assertTrue(layer2.parents().get(0) == layer1);
 417 
 418         Module m1 = layer2.findModule("m1").get();
 419         Module m2 = layer2.findModule("m2").get();
 420         Module m3 = layer2.findModule("m3").get();
 421 
 422         assertTrue(m1.getLayer() == layer1);
 423         assertTrue(m2.getLayer() == layer1);
 424         assertTrue(m3.getLayer() == layer2);
 425 
 426         assertTrue(m1.getClassLoader() == cl1);
 427         assertTrue(m2.getClassLoader() == cl1);


 435         assertTrue(m2.canRead(m2));
 436         assertFalse(m2.canRead(m3));
 437 
 438         assertTrue(m3.canRead(m1));
 439         assertTrue(m3.canRead(m2));
 440         assertTrue(m3.canRead(m3));
 441     }
 442 
 443 
 444     /**
 445      * Test layers with implied readability.
 446      *
 447      * The test consists of three configurations:
 448      * - Configuration/layer1: m1
 449      * - Configuration/layer2: m2 requires transitive m3, m3 requires m2
 450      */
 451     public void testImpliedReadabilityWithLayers2() {
 452 
 453         // cf1: m1
 454 
 455         ModuleDescriptor descriptor1 = newBuilder("m1").build();


 456 
 457         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 458 
 459         Configuration cf1 = resolve(finder1, "m1");
 460 
 461         ClassLoader cl1 = new ClassLoader() { };
 462         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
 463 
 464 
 465         // cf2: m2, m3: m2 requires transitive m1, m3 requires m2
 466 
 467         ModuleDescriptor descriptor2 = newBuilder("m2")

 468                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 469                 .build();
 470 
 471         ModuleDescriptor descriptor3 = newBuilder("m3")

 472                 .requires("m2")
 473                 .build();
 474 
 475         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3);
 476 
 477         Configuration cf2 = resolve(cf1, finder2, "m3");
 478 
 479         ClassLoader cl2 = new ClassLoader() { };
 480         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
 481 
 482         assertTrue(layer1.parents().size() == 1);
 483         assertTrue(layer1.parents().get(0) == Layer.empty());
 484 
 485         assertTrue(layer2.parents().size() == 1);
 486         assertTrue(layer2.parents().get(0) == layer1);
 487 
 488         Module m1 = layer2.findModule("m1").get();
 489         Module m2 = layer2.findModule("m2").get();
 490         Module m3 = layer2.findModule("m3").get();
 491 
 492         assertTrue(m1.getLayer() == layer1);
 493         assertTrue(m2.getLayer() == layer2);
 494         assertTrue(m3.getLayer() == layer2);
 495 
 496         assertTrue(m1.canRead(m1));
 497         assertFalse(m1.canRead(m2));


 502         assertFalse(m2.canRead(m3));
 503 
 504         assertTrue(m3.canRead(m1));
 505         assertTrue(m3.canRead(m2));
 506         assertTrue(m3.canRead(m3));
 507     }
 508 
 509 
 510     /**
 511      * Test layers with implied readability.
 512      *
 513      * The test consists of three configurations:
 514      * - Configuration/layer1: m1
 515      * - Configuration/layer2: m2 requires transitive m1
 516      * - Configuration/layer3: m3 requires m1
 517      */
 518     public void testImpliedReadabilityWithLayers3() {
 519 
 520         // cf1: m1
 521 
 522         ModuleDescriptor descriptor1 = newBuilder("m1").build();


 523 
 524         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 525 
 526         Configuration cf1 = resolve(finder1, "m1");
 527 
 528         ClassLoader cl1 = new ClassLoader() { };
 529         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
 530 
 531 
 532         // cf2: m2 requires transitive m1
 533 
 534         ModuleDescriptor descriptor2 = newBuilder("m2")

 535                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 536                 .build();
 537 
 538         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
 539 
 540         Configuration cf2 = resolve(cf1, finder2, "m2");
 541 
 542         ClassLoader cl2 = new ClassLoader() { };
 543         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
 544 
 545 
 546         // cf3: m3 requires m2
 547 
 548         ModuleDescriptor descriptor3 = newBuilder("m3")

 549                 .requires("m2")
 550                 .build();
 551 
 552         ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3);
 553 
 554         Configuration cf3 = resolve(cf2, finder3, "m3");
 555 
 556         ClassLoader cl3 = new ClassLoader() { };
 557         Layer layer3 = layer2.defineModules(cf3, mn -> cl3);
 558 
 559         assertTrue(layer1.parents().size() == 1);
 560         assertTrue(layer1.parents().get(0) == Layer.empty());
 561 
 562         assertTrue(layer2.parents().size() == 1);
 563         assertTrue(layer2.parents().get(0) == layer1);
 564 
 565         assertTrue(layer3.parents().size() == 1);
 566         assertTrue(layer3.parents().get(0) == layer2);
 567 
 568         Module m1 = layer3.findModule("m1").get();
 569         Module m2 = layer3.findModule("m2").get();
 570         Module m3 = layer3.findModule("m3").get();
 571 
 572         assertTrue(m1.getLayer() == layer1);
 573         assertTrue(m2.getLayer() == layer2);
 574         assertTrue(m3.getLayer() == layer3);


 581         assertTrue(m2.canRead(m2));
 582         assertFalse(m2.canRead(m3));
 583 
 584         assertTrue(m3.canRead(m1));
 585         assertTrue(m3.canRead(m2));
 586         assertTrue(m3.canRead(m3));
 587     }
 588 
 589 
 590     /**
 591      * Test layers with implied readability.
 592      *
 593      * The test consists of two configurations:
 594      * - Configuration/layer1: m1, m2 requires transitive m1
 595      * - Configuration/layer2: m3 requires transitive m2, m4 requires m3
 596      */
 597     public void testImpliedReadabilityWithLayers4() {
 598 
 599         // cf1: m1, m2 requires transitive m1
 600 
 601         ModuleDescriptor descriptor1 = newBuilder("m1")

 602                 .build();
 603 
 604         ModuleDescriptor descriptor2 = newBuilder("m2")

 605                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
 606                 .build();
 607 
 608         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 609 
 610         Configuration cf1 = resolve(finder1, "m2");
 611 
 612         ClassLoader cl1 = new ClassLoader() { };
 613         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
 614 
 615 
 616         // cf2: m3 requires transitive m2, m4 requires m3
 617 
 618         ModuleDescriptor descriptor3 = newBuilder("m3")

 619                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m2")
 620                 .build();
 621 
 622         ModuleDescriptor descriptor4 = newBuilder("m4")

 623                 .requires("m3")
 624                 .build();
 625 
 626 
 627         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 628 
 629         Configuration cf2 = resolve(cf1, finder2, "m3", "m4");
 630 
 631         ClassLoader cl2 = new ClassLoader() { };
 632         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
 633 
 634         assertTrue(layer1.parents().size() == 1);
 635         assertTrue(layer1.parents().get(0) == Layer.empty());
 636 
 637         assertTrue(layer2.parents().size() == 1);
 638         assertTrue(layer2.parents().get(0) == layer1);
 639 
 640         Module m1 = layer2.findModule("m1").get();
 641         Module m2 = layer2.findModule("m2").get();
 642         Module m3 = layer2.findModule("m3").get();
 643         Module m4 = layer2.findModule("m4").get();
 644 
 645         assertTrue(m1.getLayer() == layer1);
 646         assertTrue(m2.getLayer() == layer1);
 647         assertTrue(m3.getLayer() == layer2);
 648         assertTrue(m4.getLayer() == layer2);
 649 


 660         assertTrue(m3.canRead(m1));
 661         assertTrue(m3.canRead(m2));
 662         assertTrue(m3.canRead(m3));
 663         assertFalse(m3.canRead(m4));
 664 
 665         assertTrue(m4.canRead(m1));
 666         assertTrue(m4.canRead(m2));
 667         assertTrue(m4.canRead(m3));
 668         assertTrue(m4.canRead(m4));
 669     }
 670 
 671 
 672     /**
 673      * Attempt to use Layer defineModules to create a layer with a module
 674      * defined to a class loader that already has a module of the same name
 675      * defined to the class loader.
 676      */
 677     @Test(expectedExceptions = { LayerInstantiationException.class })
 678     public void testModuleAlreadyDefinedToLoader() {
 679 
 680         ModuleDescriptor md = newBuilder("m")

 681                 .requires("java.base")
 682                 .build();
 683 
 684         ModuleFinder finder = ModuleUtils.finderOf(md);
 685 
 686         Configuration parent = Layer.boot().configuration();
 687 
 688         Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m"));
 689 
 690         ClassLoader loader = new ClassLoader() { };
 691 
 692         Layer.boot().defineModules(cf, mn -> loader);
 693 
 694         // should throw LayerInstantiationException as m1 already defined to loader
 695         Layer.boot().defineModules(cf, mn -> loader);
 696 
 697     }
 698 
 699 
 700     /**
 701      * Attempt to use Layer defineModules to create a Layer with a module
 702      * containing package {@code p} where the class loader already has a module
 703      * defined to it containing package {@code p}.
 704      */
 705     @Test(expectedExceptions = { LayerInstantiationException.class })
 706     public void testPackageAlreadyInNamedModule() {
 707 
 708         ModuleDescriptor md1 = newBuilder("m1")
 709                 .packages(Set.of("p"))

 710                 .requires("java.base")
 711                 .build();
 712 
 713         ModuleDescriptor md2 = newBuilder("m2")
 714                 .packages(Set.of("p"))

 715                 .requires("java.base")
 716                 .build();
 717 
 718         ModuleFinder finder = ModuleUtils.finderOf(md1, md2);
 719 
 720         ClassLoader loader = new ClassLoader() { };
 721 
 722         // define m1 containing package p to class loader
 723 
 724         Configuration parent = Layer.boot().configuration();
 725 
 726         Configuration cf1 = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
 727 
 728         Layer layer1 = Layer.boot().defineModules(cf1, mn -> loader);
 729 
 730         // attempt to define m2 containing package p to class loader
 731 
 732         Configuration cf2 = parent.resolve(finder, ModuleFinder.of(), Set.of("m2"));
 733 
 734         // should throw exception because p already in m1
 735         Layer layer2 = Layer.boot().defineModules(cf2, mn -> loader);
 736 
 737     }
 738 
 739 
 740     /**
 741      * Attempt to use Layer defineModules to create a Layer with a module
 742      * containing a package in which a type is already loaded by the class
 743      * loader.
 744      */
 745     @Test(expectedExceptions = { LayerInstantiationException.class })
 746     public void testPackageAlreadyInUnnamedModule() throws Exception {
 747 
 748         Class<?> c = layertest.Test.class;
 749         assertFalse(c.getModule().isNamed());  // in unnamed module
 750 
 751         ModuleDescriptor md = newBuilder("m")
 752                 .packages(Set.of(c.getPackageName()))

 753                 .requires("java.base")
 754                 .build();
 755 
 756         ModuleFinder finder = ModuleUtils.finderOf(md);
 757 
 758         Configuration parent = Layer.boot().configuration();
 759         Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m"));
 760 
 761         Layer.boot().defineModules(cf, mn -> c.getClassLoader());
 762     }
 763 
 764 
 765     /**
 766      * Attempt to create a Layer with a module named "java.base".
 767      */
 768     public void testLayerWithJavaBase() {
 769         ModuleDescriptor descriptor = newBuilder("java.base")

 770                 .exports("java.lang")
 771                 .build();
 772 
 773         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 774 
 775         Configuration cf = Layer.boot()
 776             .configuration()
 777             .resolve(finder, ModuleFinder.of(), Set.of("java.base"));
 778         assertTrue(cf.modules().size() == 1);
 779 
 780         ClassLoader scl = ClassLoader.getSystemClassLoader();
 781 
 782         try {
 783             Layer.boot().defineModules(cf, mn -> new ClassLoader() { });
 784             assertTrue(false);
 785         } catch (LayerInstantiationException e) { }
 786 
 787         try {
 788             Layer.boot().defineModulesWithOneLoader(cf, scl);
 789             assertTrue(false);
 790         } catch (LayerInstantiationException e) { }
 791 
 792         try {
 793             Layer.boot().defineModulesWithManyLoaders(cf, scl);
 794             assertTrue(false);
 795         } catch (LayerInstantiationException e) { }
 796     }
 797 
 798 
 799     /**
 800      * Attempt to create a Layer with a module containing a "java." package.
 801      * This should only be allowed when the module is defined to the platform
 802      * class loader.
 803      */
 804     @Test(enabled = false)
 805     public void testLayerWithJavaPackage() {
 806         ModuleDescriptor descriptor = newBuilder("foo")
 807                 .packages(Set.of("java.foo"))

 808                 .build();
 809 
 810         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 811 
 812         Configuration cf = Layer.boot()
 813                 .configuration()
 814                 .resolve(finder, ModuleFinder.of(), Set.of("foo"));
 815         assertTrue(cf.modules().size() == 1);
 816 
 817         ClassLoader pcl = ClassLoader.getPlatformClassLoader();
 818         ClassLoader scl = ClassLoader.getSystemClassLoader();
 819 
 820         try {
 821             Layer.boot().defineModules(cf, mn -> new ClassLoader() { });
 822             assertTrue(false);
 823         } catch (LayerInstantiationException e) { }
 824 
 825         try {
 826             Layer.boot().defineModulesWithOneLoader(cf, scl);
 827             assertTrue(false);
 828         } catch (LayerInstantiationException e) { }
 829 
 830         try {
 831             Layer.boot().defineModulesWithManyLoaders(cf, scl);
 832             assertTrue(false);
 833         } catch (LayerInstantiationException e) { }
 834 
 835         // create layer with module defined to platform class loader
 836         Layer layer = Layer.boot().defineModules(cf, mn -> pcl);
 837         Optional<Module> om = layer.findModule("foo");
 838         assertTrue(om.isPresent());
 839         Module foo = om.get();
 840         assertTrue(foo.getClassLoader() == pcl);
 841         assertTrue(foo.getPackages().length == 1);
 842         assertTrue(foo.getPackages()[0].equals("java.foo"));
 843     }
 844 
 845 
 846     /**
 847      * Attempt to create a Layer with a module defined to the boot loader
 848      */
 849     @Test(expectedExceptions = { LayerInstantiationException.class })
 850     public void testLayerWithBootLoader() {
 851         ModuleDescriptor descriptor = newBuilder("m1")

 852                 .build();
 853 
 854         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 855 
 856         Configuration cf = Layer.boot()
 857             .configuration()
 858             .resolve(finder, ModuleFinder.of(), Set.of("m1"));
 859         assertTrue(cf.modules().size() == 1);
 860 
 861         Layer.boot().defineModules(cf, mn -> null );
 862     }
 863 
 864 
 865     /**
 866      * Parent of configuration != configuration of parent Layer
 867      */
 868     @Test(expectedExceptions = { IllegalArgumentException.class })
 869     public void testIncorrectParent1() {
 870 
 871         ModuleDescriptor descriptor1 = newBuilder("m1")

 872                 .requires("java.base")
 873                 .build();
 874 
 875         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 876 
 877         Configuration parent = Layer.boot().configuration();
 878         Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
 879 
 880         ClassLoader loader = new ClassLoader() { };
 881         Layer.empty().defineModules(cf, mn -> loader);
 882     }
 883 
 884 
 885     /**
 886      * Parent of configuration != configuration of parent Layer
 887      */
 888     @Test(expectedExceptions = { IllegalArgumentException.class })
 889     public void testIncorrectParent2() {
 890 
 891         ModuleDescriptor descriptor1 = newBuilder("m1")

 892                 .build();
 893 
 894         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 895 
 896         Configuration cf = resolve(finder, "m1");
 897 
 898         ClassLoader loader = new ClassLoader() { };
 899         Layer.boot().defineModules(cf, mn -> loader);
 900     }
 901 
 902 
 903     // null handling
 904 
 905     @Test(expectedExceptions = { NullPointerException.class })
 906     public void testCreateWithNull1() {
 907         ClassLoader loader = new ClassLoader() { };
 908         Layer.empty().defineModules(null, mn -> loader);
 909     }
 910 
 911     @Test(expectedExceptions = { NullPointerException.class })
 912     public void testCreateWithNull2() {
 913         Configuration cf = resolve(Layer.boot().configuration(), ModuleFinder.of());
 914         Layer.boot().defineModules(cf, null);
 915     }
 916 
 917     @Test(expectedExceptions = { NullPointerException.class })
 918     public void testCreateWithNull3() {
 919         ClassLoader scl = ClassLoader.getSystemClassLoader();
 920         Layer.empty().defineModulesWithOneLoader(null, scl);
 921     }
 922 
 923     @Test(expectedExceptions = { NullPointerException.class })
 924     public void testCreateWithNull4() {
 925         ClassLoader scl = ClassLoader.getSystemClassLoader();
 926         Layer.empty().defineModulesWithManyLoaders(null, scl);
 927     }
 928 
 929     @Test(expectedExceptions = { NullPointerException.class })
 930     public void testFindModuleWithNull() {
 931         Layer.boot().findModule(null);
 932     }
 933 
 934     @Test(expectedExceptions = { NullPointerException.class })
 935     public void testFindLoaderWithNull() {
 936         Layer.boot().findLoader(null);
 937     }
 938 
 939 
 940     // immutable sets
 941 
 942     @Test(expectedExceptions = { UnsupportedOperationException.class })
 943     public void testImmutableSet() {
 944         Module base = Object.class.getModule();
 945         Layer.boot().modules().add(base);
 946     }
 947 
 948 
 949     /**
 950      * Resolve the given modules, by name, and returns the resulting
 951      * Configuration.
 952      */
 953     private static Configuration resolve(Configuration cf,
 954                                          ModuleFinder finder,
 955                                          String... roots) {
 956         return cf.resolve(finder, ModuleFinder.of(), Set.of(roots));
 957     }
 958 
 959     private static Configuration resolve(ModuleFinder finder,
 960                                          String... roots) {
 961         return resolve(Configuration.empty(), finder, roots);
 962     }
 963 }
< prev index next >