On Sep 29, 2016, at 2:29 AM, Remi Forax <fo...@univ-mlv.fr> wrote:
> 
> This bug only talk about the callee side, i.e. accessing to a non accessible 
> class by a framework.
> The other part, the caller side, is to have a way to emit a call that send 
> the caller lookup to a framework,
> the easy way to do that is to have javac to emit an invokedynamic instead of 
> an invokeinterface/invokevirtual
> after having verified that everything is typechecked.

FTR, I added a comment to the bug that expands on this theme.

https://bugs.openjdk.java.net/browse/JDK-8162494?focusedCommentId=14010672 
<https://bugs.openjdk.java.net/browse/JDK-8162494?focusedCommentId=14010672>

— John

P.S.  CC-ed here:

Remi Forax notes that this proposal is about gaining access to classes.
http://mail.openjdk.java.net/pipermail/jigsaw-dev/2016-September/009518.html

Once somebody (the class itself, a neighboring class, a module, a layer, the 
Unsafe API) grants you a Lookup object, you can call any class feature the 
lookup can access, by using a method handle.

The most general Lookup object, for a given class, can always be created by a 
method in the class's bytecodes that looks like this:

class C {
   private C() { } protected void m() { } int f; // etc., etc.
   public MethodHandles.Lookup grantAccess()  { return MethodHandles.lookup(); }
}

In this example, the "grantAccess" method gives the whole world (or at least 
the module) full access to all class members, up to and including privates.

The essence of the present proposal is to introduce mechanisms for creating 
Lookup objects which (a ) can be as powerful (on class C) as that returned by 
the "grantAccess" method above, and (b ) do not require any changes to the 
bytecodes of the class itself.

The difficult part of the proposal is designing the alternative Lookup factory 
in such a way that it doesn't just "give away the store" (as presumably the 
Unsafe version would).  The Lookup object should be (c ) handed out by a 
trusted delegate of C (such as its module layer), and (d ) only handed to 
callers who have been vetted in some way (such as by a SecurityManager check, 
as by setAccessible).  Finally, the Lookup object must be (e ) right-sized, so 
that it gives only access (say) to public methods, or package-private methods, 
according to the needs of the caller and the rules of the factory.

Another possible framework-like operation that Remi brings up is creating 
simulations of calls from managed framework code to other frameworks.  In some 
cases, this can also be done with the Lookup API.  If the callee is 
caller-sensitive (like Class.forName), the Lookup API handles it specially, 
embedding the Lookup's target class into the method handle it returns (for that 
callee) in such a way that when the method handle the caller-sensitive method 
observes the Lookup's target class, not the current invoker of the method 
handle.  Only the immediate caller is "edited" in this way; a full stack walk 
will see the specially-embedded caller and all of frames of the current 
invocation.

Another use case for frameworks is enumerating and examining (e.g., annotations 
of) reflected class members, instead of just invoking them.  The Lookup API is 
intended to help with this also.  The Lookup.revealDirect method can translate 
a previously accessed method handle into a Core Reflection object that 
describes the same underlying class member.  The Lookup API (as of 9) also has 
the ability to resolve class names with respect to the Lookup's target class.  
Finally (as noted above) calls to caller-sensitive Core Reflection API points 
can be made to appear originating from a target class by looking up those API 
points via a full-power Lookup on the target class, instead of calling from 
normal bytecodes.

Personally, I would like to encourage people interested in structured access 
elevation, by bona fide frameworks, to propose securable mechanisms for handing 
out Lookup objects, or similar restrictable capability objects.

Reply via email to