Hi John,

On 12/11/2015 12:38 PM, John Rose wrote:
That's fine.  There are two main use cases for Lookup.in,
neither of which require the tracking of long chains of L.in(A/B/C…).

A. Agent with full-power lookup wants to invoke another agent with the lookup,
but wants to limit access, because he doesn't fully trust the other agent.
He does a single L.in(A) to a remote-enough type A, creating a non-full-power 
lookup.
(Note:  Picking A is sometimes non-trivial.  This might be an API flaw.)

B. Agent with full-power lookup wants to get access to private nestmate in A.
He does a single L.in(A) where LC and A are in the same package member.
This works around differences between access checks at JVM and JLS levels,
just as the package-private accessor methods from javac do.  (Yuck!)

Focusing on case A, please consider the following design:

- PUBLIC lookup mode means:

Any 'public' type of any package exported unconditionally by the package's module.

- QUALIFIED lookup mode means:

Any 'public' type of any package exported in qualified fashion by the package's module to the lookup class's module.

- MODULE lookup mode means:

  Any 'public' type of any package in the lookup class's module.

(Sidebar: QUALIFIED is split from MODULE primarily to be explicit about access rights and secondarily to support more precise slicing of access rights in a future MethodHandles.Lookup API. Example: give me a lookup object to access the types in this module that offer a contract, i.e. are declared 'public' without regard to exported-ness. Example: give me a lookup object to access the types outside this module which are exported to it by its friends.)

- Start with an arbitrary class in an arbitrary module calling MethodHandles.Lookup.lookup() to get a "full power" lookup object L. L's lookup modes are PUBLIC + QUALIFIED + MODULE + PROTECTED + PACKAGE + PRIVATE.

- The arbitrary class obtains a Class object representing class A, then calls L.in(A):

-- If A is in a different module than L's lookup class, then the resulting lookup object has lookup mode PUBLIC.

-- If A is in the same module as L's lookup class, but a different package, then the resulting lookup object has lookup mode PUBLIC + QUALIFIED + MODULE + PROTECTED. (#include some stuff about actually accessing protected members outside A's package.)

-- If A is in the same module as L's lookup class, and in the same package, but A is a different class than L's lookup class, then the resulting lookup object has lookup modes PUBLIC + QUALIFIED + MODULE + PROTECTED + PACKAGE.

-- If A is the same class as L's lookup class, then the resulting lookup object has lookup modes PUBLIC + MODULE + PROTECTED + PACKAGE + PRIVATE.

- L.in(A) succeeds (returns a lookup object) regardless of whether its caller is in a module that reads A's module. Only when find* is called on a lookup object is there a check that the caller-of-find*'s module reads the module containing the lookup class embodied by the lookup object. It's easy for the caller-of-find* to pass the check by calling addReads(...) just before calling find*.

(Sidebar: Separately, the module containing the lookup class embodied by the lookup object had better have readability to other modules in order for find* to look up [ctors, methods, and fields of] classes in those other modules.)

Should there be a way to build a lookup, for two modules M1/M2, which
reads those names of M2 which M1 can read, except no internals
of M1?  I wonder if such a thing would be useful?  Probably not.

But it would be useful to have a lookup in a module M1 which can
read the exports of *every* M2 that M1 can see, except no M1 internals.
(This includes the unconditionally exported public names of M1.)
This would be a Lookup with an LC in M1 and flags of PUBLIC only.

The difference between these two paragraphs is hard to discern. The first paragraph seems to fix M1 and M2 while the second paragraph fixes M1 and varies M2, but there's also a switch from "M1 can read" to "M1 can see". Modules read modules, classes see classes, types access types. Can you restate?

Alex

Reply via email to