Hi Bryan, Bryan Atsatt wrote:
... frameworks/libraries are precisely what a module system is for: to allow their clients to *avoid* bundling the jars. And they aren't likely to be deployed as extensions, either; not when there's this nice repository model. Consider Spring. Or any of the hundreds of other third party frameworks/libraries out there. We *want* these to be deployed as normal, separate modules.
I agreed. My point was that in many cases, these frameworks/libraries would be deployed into the repository and loaded with all permissions at runtime, so this should not be an issue even they are deployed as normal, separate modules.
There is a much bigger issue, which is that this whole model falls apart simply because we can't grant this type of "friend" access to module private classes... Your description of how ResourceBundle or ServiceLoader accesses the class contains a big assumption, one that *could* be correct for such JRE code, but is almost certainly wrong for third-party code. These types of frameworks call Class.forName() or loader.loadClass(). And then they call either Class.newInstance() or Constructor.newInstance(). Regardless of whether or not they invoke any other methods, JSR 294 will require an access control check at the point of instantiation, extending those it performs today. Look at how Class.newInstance() and Constructor.newInstance() both use: Reflection.ensureMemberAccess() This is the logical point at which to inject the new module private access control check. Could this be made to succeed for JRE callers? Of course (but it wouldn't be right, IMO). But, more importantly: it won't, and cannot, succeed for third-party callers without some sort of friend model for classes. Which isn't on the table. So, again, if we're not going to do this for classes, why should we do it for resources?
Sorry, I still don't think I fully understand your point. From my perspective, the access model for exported classes and exported resources are orthogonal. I agreed that it would be nice to have some symmetries between them, but I think we already concluded why this is not feasible because of their fundamental differences. The fact that this is not how we support classes today doesn't mean we could not do it for resources. Perhaps it would help to pull out the following question you had couple emails back for our discussion: Bryan Atsatt wrote: > And what about the mismatch issue I brought up? Lots of existing > frameworks use the "services" pattern, in which: > > 1. A well known resource name is used in a getResource() call. > 2. The resource contains a string naming a provider class. > 3. The provider class is loaded using Class.forName(). > > This is a simple but very powerful pattern, but it requires that *both* > the resource and the named class be accessible to the framework. If we > require a permission grant for the resource, but not for the class, it > will be very easy to get access to one and not the other. Is it really > worth opening up this potential headache to enable a friend model for > resources? In today's model, if the resource is available, #1 will always succeed. If the provider class is available, then #3 will also succeed, and whether the class is accessible will be determined by the JVM. The entire "exported resources" issue is basically around the behavioral change in #1; this is orthogonal to #2 and #3, and I think we should ignore the entire "exported classes" issue for the moment to keep this discussion focus. That said, I realize that we might have been thinking about two very different use cases (correct me if I misunderstand you) here: a. Some service-related frameworks (e.g. ServiceLoader) need to retrieve resources like META-INF/services/<service-provider> from the module classloader. b. A module uses the ResourceBundle APIs to retrieve property-based resources or list-based resources from its own module. For (a) alone, I would agree with you that this kind of resource might simply be exported. In fact, I don't think this should even be considered a private resource because its content is intended for external consumption. For (b), I don't think it makes sense to require a module exporting the private resources for its own consumption, and this is where I hope the security permission approach would help to make it work. Suppose we say that resources like (a) should be exported while resources like (b) should remain private (and we'll use the security permission approach to allow module to access its own private resources), do you think you can live with this? - Stanley