Hi Bryan,

I would like to get closures on a few open issues first, so my responses
will be limited to those threads rather than all the new threads that
have been started recently.

Bryan Atsatt wrote:
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

Good.

- 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.

The system classes are granted with all permissions, so they will have
sufficient permissions to access the private resources in a module. I
don't think this is a real issue.

Problem solved? Not at all: what about all the non JRE frameworks out in
the world that need the same kind of access?

I agreed that using other frameworks might be a concern.

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.

If the framework is bundled as part of your module, it will have the
same set of permissions as the other code in your module, so it will
have sufficient permissions to allow your code to access the private
resources. If the framework is deployed through the typical mechanisms
(e.g. extension classpath, etc.), it will have all permissions, hence it
will also have sufficient permissions to access the private resources.
Further, if the framework is deployed as another module in one of the
system's repositories, it will likely have all permissions to allow your
code to access the private resources in your module as well. Moreover,
if the framework JAR/module is signed and is trusted, the system will
typically grant all permissions to the code in the framework when the
code is loaded. In other words, there is no need to explicitly grant
permissions in most scenarios.

The scenario where this may be an issue is when the framework is
deployed through some other means (e.g. other modules in a
URLRepository, JARs in custom classloaders) *and* the framework is
unsigned (or if the framework is signed but not trusted for some
reasons), it may not have sufficient permissions to allow your code to
access the private resources through the framework API. However, it is
unclear to me if there are frameworks deployed like this for this issue
to become a real problem. Do you have any example that shows this is a
real problem?

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?

In a typical classloader, all public and private classes are visible
(return from loadClass()) externally but only the public ones are
accessible (invoke without access control failure). When a module uses
the ResourceBundle API to load the ListResourceBundle from the module
itself, the ResourceBundle API only loads the class from the module
classloader and the class is returned to the code in the module for
actual access. ServiceLoader works in similar way that the ServiceLoader
only loads the service-provider class but it's the actual caller who
accesses the class. Therefore, I don't think there is a real problem here.

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.

I don't think the security permission approach is actually complex, and
I do have two concerns with the approach you suggested:

1. A module has to export its own supposed-to-be-private resources in
the same module in order to use the ResourceBundle API to load them.

2. It does not allow private resources in a module to be accessed
externally by any mean.

My main concern is around #1 'cause it doesn't sound right to me - I
think a private resource should stay non-exported. #2 is an issue if we
want to support a way for external code to access the private resources.
There is already a setAccessible() method that allows you to override
the default access control and to access private methods/fields in
classes, so I think it would also make sense to have a way for external
code to access the private resources when necessary (e.g. debugging,
diagnosis, etc.).

- Stanley

Reply via email to