On 09/12/2015 14:54, stanislav lukyanov wrote:

1) Lookup.in() javadoc says
"If the lookup for this Lookup is in a named module, and the new lookup class is in a different module M, then no members, not even public members in M's exported packages, will be accessible"
However, it seems to be possible to have PUBLIC access after
lookupInA.in(ClassInB.class)
without breaking "no more access capabilities than the original" rule.

Are such transitions intentionally forbidden?
Yes, this is intention as the lookup class and mode bits would otherwise not be sufficient when you teleport through a sequence of lookup classes. It might be clearer if you extend the example to in(B.class).in(C.class).in(D.class) where B, C and D are in different named modules and work out the intersection.



2) Lookup.in() javadoc says
"If the lookup class for this Lookup is not in a named module, and the new lookup class is in a named module M, then no members in M's non-exported packages will be accessible"

Spec says nothing about M's 'requires' and 'exports to M'.
In current implementation, modules required by M are still accessible
and packages exported to M (with 'exports to')  are not accessible.

It seems right that packages exported to M are not accessible.
Should it be specified in the javadoc, or is it implied due to definitions somewhere else?
It is implied because the javadoc provides the guarantee that the resulting Lookup has no more access than the original. In this case there are packages exported by M's friends to M that are not accessible to code in unnamed modules. However, I think you are right that this could be make clearer in the javadoc. I'm sure that once the design settles down that we'll do several passes over the javadoc.

:

However, this creates some uncertainty.
Suppose we have A requires B. From user's point resulting lookup of
publicLookup().in(ClassInA.class)
may or may not have access to the module B - it depends on module A's 'requires' which user doesn't know about.

It may come to the following situation. Code
publicLookup().in(BlassInA.class).findStatic(ClassInB.class, "m", ...).invoke()
works with version of A that have 'requires B'.
In the next version, A removes 'requires B' which should not
have any impact on A's users, but the code above stops working.
Sure, the other thing is that readability graph can mutate at run-time so that `A` reads additional modules.




3) publicLookup() seems to allow work around the module access control.
publicLookup() is available for any module and has access to any module's exported packages. So, if we have modules A and B that do not require each other, we can still access B from A:
// code in A
publicLookup().in(ClassInB.class)

Is it OK to be able to do such tricks?

The publicLookup can only be used to access types that are are public and in packages that are exported unconditionally. It can't be used to break encapsulation, either directly or by teleporting and using a lookup class in another module.

Also `A` can call addReads to read any other module so this allows it to access any public type in any package exported by other modules if it really wants. This means that there is nothing that the publicLookup can be used to access that `A` can't access anyway.

-Alan


Reply via email to