Feedback on proposal for #ReflectiveAccessToNonExportedTypes
Jason Greene
jason.greene at redhat.com
Thu Jul 7 20:17:33 UTC 2016
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
More information about the jpms-spec-comments
mailing list