|
Java example source code file (AccessControlTest.java)
The AccessControlTest.java Java example source code/* * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* @test * @summary test access checking by java.lang.invoke.MethodHandles.Lookup * @library ../../../.. * @build test.java.lang.invoke.AccessControlTest * @build test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote * @run testng/othervm test.java.lang.invoke.AccessControlTest */ package test.java.lang.invoke; import java.lang.invoke.*; import java.lang.reflect.*; import java.util.*; import org.testng.*; import org.testng.annotations.*; import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodHandles.Lookup.*; import static java.lang.invoke.MethodType.*; import static org.testng.Assert.*; import test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote; /** * Test many combinations of Lookup access and cross-class lookupStatic. * @author jrose */ public class AccessControlTest { static final Class<?> THIS_CLASS = AccessControlTest.class; // How much output? static int verbosity = 0; static { String vstr = System.getProperty(THIS_CLASS.getSimpleName()+".verbosity"); if (vstr == null) vstr = System.getProperty(THIS_CLASS.getName()+".verbosity"); if (vstr != null) verbosity = Integer.parseInt(vstr); } private class LookupCase implements Comparable<LookupCase> { final Lookup lookup; final Class<?> lookupClass; final int lookupModes; public LookupCase(Lookup lookup) { this.lookup = lookup; this.lookupClass = lookup.lookupClass(); this.lookupModes = lookup.lookupModes(); assert(lookupString().equals(lookup.toString())); numberOf(lookupClass().getClassLoader()); // assign CL# } public LookupCase(Class<?> lookupClass, int lookupModes) { this.lookup = null; this.lookupClass = lookupClass; this.lookupModes = lookupModes; numberOf(lookupClass().getClassLoader()); // assign CL# } public final Class<?> lookupClass() { return lookupClass; } public final int lookupModes() { return lookupModes; } public Lookup lookup() { lookup.getClass(); return lookup; } @Override public int compareTo(LookupCase that) { Class<?> c1 = this.lookupClass(); Class<?> c2 = that.lookupClass(); if (c1 != c2) { int cmp = c1.getName().compareTo(c2.getName()); if (cmp != 0) return cmp; cmp = numberOf(c1.getClassLoader()) - numberOf(c2.getClassLoader()); assert(cmp != 0); return cmp; } return -(this.lookupModes() - that.lookupModes()); } @Override public boolean equals(Object that) { return (that instanceof LookupCase && equals((LookupCase)that)); } public boolean equals(LookupCase that) { return (this.lookupClass() == that.lookupClass() && this.lookupModes() == that.lookupModes()); } @Override public int hashCode() { return lookupClass().hashCode() + (lookupModes() * 31); } /** Simulate all assertions in the spec. for Lookup.toString. */ private String lookupString() { String name = lookupClass.getName(); String suffix = ""; if (lookupModes == 0) suffix = "/noaccess"; else if (lookupModes == PUBLIC) suffix = "/public"; else if (lookupModes == (PUBLIC|PACKAGE)) suffix = "/package"; else if (lookupModes == (PUBLIC|PACKAGE|PRIVATE)) suffix = "/private"; else if (lookupModes == (PUBLIC|PACKAGE|PRIVATE|PROTECTED)) suffix = ""; else suffix = "/#"+Integer.toHexString(lookupModes); return name+suffix; } /** Simulate all assertions from the spec. for Lookup.in: * <hr> * Creates a lookup on the specified new lookup class. * [A1] The resulting object will report the specified * class as its own {@link #lookupClass lookupClass}. * <p> * [A2] However, the resulting {@code Lookup} object is guaranteed * to have no more access capabilities than the original. * In particular, access capabilities can be lost as follows:<ul> * <li>[A3] If the new lookup class differs from the old one, * protected members will not be accessible by virtue of inheritance. * (Protected members may continue to be accessible because of package sharing.) * <li>[A4] If the new lookup class is in a different package * than the old one, protected and default (package) members will not be accessible. * <li>[A5] If the new lookup class is not within the same package member * as the old one, private members will not be accessible. * <li>[A6] If the new lookup class is not accessible to the old lookup class, * using the original access modes, * then no members, not even public members, will be accessible. * [A7] (In all other cases, public members will continue to be accessible.) * </ul> * Other than the above cases, the new lookup will have the same * access capabilities as the original. [A8] * <hr> */ public LookupCase in(Class<?> c2) { Class<?> c1 = lookupClass(); int m1 = lookupModes(); int changed = 0; boolean samePackage = (c1.getClassLoader() == c2.getClassLoader() && packagePrefix(c1).equals(packagePrefix(c2))); boolean sameTopLevel = (topLevelClass(c1) == topLevelClass(c2)); boolean sameClass = (c1 == c2); assert(samePackage || !sameTopLevel); assert(sameTopLevel || !sameClass); boolean accessible = sameClass; // [A6] if ((m1 & PACKAGE) != 0) accessible |= samePackage; if ((m1 & PUBLIC ) != 0) accessible |= (c2.getModifiers() & PUBLIC) != 0; if (!accessible) { // Different package and no access to c2; lose all access. changed |= (PUBLIC|PACKAGE|PRIVATE|PROTECTED); // [A6] } if (!samePackage) { // Different package; lose PACKAGE and lower access. changed |= (PACKAGE|PRIVATE|PROTECTED); // [A4] } if (!sameTopLevel) { // Different top-level class. Lose PRIVATE and lower access. changed |= (PRIVATE|PROTECTED); // [A5] } if (!sameClass) { changed |= (PROTECTED); // [A3] } else { assert(changed == 0); // [A8] (no deprivation if same class) } if (accessible) assert((changed & PUBLIC) == 0); // [A7] int m2 = m1 & ~changed; LookupCase l2 = new LookupCase(c2, m2); assert(l2.lookupClass() == c2); // [A1] assert((m1 | m2) == m1); // [A2] (no elevation of access) return l2; } @Override public String toString() { String s = lookupClass().getSimpleName(); String lstr = lookupString(); int sl = lstr.indexOf('/'); if (sl >= 0) s += lstr.substring(sl); ClassLoader cld = lookupClass().getClassLoader(); if (cld != THIS_LOADER) s += "/loader#"+numberOf(cld); return s; } /** Predict the success or failure of accessing this method. */ public boolean willAccess(Method m) { Class<?> c1 = lookupClass(); Class<?> c2 = m.getDeclaringClass(); LookupCase lc = this.in(c2); int m1 = lc.lookupModes(); int m2 = fixMods(m.getModifiers()); // privacy is strictly enforced on lookups if (c1 != c2) m1 &= ~PRIVATE; // protected access is sometimes allowed if ((m2 & PROTECTED) != 0) { int prev = m2; m2 |= PACKAGE; // it acts like a package method also if ((lookupModes() & PROTECTED) != 0 && c2.isAssignableFrom(c1)) m2 |= PUBLIC; // from a subclass, it acts like a public method also } if (verbosity >= 2) System.out.println(this+" willAccess "+lc+" m1="+m1+" m2="+m2+" => "+((m2 & m1) != 0)); return (m2 & m1) != 0; } } private static Class<?> topLevelClass(Class cls) { Class<?> c = cls; for (Class<?> ec; (ec = c.getEnclosingClass()) != null; ) c = ec; assert(c.getEnclosingClass() == null); assert(c == cls || cls.getEnclosingClass() != null); return c; } private static String packagePrefix(Class<?> c) { while (c.isArray()) c = c.getComponentType(); String s = c.getName(); assert(s.indexOf('/') < 0); return s.substring(0, s.lastIndexOf('.')+1); } private final TreeSet<LookupCase> CASES = new TreeSet<>(); private final TreeMap<LookupCase,TreeSet Other Java examples (source code examples)Here is a short list of links related to this Java AccessControlTest.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.