Proposal (revised^2): #ReflectiveAccessToNonExportedTypes & #AwkwardStrongEncapsulation: Open modules & open packages

David M. Lloyd david.lloyd at redhat.com
Mon Nov 7 15:08:15 UTC 2016


I was waiting on a response to an earlier question about readability, 
but I'm pretty sure I know the answer so I'm going to plow ahead.

On 10/27/2016 10:53 AM, mark.reinhold at oracle.com wrote:
> Extend the language of module declarations with the concept of _open_
> modules.  Open modules make it easy to define modules whose internals
> will be accessed at run time by reflection-based frameworks.
[...]
> Open modules can be considered an intermediate step on the migration
> path, between automatic modules and normal modules:
>
>   - An automatic module offers the traditional level of encapsulation:
>     All packages are both open for deep reflective access and exported
>     for ordinary compile-time and run-time access to their public types.
>
>   - An open module offers a modest degree of stronger encapsulation: All
>     packages are open for deep reflective access, but the module's author
>     must specify which packages, if any, are exported for ordinary
>     compile-time and run-time access.
>
>   - A normal module offers the strongest encapsulation: The module's
>     author must specify which packages, if any, are open, or exported,
>     or both.
>
> An open module is a good starting point for application code that's being
> modularized by its author.  It affords a separation of concerns, so that
> the author can focus on defining the module's domain-specific API without
> having to worry about how the module will be inspected or manipulated at
> run time by reflective frameworks.

This part looks OK.

> To open specific packages in normal module declarations we introduce a
> new per-package directive, `opens`.  A package in a normal module can be
> opened, or exported, or both, as follows:
>
>   - If a package is only opened (`opens p;`) then properties (1), (2),
>     and (3) hold, i.e., its types are not accessible at compile time,
>     it does not affect resolution, and all of its elements are available
>     for deep reflection at run time.
>
>   - If a package is only exported (`exports p;`) then those properties
>     do not hold, and it is exported exactly as it is today.
>
>   - If a package is both exported and opened (`exports p; opens p;`)
>     then it is exported as today and is, additionally, available for
>     deep reflection at run time (3).

I'd like to stop here and ask a bit about deep reflection, based on some 
discussion happening on jigsaw-dev.

It was my assumption that "deep reflection" implies any indirect access 
to nonpublic members - which includes MethodHandle style access as well 
as classical reflection.  So here are some questions:

1) I assume that one will continue to be able to unreflect any 
AccessibleObject which has had accessibility enabled and get 
MethodHandles which have deep reflective access.  Is this assumption true?

2) Is it a goal to ultimately eliminate setAccessible()?  In other 
words, is this the direction that Java security is moving?  (No wrong 
answer here, I just haven't been able to glean a clear yes/no answer to 
this and it's definitely important to guide my thinking on this issue 
since I'm mentally trying to follow two paths at once on this.)

3) Given nonpublic member M in an opened package; will/could/should it 
be possible for Lookups (belonging to classes which observe the 
"openness" of M's package) to be able to directly create or acquire 
MethodHandles for M without using reflection (especially if the answer 
to #2 is "yes") and without relying on donated Lookups?

Otherwise I think this part of the proposal as stated makes a lot of 
sense and covers our use cases fairly well.

> It's possible to both open and export a package in a normal module, but
> it's often inadvisable.  This is especially so for API packages, since
> normally an API's internal implementation details should be strongly
> encapsulated.  This combination of directives may, however, be useful for
> legacy APIs whose internals are known to be accessed by existing code.
>
> To ensure the integrity of the platform we expect that all the modules of
> the JDK itself will be normal modules and that very few, if any, packages
> will be opened.
>
> The `opens` directive cannot be used in an `open` module, since all
> packages in such modules are implicitly open.

Good so far.

> Both the `exports` and `opens` directives can be qualified, so that a
> package is exported or opened only to certain other named modules.  As
> before, duplicate directives are not permitted in order to ensure easy
> readability.  At most one `exports` directive is relevant to any given
> package, and at most one `opens` directive is relevant to any given
> package.

Do module names specified in qualified "opens" directives need to be 
present at compile or run time, or will absent module names be ignored?

> There is no syntax for wildcards.  If the defaults are not sufficient for
> a package then the package must be named explicitly.

OK

> The existing syntax of `requires public` has long been confusing, so we
> here take the opportunity to fix that problem by renaming the `public`
> modifier in `requires` directives to `transitive`.  Thus the declaration
>
>     module foo.bar {
>         exports com.foo.bar;
>         requires public java.sql;
>     }
>
> is now written
>
>     module foo.bar {
>         exports com.foo.bar;
>         requires transitive java.sql;
>     }

Just to clarify, since this isn't really clearly spelled out in SOTMS or 
in any other doc at present (I think?), "requires transitive" means 
exactly that all packages exported by "java.sql" are also exported by 
"foo.bar", and that there is no way to narrow the set of packages in 
this case, correct?

Also, I assume that requiring with "transitive" does not imply that 
"openness" is also transitively exposed, i.e. openness is always 
non-transitive.  Is that a correct assumption?

Overall this is a very good proposal, and I think (unless the answer to 
one of the above questions is very surprising) that we (Red Hat) are 
close to agreement on it.

-- 
- DML


More information about the jpms-spec-experts mailing list