< prev index next >

test/java/lang/reflect/Layer/LayerAndLoadersTest.java

Print this page




  64     private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
  65     private static final Path MODS_DIR = Paths.get("mods");
  66 
  67     @BeforeTest
  68     public void setup() throws Exception {
  69 
  70         // javac -d mods --module-source-path src src/**
  71         assertTrue(CompilerUtils.compile(SRC_DIR, MODS_DIR,
  72                 "--module-source-path", SRC_DIR.toString()));
  73     }
  74 
  75 
  76     /**
  77      * Basic test of Layer defineModulesWithOneLoader
  78      *
  79      * Test scenario:
  80      *   m1 requires m2 and m3
  81      */
  82     public void testWithOneLoader() throws Exception {
  83 
  84         Configuration cf = resolveRequires("m1");
  85 
  86         ClassLoader scl = ClassLoader.getSystemClassLoader();
  87 
  88         Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
  89 
  90         checkLayer(layer, "m1", "m2", "m3");
  91 
  92         ClassLoader cl1 = layer.findLoader("m1");
  93         ClassLoader cl2 = layer.findLoader("m2");
  94         ClassLoader cl3 = layer.findLoader("m3");
  95 
  96         assertTrue(cl1.getParent() == scl);
  97         assertTrue(cl2 == cl1);
  98         assertTrue(cl3 == cl1);
  99 
 100         invoke(layer, "m1", "p.Main");
 101 
 102     }
 103 
 104 
 105     /**
 106      * Basic test of Layer defineModulesWithManyLoaders
 107      *
 108      * Test scenario:
 109      *   m1 requires m2 and m3
 110      */
 111     public void testWithManyLoaders() throws Exception {
 112 
 113         Configuration cf = resolveRequires("m1");
 114 
 115         ClassLoader scl = ClassLoader.getSystemClassLoader();
 116 
 117         Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl);
 118 
 119         checkLayer(layer, "m1", "m2", "m3");
 120 
 121         ClassLoader cl1 = layer.findLoader("m1");
 122         ClassLoader cl2 = layer.findLoader("m2");
 123         ClassLoader cl3 = layer.findLoader("m3");
 124 
 125         assertTrue(cl1.getParent() == scl);
 126         assertTrue(cl2.getParent() == scl);
 127         assertTrue(cl3.getParent() == scl);
 128         assertTrue(cl2 != cl1);
 129         assertTrue(cl3 != cl1);
 130         assertTrue(cl3 != cl2);
 131 
 132         invoke(layer, "m1", "p.Main");
 133 
 134     }
 135 
 136 
 137     /**
 138      * Basic test of Layer defineModulesWithOneLoader where one of the modules
 139      * is a service provider module.
 140      *
 141      * Test scenario:
 142      *    m1 requires m2 and m3
 143      *    m1 uses S
 144      *    m4 provides S with ...
 145      */
 146     public void testServicesWithOneLoader() throws Exception {
 147 
 148         Configuration cf = resolveRequiresAndUses("m1");
 149 
 150         ClassLoader scl = ClassLoader.getSystemClassLoader();
 151 
 152         Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
 153 
 154         checkLayer(layer, "m1", "m2", "m3", "m4");
 155 
 156         ClassLoader cl1 = layer.findLoader("m1");
 157         ClassLoader cl2 = layer.findLoader("m2");
 158         ClassLoader cl3 = layer.findLoader("m3");
 159         ClassLoader cl4 = layer.findLoader("m4");
 160 
 161         assertTrue(cl1.getParent() == scl);
 162         assertTrue(cl2 == cl1);
 163         assertTrue(cl3 == cl1);
 164         assertTrue(cl4 == cl1);
 165 
 166         Class<?> serviceType = cl1.loadClass("p.Service");
 167         assertTrue(serviceType.getClassLoader() == cl1);
 168 
 169         Iterator<?> iter = ServiceLoader.load(serviceType, cl1).iterator();
 170         Object provider = iter.next();
 171         assertTrue(serviceType.isInstance(provider));
 172         assertTrue(provider.getClass().getClassLoader() == cl1);
 173         assertFalse(iter.hasNext());
 174 
 175     }
 176 
 177 
 178     /**
 179      * Basic test of Layer defineModulesWithManyLoaders where one of the
 180      * modules is a service provider module.
 181      *
 182      * Test scenario:
 183      *    m1 requires m2 and m3
 184      *    m1 uses S
 185      *    m4 provides S with ...
 186      */
 187     public void testServicesWithManyLoaders() throws Exception {
 188 
 189         Configuration cf = resolveRequiresAndUses("m1");
 190 
 191         ClassLoader scl = ClassLoader.getSystemClassLoader();
 192 
 193         Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl);
 194 
 195         checkLayer(layer, "m1", "m2", "m3", "m4");
 196 
 197         ClassLoader cl1 = layer.findLoader("m1");
 198         ClassLoader cl2 = layer.findLoader("m2");
 199         ClassLoader cl3 = layer.findLoader("m3");
 200         ClassLoader cl4 = layer.findLoader("m4");
 201 
 202         assertTrue(cl1.getParent() == scl);
 203         assertTrue(cl2.getParent() == scl);
 204         assertTrue(cl3.getParent() == scl);
 205         assertTrue(cl4.getParent() == scl);
 206         assertTrue(cl2 != cl1);
 207         assertTrue(cl3 != cl1);
 208         assertTrue(cl3 != cl2);
 209         assertTrue(cl4 != cl1);


 216         // Test that the service provider can be located via any of
 217         // the class loaders in the layer
 218         for (Module m : layer.modules()) {
 219             ClassLoader loader = m.getClassLoader();
 220             Iterator<?> iter = ServiceLoader.load(serviceType, loader).iterator();
 221             Object provider = iter.next();
 222             assertTrue(serviceType.isInstance(provider));
 223             assertTrue(provider.getClass().getClassLoader() == cl4);
 224             assertFalse(iter.hasNext());
 225         }
 226 
 227     }
 228 
 229 
 230     /**
 231      * Tests that the class loaders created by defineModulesWithXXX delegate
 232      * to the given parent class loader.
 233      */
 234     public void testDelegationToParent() throws Exception {
 235 
 236         Configuration cf = resolveRequires("m1");
 237 
 238         ClassLoader parent = this.getClass().getClassLoader();
 239         String cn = this.getClass().getName();
 240 
 241         // one loader
 242         Layer layer = Layer.boot().defineModulesWithOneLoader(cf, parent);
 243         testLoad(layer, cn);
 244 
 245          // one loader with boot loader as parent
 246         layer = Layer.boot().defineModulesWithOneLoader(cf, null);
 247         testLoadFail(layer, cn);
 248 
 249         // many loaders
 250         layer = Layer.boot().defineModulesWithManyLoaders(cf, parent);
 251         testLoad(layer, cn);
 252 
 253         // many loader with boot loader as parent
 254         layer = Layer.boot().defineModulesWithManyLoaders(cf, null);
 255         testLoadFail(layer, cn);
 256 
 257     }
 258 
 259 
 260     /**
 261      * Test defineModulesWithXXX when modules that have overlapping packages.
 262      *
 263      * Test scenario:
 264      *   m1 exports p
 265      *   m2 exports p
 266      */
 267     public void testOverlappingPackages() {
 268 
 269         ModuleDescriptor descriptor1
 270             = ModuleDescriptor.module("m1").exports("p").build();
 271 
 272         ModuleDescriptor descriptor2
 273             = ModuleDescriptor.module("m2").exports("p").build();
 274 
 275         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 276 
 277         Configuration cf = Layer.boot()
 278             .configuration()
 279             .resolveRequires(finder, ModuleFinder.of(), Set.of("m1", "m2"));
 280 
 281         // cannot define both module m1 and m2 to the same class loader
 282         try {
 283             Layer.boot().defineModulesWithOneLoader(cf, null);
 284             assertTrue(false);
 285         } catch (LayerInstantiationException expected) { }
 286 
 287         // should be okay to have one module per class loader
 288         Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, null);
 289         checkLayer(layer, "m1", "m2");
 290 
 291     }
 292 
 293 
 294     /**
 295      * Test Layer defineModulesWithXXX with split delegation.
 296      *
 297      * Test scenario:
 298      *   layer1: m1 exports p, m2 exports p
 299      *   layer2: m3 reads m1, m4 reads m2
 300      */
 301     public void testSplitDelegation() {
 302 
 303         ModuleDescriptor descriptor1
 304             = ModuleDescriptor.module("m1").exports("p").build();
 305 
 306         ModuleDescriptor descriptor2
 307             = ModuleDescriptor.module("m2").exports("p").build();
 308 
 309         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 310 
 311         Configuration cf1 = Layer.boot()
 312             .configuration()
 313             .resolveRequires(finder1, ModuleFinder.of(), Set.of("m1", "m2"));
 314 
 315         Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
 316         checkLayer(layer1, "m1", "m2");
 317 
 318         ModuleDescriptor descriptor3
 319             = ModuleDescriptor.module("m3").requires("m1").build();
 320 
 321         ModuleDescriptor descriptor4
 322             = ModuleDescriptor.module("m4").requires("m2").build();
 323 
 324         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 325 
 326         Configuration cf2 = cf1.resolveRequires(finder2, ModuleFinder.of(),
 327                                                 Set.of("m3", "m4"));
 328 
 329         // package p cannot be supplied by two class loaders
 330         try {
 331             layer1.defineModulesWithOneLoader(cf2, null);
 332             assertTrue(false);
 333         } catch (LayerInstantiationException expected) { }
 334 
 335         // no split delegation when modules have their own class loader
 336         Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
 337         checkLayer(layer2, "m3", "m4");
 338 
 339     }
 340 
 341 
 342     /**
 343      * Test Layer defineModulesWithXXX when the modules that override same
 344      * named modules in the parent layer.
 345      *
 346      * Test scenario:
 347      *   layer1: m1, m2, m3 => same loader
 348      *   layer2: m1, m2, m4 => same loader
 349      */
 350     public void testOverriding1() throws Exception {
 351 
 352         Configuration cf1 = resolveRequires("m1");
 353 
 354         Layer layer1 = Layer.boot().defineModulesWithOneLoader(cf1, null);
 355         checkLayer(layer1, "m1", "m2", "m3");
 356 
 357         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
 358         Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
 359                                                 Set.of("m1"));
 360 
 361         Layer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
 362         checkLayer(layer2, "m1", "m2", "m3");
 363         invoke(layer1, "m1", "p.Main");
 364 
 365         ClassLoader loader1 = layer1.findLoader("m1");
 366         ClassLoader loader2 = layer1.findLoader("m2");
 367         ClassLoader loader3 = layer1.findLoader("m3");
 368 
 369         ClassLoader loader4 = layer2.findLoader("m1");
 370         ClassLoader loader5 = layer2.findLoader("m2");
 371         ClassLoader loader6 = layer2.findLoader("m3");
 372 
 373         assertTrue(loader1 == loader2);
 374         assertTrue(loader1 == loader3);
 375 
 376         assertTrue(loader4 == loader5);
 377         assertTrue(loader4 == loader6);
 378         assertTrue(loader4 != loader1);


 381         assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1);
 382         assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1);
 383 
 384         assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);
 385         assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader4);
 386         assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader4);
 387 
 388     }
 389 
 390 
 391     /**
 392      * Test Layer defineModulesWithXXX when the modules that override same
 393      * named modules in the parent layer.
 394      *
 395      * Test scenario:
 396      *   layer1: m1, m2, m3 => loader pool
 397      *   layer2: m1, m2, m3 => loader pool
 398      */
 399     public void testOverriding2() throws Exception {
 400 
 401         Configuration cf1 = resolveRequires("m1");
 402 
 403         Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
 404         checkLayer(layer1, "m1", "m2", "m3");
 405 
 406         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
 407         Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
 408                                                 Set.of("m1"));
 409 
 410         Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
 411         checkLayer(layer2, "m1", "m2", "m3");
 412         invoke(layer1, "m1", "p.Main");
 413 
 414         ClassLoader loader1 = layer1.findLoader("m1");
 415         ClassLoader loader2 = layer1.findLoader("m2");
 416         ClassLoader loader3 = layer1.findLoader("m3");
 417 
 418         ClassLoader loader4 = layer2.findLoader("m1");
 419         ClassLoader loader5 = layer2.findLoader("m2");
 420         ClassLoader loader6 = layer2.findLoader("m3");
 421 
 422         assertTrue(loader4 != loader1);
 423         assertTrue(loader5 != loader2);
 424         assertTrue(loader6 != loader3);
 425 
 426         assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
 427         assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader2);


 475         } catch (ClassNotFoundException expected) { }
 476 
 477         // q.Hello is not visible via loader6
 478         try {
 479             loader6.loadClass("q.Hello");
 480             assertTrue(false);
 481         } catch (ClassNotFoundException expected) { }
 482 
 483     }
 484 
 485 
 486     /**
 487      * Test Layer defineModulesWithXXX when the modules that override same
 488      * named modules in the parent layer.
 489      *
 490      * layer1: m1, m2, m3 => same loader
 491      * layer2: m1, m3 => same loader
 492      */
 493     public void testOverriding3() throws Exception {
 494 
 495         Configuration cf1 = resolveRequires("m1");
 496 
 497         Layer layer1 = Layer.boot().defineModulesWithOneLoader(cf1, null);
 498         checkLayer(layer1, "m1", "m2", "m3");
 499 
 500         ModuleFinder finder = finderFor("m1", "m3");
 501 
 502         Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
 503                                                 Set.of("m1"));
 504 
 505         Layer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
 506         checkLayer(layer2, "m1", "m3");
 507         invoke(layer1, "m1", "p.Main");
 508 
 509         ClassLoader loader1 = layer1.findLoader("m1");
 510         ClassLoader loader2 = layer2.findLoader("m1");
 511 
 512         assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
 513         assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1);
 514         assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1);
 515 
 516         assertTrue(loader2.loadClass("p.Main").getClassLoader() == loader2);
 517         assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader1);
 518         assertTrue(loader2.loadClass("w.Hello").getClassLoader() == loader2);
 519 
 520     }
 521 
 522 
 523     /**
 524      * Test Layer defineModulesWithXXX when the modules that override same
 525      * named modules in the parent layer.
 526      *
 527      * layer1: m1, m2, m3 => loader pool
 528      * layer2: m1, m3 => loader pool
 529      */
 530     public void testOverriding4() throws Exception {
 531 
 532         Configuration cf1 = resolveRequires("m1");
 533 
 534         Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
 535         checkLayer(layer1, "m1", "m2", "m3");
 536 
 537         ModuleFinder finder = finderFor("m1", "m3");
 538 
 539         Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
 540                                                 Set.of("m1"));
 541 
 542         Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
 543         checkLayer(layer2, "m1", "m3");
 544         invoke(layer1, "m1", "p.Main");
 545 
 546         ClassLoader loader1 = layer1.findLoader("m1");
 547         ClassLoader loader2 = layer1.findLoader("m2");
 548         ClassLoader loader3 = layer1.findLoader("m3");
 549 
 550         ClassLoader loader4 = layer2.findLoader("m1");
 551         ClassLoader loader5 = layer2.findLoader("m2");
 552         ClassLoader loader6 = layer2.findLoader("m3");
 553 
 554         assertTrue(loader4 != loader1);
 555         assertTrue(loader5 == loader2);  // m2 not overridden
 556         assertTrue(loader6 != loader3);
 557 
 558         assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
 559         assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader2);
 560         assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader3);
 561 
 562         assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader2);
 563 
 564         assertTrue(loader3.loadClass("w.Hello").getClassLoader() == loader3);
 565 
 566         assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);
 567         assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader2);
 568         assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader6);
 569 
 570         assertTrue(loader6.loadClass("w.Hello").getClassLoader() == loader6);
 571 
 572     }
 573 
 574 
 575     /**
 576      * Basic test of resource loading with a class loader created by
 577      * Layer.defineModulesWithOneLoader.
 578      */
 579     public void testResourcesOneLoader() throws Exception {
 580         Configuration cf = resolveRequires("m1");
 581         ClassLoader scl = ClassLoader.getSystemClassLoader();
 582         Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
 583         ClassLoader loader = layer.findLoader("m1");
 584         testResourceLoading(loader, "p/Main.class");
 585     }
 586 
 587     /**
 588      * Basic test of resource loading with a class loader created by
 589      * Layer.defineModulesWithOneLoader.
 590      */
 591     public void testResourcesManyLoaders() throws Exception {
 592         Configuration cf = resolveRequires("m1");
 593         ClassLoader scl = ClassLoader.getSystemClassLoader();
 594         Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl);
 595         ClassLoader loader = layer.findLoader("m1");
 596         testResourceLoading(loader, "p/Main.class");
 597     }
 598 
 599     /**
 600      * Test that a resource is located by a class loader.
 601      */
 602     private void testResourceLoading(ClassLoader loader, String name)
 603         throws IOException
 604     {
 605         URL url = loader.getResource(name);
 606         assertNotNull(url);
 607 
 608         try (InputStream in = loader.getResourceAsStream(name)) {
 609             assertNotNull(in);
 610         }
 611 
 612         Enumeration<URL> urls = loader.getResources(name);
 613         assertTrue(urls.hasMoreElements());
 614     }
 615 
 616 
 617     // -- supporting methods --
 618 
 619 
 620     /**
 621      * Resolve the given modules, by name, and returns the resulting
 622      * Configuration.
 623      */
 624     private static Configuration resolveRequires(String... roots) {
 625         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
 626         return Layer.boot()
 627             .configuration()
 628             .resolveRequires(finder, ModuleFinder.of(), Set.of(roots));
 629     }
 630 
 631     /**
 632      * Resolve the given modules, by name, and returns the resulting
 633      * Configuration.
 634      */
 635     private static Configuration resolveRequiresAndUses(String... roots) {
 636         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
 637         return Layer.boot()
 638             .configuration()
 639             .resolveRequiresAndUses(finder, ModuleFinder.of(), Set.of(roots));
 640     }
 641 
 642 
 643     /**
 644      * Invokes the static void main(String[]) method on the given class
 645      * in the given module.
 646      */
 647     private static void invoke(Layer layer, String mn, String mc) throws Exception {
 648         ClassLoader loader = layer.findLoader(mn);
 649         Class<?> c = loader.loadClass(mc);
 650         Method mainMethod = c.getMethod("main", String[].class);
 651         mainMethod.invoke(null, (Object)new String[0]);
 652     }
 653 
 654 
 655     /**
 656      * Checks that the given layer contains exactly the expected modules
 657      * (by name).
 658      */
 659     private void checkLayer(Layer layer, String ... expected) {




  64     private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
  65     private static final Path MODS_DIR = Paths.get("mods");
  66 
  67     @BeforeTest
  68     public void setup() throws Exception {
  69 
  70         // javac -d mods --module-source-path src src/**
  71         assertTrue(CompilerUtils.compile(SRC_DIR, MODS_DIR,
  72                 "--module-source-path", SRC_DIR.toString()));
  73     }
  74 
  75 
  76     /**
  77      * Basic test of Layer defineModulesWithOneLoader
  78      *
  79      * Test scenario:
  80      *   m1 requires m2 and m3
  81      */
  82     public void testWithOneLoader() throws Exception {
  83 
  84         Configuration cf = resolve("m1");
  85 
  86         ClassLoader scl = ClassLoader.getSystemClassLoader();
  87 
  88         Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
  89 
  90         checkLayer(layer, "m1", "m2", "m3");
  91 
  92         ClassLoader cl1 = layer.findLoader("m1");
  93         ClassLoader cl2 = layer.findLoader("m2");
  94         ClassLoader cl3 = layer.findLoader("m3");
  95 
  96         assertTrue(cl1.getParent() == scl);
  97         assertTrue(cl2 == cl1);
  98         assertTrue(cl3 == cl1);
  99 
 100         invoke(layer, "m1", "p.Main");
 101 
 102     }
 103 
 104 
 105     /**
 106      * Basic test of Layer defineModulesWithManyLoaders
 107      *
 108      * Test scenario:
 109      *   m1 requires m2 and m3
 110      */
 111     public void testWithManyLoaders() throws Exception {
 112 
 113         Configuration cf = resolve("m1");
 114 
 115         ClassLoader scl = ClassLoader.getSystemClassLoader();
 116 
 117         Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl);
 118 
 119         checkLayer(layer, "m1", "m2", "m3");
 120 
 121         ClassLoader cl1 = layer.findLoader("m1");
 122         ClassLoader cl2 = layer.findLoader("m2");
 123         ClassLoader cl3 = layer.findLoader("m3");
 124 
 125         assertTrue(cl1.getParent() == scl);
 126         assertTrue(cl2.getParent() == scl);
 127         assertTrue(cl3.getParent() == scl);
 128         assertTrue(cl2 != cl1);
 129         assertTrue(cl3 != cl1);
 130         assertTrue(cl3 != cl2);
 131 
 132         invoke(layer, "m1", "p.Main");
 133 
 134     }
 135 
 136 
 137     /**
 138      * Basic test of Layer defineModulesWithOneLoader where one of the modules
 139      * is a service provider module.
 140      *
 141      * Test scenario:
 142      *    m1 requires m2 and m3
 143      *    m1 uses S
 144      *    m4 provides S with ...
 145      */
 146     public void testServicesWithOneLoader() throws Exception {
 147 
 148         Configuration cf = resolveAndBind("m1");
 149 
 150         ClassLoader scl = ClassLoader.getSystemClassLoader();
 151 
 152         Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
 153 
 154         checkLayer(layer, "m1", "m2", "m3", "m4");
 155 
 156         ClassLoader cl1 = layer.findLoader("m1");
 157         ClassLoader cl2 = layer.findLoader("m2");
 158         ClassLoader cl3 = layer.findLoader("m3");
 159         ClassLoader cl4 = layer.findLoader("m4");
 160 
 161         assertTrue(cl1.getParent() == scl);
 162         assertTrue(cl2 == cl1);
 163         assertTrue(cl3 == cl1);
 164         assertTrue(cl4 == cl1);
 165 
 166         Class<?> serviceType = cl1.loadClass("p.Service");
 167         assertTrue(serviceType.getClassLoader() == cl1);
 168 
 169         Iterator<?> iter = ServiceLoader.load(serviceType, cl1).iterator();
 170         Object provider = iter.next();
 171         assertTrue(serviceType.isInstance(provider));
 172         assertTrue(provider.getClass().getClassLoader() == cl1);
 173         assertFalse(iter.hasNext());
 174 
 175     }
 176 
 177 
 178     /**
 179      * Basic test of Layer defineModulesWithManyLoaders where one of the
 180      * modules is a service provider module.
 181      *
 182      * Test scenario:
 183      *    m1 requires m2 and m3
 184      *    m1 uses S
 185      *    m4 provides S with ...
 186      */
 187     public void testServicesWithManyLoaders() throws Exception {
 188 
 189         Configuration cf = resolveAndBind("m1");
 190 
 191         ClassLoader scl = ClassLoader.getSystemClassLoader();
 192 
 193         Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl);
 194 
 195         checkLayer(layer, "m1", "m2", "m3", "m4");
 196 
 197         ClassLoader cl1 = layer.findLoader("m1");
 198         ClassLoader cl2 = layer.findLoader("m2");
 199         ClassLoader cl3 = layer.findLoader("m3");
 200         ClassLoader cl4 = layer.findLoader("m4");
 201 
 202         assertTrue(cl1.getParent() == scl);
 203         assertTrue(cl2.getParent() == scl);
 204         assertTrue(cl3.getParent() == scl);
 205         assertTrue(cl4.getParent() == scl);
 206         assertTrue(cl2 != cl1);
 207         assertTrue(cl3 != cl1);
 208         assertTrue(cl3 != cl2);
 209         assertTrue(cl4 != cl1);


 216         // Test that the service provider can be located via any of
 217         // the class loaders in the layer
 218         for (Module m : layer.modules()) {
 219             ClassLoader loader = m.getClassLoader();
 220             Iterator<?> iter = ServiceLoader.load(serviceType, loader).iterator();
 221             Object provider = iter.next();
 222             assertTrue(serviceType.isInstance(provider));
 223             assertTrue(provider.getClass().getClassLoader() == cl4);
 224             assertFalse(iter.hasNext());
 225         }
 226 
 227     }
 228 
 229 
 230     /**
 231      * Tests that the class loaders created by defineModulesWithXXX delegate
 232      * to the given parent class loader.
 233      */
 234     public void testDelegationToParent() throws Exception {
 235 
 236         Configuration cf = resolve("m1");
 237 
 238         ClassLoader parent = this.getClass().getClassLoader();
 239         String cn = this.getClass().getName();
 240 
 241         // one loader
 242         Layer layer = Layer.boot().defineModulesWithOneLoader(cf, parent);
 243         testLoad(layer, cn);
 244 
 245          // one loader with boot loader as parent
 246         layer = Layer.boot().defineModulesWithOneLoader(cf, null);
 247         testLoadFail(layer, cn);
 248 
 249         // many loaders
 250         layer = Layer.boot().defineModulesWithManyLoaders(cf, parent);
 251         testLoad(layer, cn);
 252 
 253         // many loader with boot loader as parent
 254         layer = Layer.boot().defineModulesWithManyLoaders(cf, null);
 255         testLoadFail(layer, cn);
 256 
 257     }
 258 
 259 
 260     /**
 261      * Test defineModulesWithXXX when modules that have overlapping packages.
 262      *
 263      * Test scenario:
 264      *   m1 exports p
 265      *   m2 exports p
 266      */
 267     public void testOverlappingPackages() {
 268 
 269         ModuleDescriptor descriptor1
 270             = ModuleDescriptor.newModule("m1").exports("p").build();
 271 
 272         ModuleDescriptor descriptor2
 273             = ModuleDescriptor.newModule("m2").exports("p").build();
 274 
 275         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 276 
 277         Configuration cf = Layer.boot()
 278             .configuration()
 279             .resolve(finder, ModuleFinder.of(), Set.of("m1", "m2"));
 280 
 281         // cannot define both module m1 and m2 to the same class loader
 282         try {
 283             Layer.boot().defineModulesWithOneLoader(cf, null);
 284             assertTrue(false);
 285         } catch (LayerInstantiationException expected) { }
 286 
 287         // should be okay to have one module per class loader
 288         Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, null);
 289         checkLayer(layer, "m1", "m2");
 290 
 291     }
 292 
 293 
 294     /**
 295      * Test Layer defineModulesWithXXX with split delegation.
 296      *
 297      * Test scenario:
 298      *   layer1: m1 exports p, m2 exports p
 299      *   layer2: m3 reads m1, m4 reads m2
 300      */
 301     public void testSplitDelegation() {
 302 
 303         ModuleDescriptor descriptor1
 304             = ModuleDescriptor.newModule("m1").exports("p").build();
 305 
 306         ModuleDescriptor descriptor2
 307             = ModuleDescriptor.newModule("m2").exports("p").build();
 308 
 309         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 310 
 311         Configuration cf1 = Layer.boot()
 312             .configuration()
 313             .resolve(finder1, ModuleFinder.of(), Set.of("m1", "m2"));
 314 
 315         Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
 316         checkLayer(layer1, "m1", "m2");
 317 
 318         ModuleDescriptor descriptor3
 319             = ModuleDescriptor.newModule("m3").requires("m1").build();
 320 
 321         ModuleDescriptor descriptor4
 322             = ModuleDescriptor.newModule("m4").requires("m2").build();
 323 
 324         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 325 
 326         Configuration cf2 = cf1.resolve(finder2, ModuleFinder.of(),
 327                                                 Set.of("m3", "m4"));
 328 
 329         // package p cannot be supplied by two class loaders
 330         try {
 331             layer1.defineModulesWithOneLoader(cf2, null);
 332             assertTrue(false);
 333         } catch (LayerInstantiationException expected) { }
 334 
 335         // no split delegation when modules have their own class loader
 336         Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
 337         checkLayer(layer2, "m3", "m4");
 338 
 339     }
 340 
 341 
 342     /**
 343      * Test Layer defineModulesWithXXX when the modules that override same
 344      * named modules in the parent layer.
 345      *
 346      * Test scenario:
 347      *   layer1: m1, m2, m3 => same loader
 348      *   layer2: m1, m2, m4 => same loader
 349      */
 350     public void testOverriding1() throws Exception {
 351 
 352         Configuration cf1 = resolve("m1");
 353 
 354         Layer layer1 = Layer.boot().defineModulesWithOneLoader(cf1, null);
 355         checkLayer(layer1, "m1", "m2", "m3");
 356 
 357         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
 358         Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
 359                                                 Set.of("m1"));
 360 
 361         Layer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
 362         checkLayer(layer2, "m1", "m2", "m3");
 363         invoke(layer1, "m1", "p.Main");
 364 
 365         ClassLoader loader1 = layer1.findLoader("m1");
 366         ClassLoader loader2 = layer1.findLoader("m2");
 367         ClassLoader loader3 = layer1.findLoader("m3");
 368 
 369         ClassLoader loader4 = layer2.findLoader("m1");
 370         ClassLoader loader5 = layer2.findLoader("m2");
 371         ClassLoader loader6 = layer2.findLoader("m3");
 372 
 373         assertTrue(loader1 == loader2);
 374         assertTrue(loader1 == loader3);
 375 
 376         assertTrue(loader4 == loader5);
 377         assertTrue(loader4 == loader6);
 378         assertTrue(loader4 != loader1);


 381         assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1);
 382         assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1);
 383 
 384         assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);
 385         assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader4);
 386         assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader4);
 387 
 388     }
 389 
 390 
 391     /**
 392      * Test Layer defineModulesWithXXX when the modules that override same
 393      * named modules in the parent layer.
 394      *
 395      * Test scenario:
 396      *   layer1: m1, m2, m3 => loader pool
 397      *   layer2: m1, m2, m3 => loader pool
 398      */
 399     public void testOverriding2() throws Exception {
 400 
 401         Configuration cf1 = resolve("m1");
 402 
 403         Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
 404         checkLayer(layer1, "m1", "m2", "m3");
 405 
 406         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
 407         Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
 408                                                 Set.of("m1"));
 409 
 410         Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
 411         checkLayer(layer2, "m1", "m2", "m3");
 412         invoke(layer1, "m1", "p.Main");
 413 
 414         ClassLoader loader1 = layer1.findLoader("m1");
 415         ClassLoader loader2 = layer1.findLoader("m2");
 416         ClassLoader loader3 = layer1.findLoader("m3");
 417 
 418         ClassLoader loader4 = layer2.findLoader("m1");
 419         ClassLoader loader5 = layer2.findLoader("m2");
 420         ClassLoader loader6 = layer2.findLoader("m3");
 421 
 422         assertTrue(loader4 != loader1);
 423         assertTrue(loader5 != loader2);
 424         assertTrue(loader6 != loader3);
 425 
 426         assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
 427         assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader2);


 475         } catch (ClassNotFoundException expected) { }
 476 
 477         // q.Hello is not visible via loader6
 478         try {
 479             loader6.loadClass("q.Hello");
 480             assertTrue(false);
 481         } catch (ClassNotFoundException expected) { }
 482 
 483     }
 484 
 485 
 486     /**
 487      * Test Layer defineModulesWithXXX when the modules that override same
 488      * named modules in the parent layer.
 489      *
 490      * layer1: m1, m2, m3 => same loader
 491      * layer2: m1, m3 => same loader
 492      */
 493     public void testOverriding3() throws Exception {
 494 
 495         Configuration cf1 = resolve("m1");
 496 
 497         Layer layer1 = Layer.boot().defineModulesWithOneLoader(cf1, null);
 498         checkLayer(layer1, "m1", "m2", "m3");
 499 
 500         ModuleFinder finder = finderFor("m1", "m3");
 501 
 502         Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
 503                                                 Set.of("m1"));
 504 
 505         Layer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
 506         checkLayer(layer2, "m1", "m3");
 507         invoke(layer1, "m1", "p.Main");
 508 
 509         ClassLoader loader1 = layer1.findLoader("m1");
 510         ClassLoader loader2 = layer2.findLoader("m1");
 511 
 512         assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
 513         assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader1);
 514         assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader1);
 515 
 516         assertTrue(loader2.loadClass("p.Main").getClassLoader() == loader2);
 517         assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader1);
 518         assertTrue(loader2.loadClass("w.Hello").getClassLoader() == loader2);
 519 
 520     }
 521 
 522 
 523     /**
 524      * Test Layer defineModulesWithXXX when the modules that override same
 525      * named modules in the parent layer.
 526      *
 527      * layer1: m1, m2, m3 => loader pool
 528      * layer2: m1, m3 => loader pool
 529      */
 530     public void testOverriding4() throws Exception {
 531 
 532         Configuration cf1 = resolve("m1");
 533 
 534         Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
 535         checkLayer(layer1, "m1", "m2", "m3");
 536 
 537         ModuleFinder finder = finderFor("m1", "m3");
 538 
 539         Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
 540                                                 Set.of("m1"));
 541 
 542         Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
 543         checkLayer(layer2, "m1", "m3");
 544         invoke(layer1, "m1", "p.Main");
 545 
 546         ClassLoader loader1 = layer1.findLoader("m1");
 547         ClassLoader loader2 = layer1.findLoader("m2");
 548         ClassLoader loader3 = layer1.findLoader("m3");
 549 
 550         ClassLoader loader4 = layer2.findLoader("m1");
 551         ClassLoader loader5 = layer2.findLoader("m2");
 552         ClassLoader loader6 = layer2.findLoader("m3");
 553 
 554         assertTrue(loader4 != loader1);
 555         assertTrue(loader5 == loader2);  // m2 not overridden
 556         assertTrue(loader6 != loader3);
 557 
 558         assertTrue(loader1.loadClass("p.Main").getClassLoader() == loader1);
 559         assertTrue(loader1.loadClass("q.Hello").getClassLoader() == loader2);
 560         assertTrue(loader1.loadClass("w.Hello").getClassLoader() == loader3);
 561 
 562         assertTrue(loader2.loadClass("q.Hello").getClassLoader() == loader2);
 563 
 564         assertTrue(loader3.loadClass("w.Hello").getClassLoader() == loader3);
 565 
 566         assertTrue(loader4.loadClass("p.Main").getClassLoader() == loader4);
 567         assertTrue(loader4.loadClass("q.Hello").getClassLoader() == loader2);
 568         assertTrue(loader4.loadClass("w.Hello").getClassLoader() == loader6);
 569 
 570         assertTrue(loader6.loadClass("w.Hello").getClassLoader() == loader6);
 571 
 572     }
 573 
 574 
 575     /**
 576      * Basic test of resource loading with a class loader created by
 577      * Layer.defineModulesWithOneLoader.
 578      */
 579     public void testResourcesOneLoader() throws Exception {
 580         Configuration cf = resolve("m1");
 581         ClassLoader scl = ClassLoader.getSystemClassLoader();
 582         Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
 583         ClassLoader loader = layer.findLoader("m1");
 584         testResourceLoading(loader, "p/Main.class");
 585     }
 586 
 587     /**
 588      * Basic test of resource loading with a class loader created by
 589      * Layer.defineModulesWithOneLoader.
 590      */
 591     public void testResourcesManyLoaders() throws Exception {
 592         Configuration cf = resolve("m1");
 593         ClassLoader scl = ClassLoader.getSystemClassLoader();
 594         Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl);
 595         ClassLoader loader = layer.findLoader("m1");
 596         testResourceLoading(loader, "p/Main.class");
 597     }
 598 
 599     /**
 600      * Test that a resource is located by a class loader.
 601      */
 602     private void testResourceLoading(ClassLoader loader, String name)
 603         throws IOException
 604     {
 605         URL url = loader.getResource(name);
 606         assertNotNull(url);
 607 
 608         try (InputStream in = loader.getResourceAsStream(name)) {
 609             assertNotNull(in);
 610         }
 611 
 612         Enumeration<URL> urls = loader.getResources(name);
 613         assertTrue(urls.hasMoreElements());
 614     }
 615 
 616 
 617     // -- supporting methods --
 618 
 619 
 620     /**
 621      * Resolve the given modules, by name, and returns the resulting
 622      * Configuration.
 623      */
 624     private static Configuration resolve(String... roots) {
 625         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
 626         return Layer.boot()
 627             .configuration()
 628             .resolve(finder, ModuleFinder.of(), Set.of(roots));
 629     }
 630 
 631     /**
 632      * Resolve the given modules, by name, and returns the resulting
 633      * Configuration.
 634      */
 635     private static Configuration resolveAndBind(String... roots) {
 636         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
 637         return Layer.boot()
 638             .configuration()
 639             .resolveAndBind(finder, ModuleFinder.of(), Set.of(roots));
 640     }
 641 
 642 
 643     /**
 644      * Invokes the static void main(String[]) method on the given class
 645      * in the given module.
 646      */
 647     private static void invoke(Layer layer, String mn, String mc) throws Exception {
 648         ClassLoader loader = layer.findLoader(mn);
 649         Class<?> c = loader.loadClass(mc);
 650         Method mainMethod = c.getMethod("main", String[].class);
 651         mainMethod.invoke(null, (Object)new String[0]);
 652     }
 653 
 654 
 655     /**
 656      * Checks that the given layer contains exactly the expected modules
 657      * (by name).
 658      */
 659     private void checkLayer(Layer layer, String ... expected) {


< prev index next >