1 /* 2 * Copyright (c) 2013, 2015, 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. Also sanity check java.compact2 28 * requires. 29 * @run testng/othervm -Djdk.launcher.addmods=ALL-SYSTEM VerifyModuleDelegation 30 */ 31 32 import java.lang.module.ModuleDescriptor; 33 import java.lang.module.ModuleFinder; 34 import java.lang.module.ModuleReference; 35 import java.lang.reflect.Layer; 36 import java.util.Set; 37 38 import static java.lang.module.ModuleDescriptor.Requires.Modifier.*; 39 40 import org.testng.annotations.*; 41 42 import static org.testng.Assert.*; 43 44 public class VerifyModuleDelegation { 45 private static final String JAVA_BASE = "java.base"; 46 private static final String JAVA_COMPACT1 = "java.compact1"; 47 private static final String JAVA_COMPACT2 = "java.compact2"; 48 49 private static final ModuleDescriptor BASE 50 = new ModuleDescriptor.Builder(JAVA_BASE).build(); 51 52 private static final ModuleDescriptor COMPACT2 53 = new ModuleDescriptor.Builder(JAVA_COMPACT2) 54 .requires(MANDATED, JAVA_BASE) 55 .requires(PUBLIC, JAVA_COMPACT1) 56 .requires(PUBLIC, "java.rmi") 57 .requires(PUBLIC, "java.sql") 58 .requires(PUBLIC, "java.xml") 59 .build(); 60 61 private static final Set<ModuleReference> MREFS 62 = ModuleFinder.ofSystem().findAll(); 63 64 private void check(ModuleDescriptor md, ModuleDescriptor ref) { 65 assertTrue(md.requires().size() == ref.requires().size()); 66 assertTrue(md.requires().containsAll(ref.requires())); 67 } 68 69 @Test 70 public void checkJavaBase() { 71 ModuleDescriptor md = 72 MREFS.stream().map(ModuleReference::descriptor) 73 .filter(d -> d.name().equals(JAVA_BASE)) 74 .findFirst().orElseThrow(Error::new); 75 76 check(md, BASE); 77 } 78 @Test 79 public void checkCompact2() { 80 ModuleDescriptor md = 81 MREFS.stream().map(ModuleReference::descriptor) 82 .filter(d -> d.name().equals(JAVA_COMPACT2)) 83 .findFirst().orElseThrow(Error::new); 84 check(md, COMPACT2); 85 } 86 87 @Test 88 public void checkLoaderDelegation() { 89 Layer boot = Layer.boot(); 90 MREFS.stream().map(ModuleReference::descriptor) 91 .forEach(md -> md.requires().stream().forEach(req -> 92 { 93 // check if M requires D and D's loader must be either the 94 // same or an ancestor of M's loader 95 ClassLoader loader1 = boot.findLoader(md.name()); 96 ClassLoader loader2 = boot.findLoader(req.name()); 97 if (loader1 != loader2 && !isAncestor(loader2, loader1)) { 98 throw new Error(md.name() + " can't delegate to " + 99 "find classes from " + req.name()); 100 } 101 })); 102 } 103 104 // Returns true if p is an ancestor of cl i.e. class loader 'p' can 105 // be found in the cl's delegation chain 106 private static boolean isAncestor(ClassLoader p, ClassLoader cl) { 107 if (p != null && cl == null) { 108 return false; 109 } 110 ClassLoader acl = cl; 111 do { 112 acl = acl.getParent(); 113 if (p == acl) { 114 return true; 115 } 116 } while (acl != null); 117 return false; 118 } 119 }