Hi Stanley,
Sorry if I'm not being clear. Let me try to summarize:
- I *do* want 277 to support private (non-exported) resources, but
- I do not think we should use permissions as the enforcement mechanism.
- I believe the 'caller-class-is-member' enforcement mechanism is
sufficient, and
- I do realize that this means ResourceBundle.getBundle() (or similar)
will fail to find private resources; these must be made public.
Let me give more detailed reasoning for this position...
You are of course correct that a class loader is free to add permissions
to any class by assigning a ProtectionDomain with those permissions
during defineClass(). (Let's call these "hard-wired" permissions.)
So permission to access private resources could easily be hard-wired for
other classes *in the same module*.
To this point, there really isn't any meaningful difference between
using permissions or using my approach: both allow module classes to
directly access their private resources.
But if we want to grant that same permission to *any* class outside of
the module, it gets far more interesting. And it is this problem that
I'm concerned with.
For ResourceBundle.getBundle(), for example, to access a private
resource, we must grant permission to the *ResourceBundle* class. And
how do we do that?
We could hard-wire permission for ResourceBundle, but... what about
ServiceLoader? Ok, so let's just hard-wire permission for any JRE module.
Problem solved? Not at all: what about all the non JRE frameworks out in
the world that need the same kind of access?
Clearly we cannot hard-wire permissions for these. So now we need to use
policy file entries to do so. We could of course take this approach, but
it either leaves some poor admin running around to update policy files
as things break, or some fancy mechanism to grant access during
framework module install. Ick.
And, hard-wired or not, permissions *are* a friend model.
But 294 is not likely to provide such a model for classes.
So, even if we hard-wire permission for ResourceBundle to access a
private resource, how is it going to access a private ListResourceBundle
class? Or how will the ServiceLoader gain access to the service provider
class? How will third-party frameworks solve this problem?
It is hard for me to see how all this complexity is justified, simply to
hide resources that have never been hidden before.
This doesn't mean there is no place for private resources! It just means
that they can only be used by the module classes themselves. And this is
still a very valuable feature: developers can restrict access to
resources that are strictly implementation details.
// Bryan
Stanley M. Ho wrote:
Hi Bryan,
Bryan Atsatt wrote:
...
No, I don't agree. That's what I said before :^). I *really* don't like
the idea that I'm going to have to explicitly grant permission to some
module to access my resource. This *significantly* complicates
No, this was not what I suggested. If some other modules want to access
your resource, your resources need to be exported. However, if you want
to access your own private resource in your module (call
ClassLoader.getResource*() directly or call ResourceBundle.getBundle(),
etc.), then your code would require additional permissions.
deployment. How will the grant occur, especially given that each
environment can use an entirely different permission storage mechanism?
Or are you thinking that the loaders in the module system will construct
ProtectionDomains pre-wired with permissions? If so, exactly which
entities will be blessed? Just the JRE code? What about all the existing
non-JRE frameworks in use?
When your module instance is initialized, the module system can
construct the ProtectionDomain with the appropriate permissions and
associate that with the classes in your module, so your classes in your
module will always have the necessary permissions to access your own
resources.
Sure, resources have never had JVM access control applied to them. But I
don't think we should go to the other extreme (permissions) just so that
I can give "friend" access to private resources. I'd much prefer that
such resources simply be exported.
And I don't see this as a particular problem, either. We've gotten along
just fine without private resources so far (or maybe there is some big
demand for this that I'm missing?).
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?
// Bryan
Note that the security permission approach can be abused if a module has
all permissions, it can access even the private resources in other
modules. This is the friend access as you mentioned, but this is not my
intention of using the security permission approach.
Sorry, I have to go and I can't response in details here. Are you saying
that we should probably give up the idea of exported/private resources
and make all resources in a module to be always public and accessible?
Or are you saying that you still like the idea of exported/private
resources but you don't like to address it using the security permission
approach?
- Stanley