A different feedback on proposal for #ReflectiveAccessToNonExportedTypes
Peter Levart
peter.levart at gmail.com
Tue Jul 12 16:51:59 UTC 2016
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
More information about the jigsaw-dev
mailing list