Proposal: #ReflectiveAccessToNonExportedTypes (revised) & #AwkwardStrongEncapsulation: Weak modules & private exports

Stephen Colebourne scolebourne at joda.org
Tue Oct 11 17:11:53 UTC 2016


On 11 October 2016 at 16:14,  <mark.reinhold at oracle.com> wrote:
> A couple of other problems I see with Colebourne's approach:
>
>   - The only way to allow an exported API package to be used reflectively
>     is to expose it for deep reflection.  That requires typing another
>     directive and, worse, makes the internals of that package available
>     for deep reflection, which is probably not what was intended.

Having re-read my proposal, you are correct, however it wasn't what I
intended. My intention was that 'exports' included reflection on
public types (shallow reflection) and 'exposes' was necessary for
access to non-public types (deep reflection).

>   - The interactions between `exports`, `exposes`, and the qualified
>     forms of these directives turns out to be pretty complicated once you
>     work out all the cases.  (We've done this internally, for a somewhat
>     similar proposal that allows both `private` and `dynamic` modifiers
>     on the `exports` directive.)  They wind up being nearly as bad as the
>     existing rules for protected members [2].  I'm not convinced that
>     this relatively small bit of expressive power is worth the additional
>     complexity.

I suspect that this complexity comes from interaction with the "to"
clause of exports/exposes. (4 basic variations - not exported,
standard export, exposed not exported, exposed & exported, plus the
various combinations of where things are exported/exposed to)

However, I also consider the compromise of the Reinhold proposal, that
there is no way to export for deep reflection without also exporting
for normal IDE use, is simply not acceptable. Too many modules will
need deep reflection, that the current proposal essentially means that
the strong encapsulation requirement cannot be met.

It is worth noting that the debate since the latest proposal came out
has primarily been about deep reflection and how to allow that in the
system There has been little disagreement that the "standard" type of
strong encapsulation should only include shallow reflection on public
types.

Taking a step back, the following seems like simplest thing that would work:

weak module foo {
  requires...
  // all packages exported
  // all packages accessible for deep reflection
}

exposed module foo {
  requires...
  exports...
  // all packages accessible for deep reflection
}

module foo {
  requires...
  exports...
  // strongly encapsulated, no deep reflection
}

(Happy to see alternative keywords proposed instead of weak/exposed)

This provides a simple sliding scale of encapsulation - weak, exposed
for deep reflection and strong. And there should be no combinatorial
explosion of complexity.

What is lost is the ability to only expose some packages for deep
reflection, or to expose deep reflection only to certain modules. But
I am very comfortable with that compromise - it seems like once you
grant deep reflection, you are giving the keys away to the whole
module, and trying to restrict it further than the module-level is a
game of diminishing returns.

Consider this Colebourne proposal #2 ;-)

Stephen


More information about the jigsaw-dev mailing list