Proposal: #ReflectiveAccessToNonExportedTypes: `exports dynamic`

Alex Buckley alex.buckley at
Thu Jun 30 22:53:43 UTC 2016

On 6/30/2016 3:33 PM, Paul Benedict wrote:
> To my main point, it's not really reasonable to know who may want to
> reflect your internals. If you're publishing yourself as a common
> library serving as middleware, how can you guess at that? You just
> can't.

Stephen's case involved a user module whose code is written to follow a 
specific idiom offered by a library. Since the library specifies that it 
implements the idiom through reflection, it's fine for the user module 
to have a qualified 'exports dynamic ... to strata'.

> Alex, in your counter example, pretend "myapp" has been published to the
> Maven repository in 2017 and ten years has passed. In 2017, it's great
> that "myapp" can use "opengamma.strata", but it becomes absolutely
> useless to "opengamma.strata2" in 2027 despite the fact "myapp" should
> be perfectly usable. See the problem?

Remember that module myapp requires opengamma.strata so 
opengamma.strata2 is irrelevant. If opengamma.strata2 offers a 
SuperDuperExtendedEnum idiom in 2027, that's great, but myapp's enum 
provider classes weren't written to follow that idiom, so it's right for 
myapp to export its tickers package solely to opengamma.strata.


> Let's take this example closer to the real world:
> Struts:
> (1.x) org.apache.struts
> (2.x) org.apache.struts2
> (3.x) ???
> Log4J:
> (1.x) org.apache.log4j
> (2.x) org.apache.logging.log4j
> (3.x) ???
> JBoss Community/AS:
> (<7) org.jboss
> (8-11) org.wildfly
> (12+) ??? * not implying a change but not presuming either
> [1]
> Cheers,
> Paul
> On Thu, Jun 30, 2016 at 4:58 PM, Alex Buckley <alex.buckley at
> <mailto:alex.buckley at>> wrote:
>     On 6/30/2016 2:29 PM, Stephen Colebourne wrote:
>         To take one example from OpenGamma Strata:
>     (Line 50: I think "are" should be "as".)
>     (Line 181: I notice that while "constants" and "lookup" providers
>     are specified in the class-level javadoc, "instance" providers are
>     not. Admittedly, reflection is used not only for the [unspecified]
>     special field of an "instance" provider class but also for the
>     [specified] no-args ctor of a "lookup" provider class.)
>         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.
>     Counterpoint: the user's is a great place to
>     document the special relationship between one of their packages and
>     one of their dependencies.
>     module myapp {
>        requires opengamma.strata;
>        // Classes to drive Strata's ExtendedEnum instances
>        exports dynamic to opengamma.strata;
>     }
>     Alex

More information about the jpms-spec-observers mailing list