1 /* 2 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @summary Verify the defining class loader of each module never delegates 27 * to its child class loader. 28 * @run testng/othervm --add-modules=ALL-SYSTEM VerifyModuleDelegation 29 */ 30 31 import java.lang.module.ModuleDescriptor; 32 import java.lang.module.ModuleFinder; 33 import java.lang.module.ModuleReference; 34 import java.lang.reflect.Layer; 35 import java.lang.reflect.Module; 36 import java.util.Set; 37 import static java.util.stream.Collectors.toSet; 38 39 import static java.lang.module.ModuleDescriptor.Requires.Modifier.*; 40 41 import org.testng.annotations.*; 42 43 import static org.testng.Assert.*; 44 45 public class VerifyModuleDelegation { 46 private static final String JAVA_BASE = "java.base"; 47 48 private static final ModuleDescriptor BASE 49 = ModuleDescriptor.module(JAVA_BASE).build(); 50 51 private static final Set<ModuleDescriptor> MREFS 52 = Layer.boot().modules().stream().map(Module::getDescriptor) 53 .collect(toSet()); 54 55 private void check(ModuleDescriptor md, ModuleDescriptor ref) { 56 assertTrue(md.requires().size() == ref.requires().size()); 57 assertTrue(md.requires().containsAll(ref.requires())); 58 } 59 60 @Test 61 public void checkJavaBase() { 62 ModuleDescriptor md = 63 MREFS.stream() 64 .filter(d -> d.name().equals(JAVA_BASE)) 65 .findFirst().orElseThrow(Error::new); 66 67 check(md, BASE); 68 } 69 70 @Test 71 public void checkLoaderDelegation() { 72 Layer boot = Layer.boot(); 73 MREFS.stream() 74 .forEach(md -> md.requires().stream().forEach(req -> 75 { 76 // check if M requires D and D's loader must be either the 77 // same or an ancestor of M's loader 78 ClassLoader loader1 = boot.findLoader(md.name()); 79 ClassLoader loader2 = boot.findLoader(req.name()); 80 if (loader1 != loader2 && !isAncestor(loader2, loader1)) { 81 throw new Error(md.name() + " can't delegate to " + 82 "find classes from " + req.name()); 83 } 84 })); 85 } 86 87 // Returns true if p is an ancestor of cl i.e. class loader 'p' can 88 // be found in the cl's delegation chain 89 private static boolean isAncestor(ClassLoader p, ClassLoader cl) { 90 if (p != null && cl == null) { 91 return false; 92 } 93 ClassLoader acl = cl; 94 do { 95 acl = acl.getParent(); 96 if (p == acl) { 97 return true; 98 } 99 } while (acl != null); 100 return false; 101 } 102 }