MethodHandles.Lookup and modules
Alan.Bateman at oracle.com
Fri Dec 11 08:14:53 UTC 2015
On 10/12/2015 19:20, stanislav lukyanov wrote:
> This is connected to the second part of the question (2).
> If access to readable modules were allowed only if MODULE bit is set,
> transition from A to B would be safe, since only one transition could
> be made (actually, same as it is now, but not from unnamed module only).
> BTW, 'requires public' chain could be traversed safely even with
> PUBLIC mode:
> A.in(B).in(C).in(D) would have access to D's exported members and D's
> 'requires public' - same as A.
The MODULE bit is for access to "module private" members, it has to be
dropped when hopping to a lookup class in another module.
In the A.in(B).in(C).in(D) example then each hop will preserve or
degrade access. The modules for A, B, C and D may read very different
sets of modules. The lookup class and mode bits aren't enough to
represent this intersection so this is why access degrades quickly (or
immediately) to 0. We have of course looked at preserving a snapshot of
the intersection but this complicates things greatly and would diverge
from bytecode behavior.
> Method handles API is really "conservative" in regard of access
> control and I believe it supposed to be nearly as safe
> as plain method calls (since Lookup basically reproduces
> bytecode-level checks).
> I think it shouldn't allow something just because reflection API is
> able to do the trick anyway.
> After all, it doesn't go easy with method access checks despite we
> have Method.setAccessible
It might be a surprise but changing the readability graph at run-time
via addReads changes the VM and bytecode behavior, it's not tied to core
reflection. So yes, as things currently stand, then addReads will
increase readability and therefore the types that can be accessed. Using
addReads cannot be used to break encapsulation of course.
> One more thing about javadoc.
> publicLookup() spec says
> - "As a matter of pure convention, the lookup class of this lookup
> object will be in an unnamed module."
> It's not about pure convention anymore - it really matters now where
> publicLookup() resides.
You're right. This wording was mostly correct in early prototyping but
isn't right now. It needs to be specified to be in an unnamed module, it
can't be in a named module (at least not unless we get to the point
where a named module can read all other modules).
More information about the jigsaw-dev