Hi,

I'll try to question the proposal for #ReflectiveAccessToNonExportedTypes from a different angle.

The proposal extends the language of module declaration with "exports dynamic" variant of export. Like classical plain "exports", the dynamic variant comes in unqualified and qualified flavor.

1st I'll question the qualified flavor. A qualified dynamic export is meant to list the modules that are granted runtime-only access to exported types, such as IoC frameworks or JPA frameworks, etc. I argue that such frameworks, when compiled, don't even know of modules that will dynamically export the types to them. Such frameworks only learn of those dynamically exported types at runtime. That's why such frameworks use reflection or runtime bytecode generation to access such types. The question is then why would one want to use qualified "exports dynamic" instead of plain qualified "exports" if the modules that are listed in qualified exports never appear to be compiled compiled together with the exporting module. IoC containers are never compiled together with all the modules that will use them. Hibernate is never compiled with all the modules that will use it, etc. In my opinion, qualified "exports dynamic" has no weight. Plain qualified export is enough for the same purpose.

2nd I'll question the unqualified flavor of "exports dynamic". I have a feeling that unqualified "exports dynamic" is a compromise. A module may not know at compile time to which IoC framework or JPA implementation it wants to export some of its types so that this framework may access those types at runtime. Will it be Spring or Guice? Will it be Hibernate or EclipseLink? So instead of listing all the possible modules (that may not even exist yet at that time), it simply uses an unqualified "exports dynamic". What it does by unqualified export is it gives runtime access to those types to all modules. It prevents compilation against those types, but I'll argue that this is not a "strong" encapsulation that Jigsaw is famous for and can be used to implement secure systems. It is a compromise. And users are forced to make a compromise too. Either they use qualified exports with fear that they will not list a module that may be used at runtime and will want to rightfully access the types or they use unqualified "exports dynamic" and fear that some unauthorized module accesses their types at runtime.

Is there an alternative?

Remember J2EE and infamous deployment descriptors? Despite the hatred towards those XML files that had to be composed somehow at "deployment" time, J2EE acknowledged the fact that there is not only an app developer, but also a "deployer". The one that decides how application modules and app server interact in some details. In above cases, the module that "exports dynamic" some of its types is not always in a position to decide what modules it wants its types to export to. It is always in a position to decide what packages to export but not to which modules. Could these two pieces of information be decoupled so that the module would just specify the packages and the "deployer" would specify target modules?

A rough idea:

Let's extend the qualified export with the ability to specify as targets not only module names, but also "labels" or "module groups" - those could be names distinguished from module names by using a special syntax. For example: this.is.a.module.name vs. @this.is.a.label.name. Now we have created a job for the "deployer". What he/she does is specifies the mapping from label names to module names (many to many). That's all.

The devil is in the details of course. How to surface such mapping? The most logical place is in the Layer. Each Layer would specify a mapping from arbitrary label names to arbitrary module names limited to modules of that Layer. The composition of a child Layer would then have to be protected by a special permission otherwise arbitrary code could "attach" its own Layer and get access to types exported to any "label". java/javac tools would specify the mappings for the boot layer as command-line options.

As to the implementation details. Label names perhaps don't need to be exposed to the VM. The mappings could be "expanded" when a Layer is constructed and exports at the VM level augmented with new module targets.


What do you think?

Regards, Peter

Reply via email to