I wanted to second Paul’s comments on jams-spec-comments[1], but with some 
additional thoughts.

The proposal takes a step in the right direction by allowing a runtime path to 
bypass access control. However, the fundamental issue at play is that class 
visibility is being used as an access control mechanism, and these concerns are 
really orthogonal notions. One of Java’s most powerful historic capabilities is 
that it is fully introspective and dynamic, and this has empowered a large 
ecosystem of frameworks and platforms that have extended the language in novel 
ways. All of which ultimately lead to it being a dominant server side 
development platform. 

A major commonality in modern programming models is the notion of inversion of 
control. For those unaware, with IOC, a fundamental notion is that the user 
defines code which is solely focused on a particular concern, and it is 
completely unaware of other parts of the system which later enhance that code. 
JSR 250 (part of SE), demonstrates an example, the user simply needs to add a 
few annotations, and their classes are dynamically augmented at runtime with 
new behavior.  JSR 330 (also part of SE) is another, a container of some sort 
is responsible for constructing classes that could be anywhere in any module 
and injecting those instances based on some set of rules into other classes’ 
private fields. This sort of thing is very pervasive (most specs that make up 
Java EE, JPA, Spring, JAXB, CXF, custom serialization frameworks, mock 
frameworks, etc). Even the JDK itself needs this ability.

This brings us to the problem with the proposal. The expectation AFAICT appears 
to be that the user defining the enhanced code knows the identity of the module 
enhancing it (e.g. exports dynamic com.foo.app.model to jpa). The module is 
simply not in a position to know that just “jpa” requires access. There might 
be more than one version of jpa which needs to be selected dynamically, or jpa 
might be broken into multiple modules itself. It’s effectively bleeding 
container/framework implementation details into the user defined code. 

To run reliably in a Java EE container, the user would have to not qualify 
dynamic export, and also define an export on everything to every module always. 
But then we run into a lot of boiler plate that has to always be added by the 
user and is easily forgotten and/or misconfigured for a very common use case. 
This runs counter to the goals of many modern programming models, which seek to 
eliminate boilerplate.

Additionally now the user is forced to define their visibility wider than 
necessary, causing potential conflicts that would have otherwise been avoided. 
Also any security benefit the access control check has seems easily defeated at 
this point, since IIUC anyone can just compile against a different definition 
removing the dynamic modifier.

One could address the boilerplate/usabilty issue by inverting this mechanism 
from opt-in to opt-out (all packages are dynamic export unless a restriction is 
specified). However the other visibility issues aren’t really addressed.

I think the only way to truly solve this problem is to decouple access control 
and visibility. 

If the code doing the enhancing/introspection had to obtain the permission 
which applied everywhere, this would achieve the necessary decoupling and still 
have decent security. In fact this is already accomplished with the Java 
security manager today. However if a duplicate mechanism is truly necessary, 
perhaps a special signed code mechanism, similar to what JSSE providers do 
today is workable, albeit a bit burdensome to framework developers

One proposal that was brought up long ago to improve access control that I 
thought seemed quite powerful would have been to support granting access of 
package-protected to other modules. That would have resulted in far less things 
being made public, which I suspect is the motivation for adding additional 
access control checking. I imagine it’s too late for something like that, but 
worth mentioning.

Thanks,
Jason

[1] 
http://mail.openjdk.java.net/pipermail/jpms-spec-comments/2016-June/000053.html

--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat

Reply via email to