Loading... (original) (raw)

Summary

JEP 181: Nest-Based Access Control

Problem

Closely-related classes sometimes need to share access private members. The Java language supports this, allowing access to all private members nested within the same top-level class. The JVM does not, requiring less-secure compiler workarounds and ad hoc solutions like Unsafe.defineAnonymousClass(). See JEP 181 for details.

Solution

A nest is a subset of classes in a package. Every class belongs to one nest (by default, a singleton nest containing only itself). Two classes belonging to the same nest are nestmates.

Two new JVM attributes are introduced: NestHost and NestMembers. The first points to a class's nest host class (for example, the top-level class containing it); if there is no NestHost attribute, the class is its own nest host. The second, appearing in the nest host, enumerates the classes that are authorized to claim membership in a nest.

The JVM access control rules are modified to allow access to private members from all of a class's nestmates. These checks occur on-demand: the nest host is not loaded (in order to consult its NestMembers attribute) until needed to grant access to an otherwise-inaccessible member.

The source language compiler is responsible for deciding which classes and interfaces are nestmates. For example, the javac compiler places a top-level class or interface into a nest with all of its direct, and indirect, nested classes and interfaces. The top-level enclosing class or interface is designated as the nest host. The JVM itself simply defines an access control context based on these attributes with no regard to any language-level scoping or nesting characteristics. In the future, nestmates need not directly correspond to source language constructs.

Traditionally, invokespecial is used to invoke private members, though invokevirtual also has this capability. Rather than perturb the complex rules about supertypes enforced by invokespecial, we require invocations of private methods in a different class to use invokevirtual. The invokeinterface instruction is enhanced to support invocation of private interface methods. In the process, we unify different method selection algorithms used by the JVM.

The reflection API of java.lang.Class is enhanced to support nest-related queries.

(The javac compiler is also updated to make use of nests, but this change does not impact any specifications. Some JLS changes are present to align the JLS description of runtime behavior with JVMS.)

Minor clarifications and adjustments are needed in the core reflection and MethodHandle API's. These are mainly non-normative/descriptive text changes.

MethodHandle.Lookup.findVirtual no longer throws IllegaAccessError if applied to a private interface method.

The specifications for class redefinition and retransformation, in the JVM TI and JDWP specifications, along with the java.lang.instrument and com.sun.jdi API's are enhanced to disallow any modification of the NestHost or NestMembers attributes. For JDWP and JDI we also clarify the notion of restricted redefinitions.

Specification

Proposed changes to JLS and JVMS are attached. Full updated specifications and specdiffs are available as follows: