The rationale for runtime modularization
Frank Yuan
frank.yuan at oracle.com
Fri Dec 4 09:37:13 UTC 2015
Since "you're definitely going to look into ways to address that", I would like to send a bit of personal opinion.
The module encapsulation sounds like access modifier, but non-public member can be accessed through reflection, so it looks more
like accessClassInPackage barrier of security manager. However security manager is off by default, if anybody wants security
manager, he should realize his cost, meanwhile every jdk9 user will have to bear module whether they require this feature or not,
like government taxes everyone(government certainly think it's for everyone's wellbeing, but everyone wants less tax...).
Well, let's go back to the technical topic, now module encapsulation is neither as traditional access modifier nor as security
manager, before you looking into the ways, do you think keeping a consistent concept may help lower the learning curve?
> -----Original Message-----
> From: jigsaw-dev [mailto:jigsaw-dev-bounces at openjdk.java.net] On Behalf Of mark.reinhold at oracle.com
> Sent: Friday, December 04, 2015 8:20 AM
> To: Rafael Winterhalter <rafael.wth at gmail.com>
> Cc: jigsaw-dev at openjdk.java.net
> Subject: Re: The rationale for runtime modularization
>
> 2015/12/3 1:36 -0800, Rafael Winterhalter <rafael.wth at gmail.com>:
> > I am writing this after looking into Jigsaw for about two months and
> > after running my open-source libraries and several enterprise
> > applications of my current employer using the EA builds.
>
> Glad to hear it!
>
> > In the context of these experiences, I wanted to ask for the rationale
> > of project Jigsaw to enforce modularization at runtime.
>
> Short answer: Strong encapsulation at run time greatly improves both security and maintainability. (Strong encapsulation at
compile
> time makes it much easier to prepare for strong encapsulation at run time.)
>
> > In the software I have searched, reflection is predominantly used for
> > interacting with code that is unknown during compilation. Of course,
> > sometimes reflection is used for abstracting code from types but this
> > is extremely rare as generic types pretty much cover this need.
> >
> > In practice, this implies that any reflective invocation requires an
> > explicit module check. This check can be easily forgotten.
>
> The failure in this case should be easy to diagnose, and the remedy would be to invoke the Module::addReads method. (If the
target
> module doesn't export the relevant package then you'll need to arrange for that too, either via a command-line flag or possibly by
> some more convenient means yet to be devised.)
>
> >
> > Furthermore, the compiler does not remind of missing edges when migrating software either.
> > It seems to me that the assumption for the runtime checks is that
> > invocations might accidentally cross module boundaries.
>
> The checks performed by the reflection APIs themselves are intended to match those performed by the compiler and the VM for
> non-reflective operations, so whether accidental or not a reflective attempt to break encapsulation will be caught.
>
> > From the code
> > that I looked at, I argue that this is already the primary intention
> > when using reflection.
>
> Yes, it's probably more common to use reflection to access types in other modules rather than in the same module.
>
> > One might argue that the same holds for reflection on non-public types.
> > However, in this case I believe that security concerns are the main
> > reason for enforcing accessability where access can be denied by a
> > security manager.
>
> That concern also applies to public types which are not meant to be used in unintended ways -- and there are lots of those, both
in the
> JDK and in general.
>
> > Modules on the other hand cannot provide additional security
> > as there is always an opt-out for non-modularized code to avoid such barriers.
>
> Non-modularized code can only break through module barriers if explicit permission is given for that, on the command line. So
yes,
> there's an opt-out mechanism, but it forces the end user to be aware that the system as a whole will run with compromised
integrity.
>
> > I am sure this possibility was considered and I wonder why it was not
> > implemented. Looking at the very little practical relevance of heap
> > pollution caused by type-erasure, I believe that compile-time
> > modularization would work well in this case, too. The Java compiler
> > could enforce module boundaries while users of reflection would not be
> > bothered with the boundaries they intended to cross in the first
> > place. As the most important benefit, migration would be much easier.
> > Libraries could add module descriptors to pre-Java-9 bundles without
> > needing to alter code since runtime behavior does not longer depend on the bundling format.
>
> If strong encapsulation is to mean anything then it must be enforced at run time, so a purely compile-time approach is just not
viable.
> (One could argue that we already have compile-time modularization today, with build tools such as Maven, in which case if compile-
> time modularization were sufficient then we never would've started this project.)
>
> It's become clear from all the recent feedback that the current design might be making life a bit too hard for framework libraries
that
> make heavy use of reflection, so as I indicated in a nearby thread we're definitely going to look into ways to address that.
>
> - Mark
More information about the jigsaw-dev
mailing list