Proposal: #ReflectiveAccessToNonExportedTypes: `exports dynamic`

Stephen Colebourne scolebourne at joda.org
Thu Jun 30 21:29:24 UTC 2016


For 20 years, reflection has been used as a low-level tool to access
any code on the classpath. No developer up to this point has thought
about modules being a relevant boundary for what they should or should
not touch with reflection.

To take one example from OpenGamma Strata:
https://github.com/OpenGamma/Strata/blob/master/modules/collect/src/main/java/com/opengamma/strata/collect/named/ExtendedEnum.java#L181

ExtendedEnum is a mechanism to provide enum-like behaviour, where the
set of constants is fixed at startup, but controlled dynamically based
on what configuration files are present. One of the options it
provides is for the configuration file to specify a Class name, which
is then reflected on to find suitable enum-like constants.

When designing this feature, at no stage did I think that the code
would not work because some of the constants are in a different
module. (Application users can add their own configuration files and
constants, ie, in a separate module).

This proposal essentially requires application users to specifically
expose these types to reflection where they might otherwise lock them
down in a non-exported package. While in this case, I could document
that users of extended enums must make sure their code can be accessed
if in a different module, it would at the very least be a faff, and a
source of questions.

IMO this goes against how reflection has been used and is simply not practical.

I would propose the opposite change to this one. Provide a mechanism
where a module can choose to block reflection on a package by package
basis. I believe this could provide the security necessary without
obstructing adoption.

Stephen


On 30 June 2016 at 22:02, Alex Buckley <alex.buckley at oracle.com> wrote:
> Volker,
>
> Please share details of why your application needs to reflect over the
> internals of another module.
>
> Alex
>
>
> On 6/30/2016 1:09 PM, Volker Berlin wrote:
>>
>> Reflection should be enabled by default. My current launcher for Java 9
>> check if the needed refection is possible. If not possible then it
>> restart the application with a very long list of -XaddExports switches.
>> I think this is not what we want.
>>
>> Volker Berlin
>> i-net software
>>
>>
>> Am 28.06.2016 um 23:18 schrieb Mark Reinhold:
>>>
>>> Issue summary
>>> -------------
>>>
>>>    #ReflectiveAccessToNonExportedTypes --- Some kinds of framework
>>>    libraries require reflective access to members of the non-exported
>>>    types of other modules; examples include dependency injection (Guice),
>>>    persistence (JPA), debugging tools, code-automation tools, and
>>>    serialization (XStream).  In some cases the particular library to be
>>>    used is not known until run time (e.g., Hibernate and EclipseLink both
>>>    implement JPA).  This capability is also sometimes used to work around
>>>    bugs in unchangeable code.  Access to non-exported packages can, at
>>>    present, only be done via command-line flags, which is extremely
>>>    awkward.  Provide an easier way for reflective code to access such
>>>    non-exported types. [1]
>>>
>>> Proposal
>>> --------
>>>
>>> Extend the language of module declarations so that a package can be
>>> declared to be exported at run time but not at compile time.  This is,
>>> roughly, the dual of the `requires static` construct proposed for
>>> #CompileTimeDependences, hence we propose to introduce a new modifier,
>>> `dynamic`, for use on the `exports` directive.  It has the following
>>> meanings:
>>>
>>>    - At compile time, `exports dynamic P` does not cause the package `P`
>>>      to be exported, though it does require `P` to be a package defined
>>>      in the module.
>>>
>>>    - In phases after compile time, `exports dynamic P` behaves in exactly
>>>      the same way as `exports P`.  It therefore takes part fully in
>>>      resolution and configuration, and is subject to the same consistency
>>>      constraints as normally-exported packages (e.g., no split packages).


More information about the jpms-spec-observers mailing list