JEP 181: Nest-Based Access Control
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](http://openjdk.java.net/jeps/181) for details.
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 <code>java.lang.Class</code> 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.
<code>MethodHandle.Lookup.findVirtual</code> no longer throws <code>IllegaAccessError</code> if applied to a private interface method.
The specifications for class redefinition and retransformation, in the JVM TI and JDWP specifications, along with the <code>java.lang.instrument</code> and <code>com.sun.jdi</code> API's are enhanced to disallow any modification of the <code>NestHost</code> or <code>NestMembers</code> attributes. For JDWP and JDI we also clarify the notion of restricted redefinitions.
Proposed changes to JLS and JVMS are attached. Full updated specifications and specdiffs are available as follows:
- JVM TI: