mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8010319: Implementation of JEP 181: Nest-Based Access Control
Co-authored-by: Alex Buckley <alex.buckley@oracle.com> Co-authored-by: Maurizio Mimadamore <maurizio.mimadamore@oracle.com> Co-authored-by: Mandy Chung <mandy.chung@oracle.com> Co-authored-by: Tobias Hartmann <tobias.hartmann@oracle.com> Co-authored-by: Vlaidmir Ivanov <vladimir.x.ivanov@oracle.com> Co-authored-by: Karen Kinnear <karen.kinnear@oracle.com> Co-authored-by: Vladimir Kozlov <vladimir.kozlov@oracle.com> Co-authored-by: John Rose <john.r.rose@oracle.com> Co-authored-by: Daniel Smith <daniel.smith@oracle.com> Co-authored-by: Serguei Spitsyn <serguei.spitsyn@oracle.com> Co-authored-by: Kumar Srinivasan <kumardotsrinivasan@gmail.com> Co-authored-by: Boris Ulasevich <boris.ulasevich@bell-sw.com> Reviewed-by: alanb, psandoz, mchung, coleenp, acorn, mcimadamore, forax, jlahoda, sspitsyn, abuckley
This commit is contained in:
parent
6e0bd36f42
commit
95bf19563b
259 changed files with 21354 additions and 890 deletions
|
@ -82,9 +82,9 @@ import sun.reflect.annotation.*;
|
|||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* Instances of the class {@code Class} represent classes and
|
||||
* interfaces in a running Java application. An enum is a kind of
|
||||
* class and an annotation is a kind of interface. Every array also
|
||||
* Instances of the class {@code Class} represent classes and interfaces
|
||||
* in a running Java application. An enum type is a kind of class and an
|
||||
* annotation type is a kind of interface. Every array also
|
||||
* belongs to a class that is reflected as a {@code Class} object
|
||||
* that is shared by all arrays with the same element type and number
|
||||
* of dimensions. The primitive Java types ({@code boolean},
|
||||
|
@ -93,10 +93,34 @@ import sun.reflect.misc.ReflectUtil;
|
|||
* {@code double}), and the keyword {@code void} are also
|
||||
* represented as {@code Class} objects.
|
||||
*
|
||||
* <p> {@code Class} has no public constructor. Instead {@code Class}
|
||||
* objects are constructed automatically by the Java Virtual Machine as classes
|
||||
* are loaded and by calls to the {@code defineClass} method in the class
|
||||
* loader.
|
||||
* <p> {@code Class} has no public constructor. Instead a {@code Class}
|
||||
* object is constructed automatically by the Java Virtual Machine
|
||||
* when a class loader invokes one of the
|
||||
* {@link ClassLoader#defineClass(String,byte[], int,int) defineClass} methods
|
||||
* and passes the bytes of a {@code class} file.
|
||||
*
|
||||
* <p> The methods of class {@code Class} expose many characteristics of a
|
||||
* class or interface. Most characteristics are derived from the {@code class}
|
||||
* file that the class loader passed to the Java Virtual Machine. A few
|
||||
* characteristics are determined by the class loading environment at run time,
|
||||
* such as the module returned by {@link #getModule() getModule()}.
|
||||
*
|
||||
* <p> Some methods of class {@code Class} expose whether the declaration of
|
||||
* a class or interface in Java source code was <em>enclosed</em> within
|
||||
* another declaration. Other methods describe how a class or interface
|
||||
* is situated in a <em>nest</em>. A <a id="nest">nest</a> is a set of
|
||||
* classes and interfaces, in the same run-time package, that
|
||||
* allow mutual access to their {@code private} members.
|
||||
* The classes and interfaces are known as <em>nestmates</em>.
|
||||
* One nestmate acts as the
|
||||
* <em>nest host</em>, and enumerates the other nestmates which
|
||||
* belong to the nest; each of them in turn records it as the nest host.
|
||||
* The classes and interfaces which belong to a nest, including its host, are
|
||||
* determined when
|
||||
* {@code class} files are generated, for example, a Java compiler
|
||||
* will typically record a top-level class as the host of a nest where the
|
||||
* other members are the classes and interfaces whose declarations are
|
||||
* enclosed within the top-level class declaration.
|
||||
*
|
||||
* <p> The following example uses a {@code Class} object to print the
|
||||
* class name of an object:
|
||||
|
@ -3848,4 +3872,161 @@ public final class Class<T> implements java.io.Serializable,
|
|||
public AnnotatedType[] getAnnotatedInterfaces() {
|
||||
return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
|
||||
}
|
||||
|
||||
private native Class<?> getNestHost0();
|
||||
|
||||
/**
|
||||
* Returns the nest host of the <a href=#nest>nest</a> to which the class
|
||||
* or interface represented by this {@code Class} object belongs.
|
||||
* Every class and interface is a member of exactly one nest.
|
||||
* A class or interface that is not recorded as belonging to a nest
|
||||
* belongs to the nest consisting only of itself, and is the nest
|
||||
* host.
|
||||
*
|
||||
* <p>Each of the {@code Class} objects representing array types,
|
||||
* primitive types, and {@code void} returns {@code this} to indicate
|
||||
* that the represented entity belongs to the nest consisting only of
|
||||
* itself, and is the nest host.
|
||||
*
|
||||
* <p>If there is a {@linkplain LinkageError linkage error} accessing
|
||||
* the nest host, or if this class or interface is not enumerated as
|
||||
* a member of the nest by the nest host, then it is considered to belong
|
||||
* to its own nest and {@code this} is returned as the host.
|
||||
*
|
||||
* @apiNote A {@code class} file of version 55.0 or greater may record the
|
||||
* host of the nest to which it belongs by using the {@code NestHost}
|
||||
* attribute (JVMS 4.7.28). Alternatively, a {@code class} file of
|
||||
* version 55.0 or greater may act as a nest host by enumerating the nest's
|
||||
* other members with the
|
||||
* {@code NestMembers} attribute (JVMS 4.7.29).
|
||||
* A {@code class} file of version 54.0 or lower does not use these
|
||||
* attributes.
|
||||
*
|
||||
* @return the nest host of this class or interface
|
||||
*
|
||||
* @throws SecurityException
|
||||
* If the returned class is not the current class, and
|
||||
* if a security manager, <i>s</i>, is present and the caller's
|
||||
* class loader is not the same as or an ancestor of the class
|
||||
* loader for the returned class and invocation of {@link
|
||||
* SecurityManager#checkPackageAccess s.checkPackageAccess()}
|
||||
* denies access to the package of the returned class
|
||||
* @since 11
|
||||
* @jvms 4.7.28 and 4.7.29 NestHost and NestMembers attributes
|
||||
* @jvms 5.4.4 Access Control
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Class<?> getNestHost() {
|
||||
if (isPrimitive() || isArray()) {
|
||||
return this;
|
||||
}
|
||||
Class<?> host;
|
||||
try {
|
||||
host = getNestHost0();
|
||||
} catch (LinkageError e) {
|
||||
// if we couldn't load our nest-host then we
|
||||
// act as-if we have no nest-host attribute
|
||||
return this;
|
||||
}
|
||||
// if null then nest membership validation failed, so we
|
||||
// act as-if we have no nest-host attribute
|
||||
if (host == null || host == this) {
|
||||
return this;
|
||||
}
|
||||
// returning a different class requires a security check
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
checkPackageAccess(sm,
|
||||
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the given {@code Class} is a nestmate of the
|
||||
* class or interface represented by this {@code Class} object.
|
||||
* Two classes or interfaces are nestmates
|
||||
* if they have the same {@linkplain #getNestHost() nest host}.
|
||||
*
|
||||
* @param c the class to check
|
||||
* @return {@code true} if this class and {@code c} are members of
|
||||
* the same nest; and {@code false} otherwise.
|
||||
*
|
||||
* @since 11
|
||||
*/
|
||||
public boolean isNestmateOf(Class<?> c) {
|
||||
if (this == c) {
|
||||
return true;
|
||||
}
|
||||
if (isPrimitive() || isArray() ||
|
||||
c.isPrimitive() || c.isArray()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return getNestHost0() == c.getNestHost0();
|
||||
} catch (LinkageError e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private native Class<?>[] getNestMembers0();
|
||||
|
||||
/**
|
||||
* Returns an array containing {@code Class} objects representing all the
|
||||
* classes and interfaces that are members of the nest to which the class
|
||||
* or interface represented by this {@code Class} object belongs.
|
||||
* The {@linkplain #getNestHost() nest host} of that nest is the zeroth
|
||||
* element of the array. Subsequent elements represent any classes or
|
||||
* interfaces that are recorded by the nest host as being members of
|
||||
* the nest; the order of such elements is unspecified. Duplicates are
|
||||
* permitted.
|
||||
* If the nest host of that nest does not enumerate any members, then the
|
||||
* array has a single element containing {@code this}.
|
||||
*
|
||||
* <p>Each of the {@code Class} objects representing array types,
|
||||
* primitive types, and {@code void} returns an array containing only
|
||||
* {@code this}.
|
||||
*
|
||||
* <p>This method validates that, for each class or interface which is
|
||||
* recorded as a member of the nest by the nest host, that class or
|
||||
* interface records itself as a member of that same nest. Any exceptions
|
||||
* that occur during this validation are rethrown by this method.
|
||||
*
|
||||
* @return an array of all classes and interfaces in the same nest as
|
||||
* this class
|
||||
*
|
||||
* @throws LinkageError
|
||||
* If there is any problem loading or validating a nest member or
|
||||
* its nest host
|
||||
* @throws SecurityException
|
||||
* If any returned class is not the current class, and
|
||||
* if a security manager, <i>s</i>, is present and the caller's
|
||||
* class loader is not the same as or an ancestor of the class
|
||||
* loader for that returned class and invocation of {@link
|
||||
* SecurityManager#checkPackageAccess s.checkPackageAccess()}
|
||||
* denies access to the package of that returned class
|
||||
*
|
||||
* @since 11
|
||||
* @see #getNestHost()
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Class<?>[] getNestMembers() {
|
||||
if (isPrimitive() || isArray()) {
|
||||
return new Class<?>[] { this };
|
||||
}
|
||||
Class<?>[] members = getNestMembers0();
|
||||
// Can't actually enable this due to bootstrapping issues
|
||||
// assert(members.length != 1 || members[0] == this); // expected invariant from VM
|
||||
|
||||
if (members.length > 1) {
|
||||
// If we return anything other than the current class we need
|
||||
// a security check
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
checkPackageAccess(sm,
|
||||
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue