diff -r d0f7a3e441c4 -r 88ab34b6da6d jdk/src/share/classes/sun/invoke/util/VerifyAccess.java --- a/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java Tue May 17 19:48:19 2011 -0700 +++ b/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java Thu May 26 17:37:36 2011 -0700 @@ -154,9 +154,10 @@ * @return whether they are in the same package */ public static boolean isSamePackage(Class class1, Class class2) { + assert(!class1.isArray() && !class2.isArray()); if (class1 == class2) return true; - if (!loadersAreRelated(class1.getClassLoader(), class2.getClassLoader())) + if (!loadersAreRelated(class1.getClassLoader(), class2.getClassLoader(), false)) return false; String name1 = class1.getName(), name2 = class2.getName(); int dot = name1.lastIndexOf('.'); @@ -169,6 +170,16 @@ return true; } + /** Return the package name for this class. + */ + public static String getPackageName(Class cls) { + assert(!cls.isArray()); + String name = cls.getName(); + int dot = name.lastIndexOf('.'); + if (dot < 0) return ""; + return name.substring(0, dot); + } + /** * Test if two classes are defined as part of the same package member (top-level class). * If this is true, they can share private access with each other. @@ -193,18 +204,33 @@ return pkgmem; } - private static boolean loadersAreRelated(ClassLoader loader1, ClassLoader loader2) { - if (loader1 == loader2 || loader1 == null || loader2 == null) { + private static boolean loadersAreRelated(ClassLoader loader1, ClassLoader loader2, + boolean loader1MustBeParent) { + if (loader1 == loader2 || loader1 == null + || (loader2 == null && !loader1MustBeParent)) { return true; } - for (ClassLoader scan1 = loader1; - scan1 != null; scan1 = scan1.getParent()) { - if (scan1 == loader2) return true; - } for (ClassLoader scan2 = loader2; scan2 != null; scan2 = scan2.getParent()) { if (scan2 == loader1) return true; } + if (loader1MustBeParent) return false; + // see if loader2 is a parent of loader1: + for (ClassLoader scan1 = loader1; + scan1 != null; scan1 = scan1.getParent()) { + if (scan1 == loader2) return true; + } return false; } + + /** + * Is the class loader of parentClass identical to, or an ancestor of, + * the class loader of childClass? + * @param parentClass + * @param childClass + * @return whether parentClass precedes or equals childClass in class loader order + */ + public static boolean classLoaderIsAncestor(Class parentClass, Class childClass) { + return loadersAreRelated(parentClass.getClassLoader(), childClass.getClassLoader(), true); + } }