Exported resources
Bryan Atsatt
bryan.atsatt at oracle.com
Wed Jun 6 16:48:07 PDT 2007
Stanley M. Ho wrote:
> 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,
That last phrase seems like a huge leap to me. How exactly would this
grant all permissions? And, even if it did, it seems like an *extremely*
large security hole!
(But, again, I don't feel the need to dwell on the grant issue at the
moment--we have bigger fish to fry.)
> 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?
It isn't just me that can't live with it :^). You are correct that
private *property-based* resources could be retrieved this way, but
incorrect about *list-based* resources.
"List-based" resources are... *Class* instances. Specifically, they are
subclasses of ListResourceBundle. They must be loaded and instantiated
by ResourceBundle.
If ListResourceBundle subclasses are module private,
ResourceBundle.getBundle() will fail. And we have no mechanism to grant
access.
// Bryan
>
> - Stanley
>
More information about the jsr277-eg-observer
mailing list