Re: Exported resources
Whoops, .jsp files are not candidates for private resources, since the *container* must have access to them. But I stand by the gif/html/xml comment :^). Another candidate is property files (thanks to Stephen McConnell for reminding me), when used as default configuration. Bryan Atsatt wrote: Stanley M. Ho wrote: Hi Bryan, Bryan Atsatt wrote: Yes, I think we're getting close now :^) (By privileged reflection, you mean having permission to call AccessibleObject.setAccessible(true), right? If so, then we're back to the grant issue!) Yes. In this case, it's the ResourceBundle API calling it to retrieve ListResourceBundle, so it'll have the sufficient permissions to do that. Anyway, I think we should leave this issue aside for now. I still think we can provide private, (i.e. non-exported) resources which *are* available to the module classes, but to no class outside of it. Without using permissions. Remember this? private static class StackAccessor extends SecurityManager { public Class[] getStack() { return getClassContext(); } } private static final STACK_ACCESSOR = new StackAccessor(); If a resource is found, and is not-exported, a module class loader can use this (or similar) to get the immediate caller's class (at a fixed index). If the caller class' Module does not match that for the loader, we don't return the resource. I think we should step back to rethink the use cases a bit. Typically, a module calls some APIs (e.g. ResourceBundle, AWTToolkit, etc.) and these APIs might then retrieve resources through the module's ClassLoader.getResource*(). If we are saying that a module is required to make these resources exported in order for these use cases to work, then what are the actual use cases we want to support by hiding resources from getResource*()? I think there remains a common use case where hiding resources would be a good thing if developers want to hide all the resources that are not used by anyone through ClassLoader.getResource*() (e.g. all the .class files). On the other hand, I think the use case where the code in the module calls its own ClassLoader.getResource*() to retrieve private resources directly is not very common; If this is a rare use case, I don't think it makes sense to introduce this notion of private resources. If we are forcing developers to export resources for the common use cases (like ResourceBundle and ServiceLoader) anyway, then why not require them to export resources in other cases as well? It would help if there are some real use cases to support why it is important to have this notion of private resources. One very common use case comes from the EE world: web modules containing html/gif/xml/jsp files, all of which are implementation details. I would assume that most any app with a UI would have similar resources. - Stanley
Re: Exported resources
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
Re: Exported resources
Some feedback from an observer which may help: Bryan misses the need for extender model to load internal impl classes ala Bundle.loadClass in OSGi. You do not want to have to export the service impl class from a module. You want to hide the class from others' casual loading. However an extender bundle (e.g. ServiceLoader) will need to be able to load that class to make it instances of it available to others under the service interface class. Glyn Bryan Atsatt [EMAIL PROTECTED] wrote on 30/05/2007 21:21:36: I've been assuming that Module private resources should not be visible to *any* class outside of the module. Including ResourceBundle, or any other existing framework classes that do resource lookups (e.g. ServiceLoader, JSF, etc). If resources need to be visible to these existing classes, they must be exported. The very simple check I proposed (immediate caller) is sufficient to make this assertion. I believe your point is that if we used the permission model instead, it would become possible for a module to invoke an external class (e.g. ResourceBundle.getBundle()) and enable *it* to successfully load a private resource from the module. Aside from the permission *grant* mechanism this model would rely on, it is an entirely different model than that used for classes! (Though we haven't explicitly defined this in 294, it seems extremely unlikely that we will rely on permissions--none of the other access modes do so.) Such asymmetry is very disconcerting to me, and, I believe, just plain wrong... Consider that you could grant the ServiceLoader, for example, access to a resource that names a class that it could not instantiate. That class would have to be exported. I believe the resource should be as well. // Bryan Stanley M. Ho wrote: Hi Bryan, Those resource-related methods in ClassLoader can be called by anyone, including code that is part of the module, code that is from other modules, or code that is part of the platform libraries (e.g. ResourceBundle). The approach you described would require walking the stack to get the caller's Module, but the real issue is that it is difficult to determine who the actual caller is from the stack. Treating the immediate caller on the stack as the actual caller wouldn't be sufficient because the immediate caller could be called by someone else who is the one actually making the call. On the other hand, treating the originated caller on the stack as the actual caller would be the right semantic, but this is basically the same as the security permission approach. - Stanley Bryan Atsatt wrote: Both solutions require stack walking (unless there is some new implementation of the java security model I've not yet seen!). The permission check does much more work than is necessary here. Take a look at AccessController.checkPermission() to see what I mean. And actually there is a very simple API to get the stack, which I've used for years: private static class StackAccessor extends SecurityManager { public Class[] getStack() { return getClassContext(); } } private static final STACK_ACCESSOR = new StackAccessor(); Now the enclosing class can simply call STACK_ACCESSOR.getStack(). // Bryan Stanley M. Ho wrote: Hi Bryan, Bryan Atsatt wrote: 1. Definitely agree that resource search order should be identical to class search order. Glad to hear! 2. Using permissions to limit access to private resources seems like overkill to me. The prototype implemented this in a very simple fashion: a. If resource is exported, return it, else a. Get the caller's Module (get class from stack, get module from it) b. If callerModule == this, return resource, else return null. The issue is that this approach still requires stack walking and there is no public API in the SE platform that let you implement this. If stack walking is required for the check anyway, I think the security permission approach is better that it is implementable with the existing API in the SE platform. - Stanley Unless stated otherwise above: IBM United Kingdom Limited - Registered in England and Wales with number 741598. Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
Re: Exported resources
I don't think I'm missing anything, just looking at it from perhaps a different perspective :^) First, 294 will determine accessibility for non-exported classes. The assumption at the moment is that they will not be accessible to *any* class outside of the module. I do understand the value of a friend semantic; it would certainly be nice to grant certain frameworks special access. But, so far, that is not on the table for classes. And if we don't have it for classes, I can't see why we should have it for resources. // Bryan Glyn Normington wrote: Some feedback from an observer which may help: Bryan misses the need for extender model to load internal impl classes ala Bundle.loadClass in OSGi. You do not want to have to export the service impl class from a module. You want to hide the class from others' casual loading. However an extender bundle (e.g. ServiceLoader) will need to be able to load that class to make it instances of it available to others under the service interface class. Glyn *Bryan Atsatt [EMAIL PROTECTED]* wrote on 30/05/2007 21:21:36: I've been assuming that Module private resources should not be visible to *any* class outside of the module. Including ResourceBundle, or any other existing framework classes that do resource lookups (e.g. ServiceLoader, JSF, etc). If resources need to be visible to these existing classes, they must be exported. The very simple check I proposed (immediate caller) is sufficient to make this assertion. I believe your point is that if we used the permission model instead, it would become possible for a module to invoke an external class (e.g. ResourceBundle.getBundle()) and enable *it* to successfully load a private resource from the module. Aside from the permission *grant* mechanism this model would rely on, it is an entirely different model than that used for classes! (Though we haven't explicitly defined this in 294, it seems extremely unlikely that we will rely on permissions--none of the other access modes do so.) Such asymmetry is very disconcerting to me, and, I believe, just plain wrong... Consider that you could grant the ServiceLoader, for example, access to a resource that names a class that it could not instantiate. That class would have to be exported. I believe the resource should be as well. // Bryan Stanley M. Ho wrote: Hi Bryan, Those resource-related methods in ClassLoader can be called by anyone, including code that is part of the module, code that is from other modules, or code that is part of the platform libraries (e.g. ResourceBundle). The approach you described would require walking the stack to get the caller's Module, but the real issue is that it is difficult to determine who the actual caller is from the stack. Treating the immediate caller on the stack as the actual caller wouldn't be sufficient because the immediate caller could be called by someone else who is the one actually making the call. On the other hand, treating the originated caller on the stack as the actual caller would be the right semantic, but this is basically the same as the security permission approach. - Stanley Bryan Atsatt wrote: Both solutions require stack walking (unless there is some new implementation of the java security model I've not yet seen!). The permission check does much more work than is necessary here. Take a look at AccessController.checkPermission() to see what I mean. And actually there is a very simple API to get the stack, which I've used for years: private static class StackAccessor extends SecurityManager { public Class[] getStack() { return getClassContext(); } } private static final STACK_ACCESSOR = new StackAccessor(); Now the enclosing class can simply call STACK_ACCESSOR.getStack(). // Bryan Stanley M. Ho wrote: Hi Bryan, Bryan Atsatt wrote: 1. Definitely agree that resource search order should be identical to class search order. Glad to hear! 2. Using permissions to limit access to private resources seems like overkill to me. The prototype implemented this in a very simple fashion: a. If resource is exported, return it, else a. Get the caller's Module (get class from stack, get module from it) b. If callerModule == this, return resource, else return null. The issue is that this approach still requires stack walking and there is no public API in the SE platform that let you implement this. If stack walking is required for the check anyway, I think the security permission approach is better that it is implementable with the existing API in the SE platform. - Stanley / / /Unless stated otherwise above: IBM United Kingdom Limited - Registered
Re: Exported resources
I've been assuming that Module private resources should not be visible to *any* class outside of the module. Including ResourceBundle, or any other existing framework classes that do resource lookups (e.g. ServiceLoader, JSF, etc). If resources need to be visible to these existing classes, they must be exported. The very simple check I proposed (immediate caller) is sufficient to make this assertion. I believe your point is that if we used the permission model instead, it would become possible for a module to invoke an external class (e.g. ResourceBundle.getBundle()) and enable *it* to successfully load a private resource from the module. Aside from the permission *grant* mechanism this model would rely on, it is an entirely different model than that used for classes! (Though we haven't explicitly defined this in 294, it seems extremely unlikely that we will rely on permissions--none of the other access modes do so.) Such asymmetry is very disconcerting to me, and, I believe, just plain wrong... Consider that you could grant the ServiceLoader, for example, access to a resource that names a class that it could not instantiate. That class would have to be exported. I believe the resource should be as well. // Bryan Stanley M. Ho wrote: Hi Bryan, Those resource-related methods in ClassLoader can be called by anyone, including code that is part of the module, code that is from other modules, or code that is part of the platform libraries (e.g. ResourceBundle). The approach you described would require walking the stack to get the caller's Module, but the real issue is that it is difficult to determine who the actual caller is from the stack. Treating the immediate caller on the stack as the actual caller wouldn't be sufficient because the immediate caller could be called by someone else who is the one actually making the call. On the other hand, treating the originated caller on the stack as the actual caller would be the right semantic, but this is basically the same as the security permission approach. - Stanley Bryan Atsatt wrote: Both solutions require stack walking (unless there is some new implementation of the java security model I've not yet seen!). The permission check does much more work than is necessary here. Take a look at AccessController.checkPermission() to see what I mean. And actually there is a very simple API to get the stack, which I've used for years: private static class StackAccessor extends SecurityManager { public Class[] getStack() { return getClassContext(); } } private static final STACK_ACCESSOR = new StackAccessor(); Now the enclosing class can simply call STACK_ACCESSOR.getStack(). // Bryan Stanley M. Ho wrote: Hi Bryan, Bryan Atsatt wrote: 1. Definitely agree that resource search order should be identical to class search order. Glad to hear! 2. Using permissions to limit access to private resources seems like overkill to me. The prototype implemented this in a very simple fashion: a. If resource is exported, return it, else a. Get the caller's Module (get class from stack, get module from it) b. If callerModule == this, return resource, else return null. The issue is that this approach still requires stack walking and there is no public API in the SE platform that let you implement this. If stack walking is required for the check anyway, I think the security permission approach is better that it is implementable with the existing API in the SE platform. - Stanley
Re: Exported resources
Hey Stanley, Sorry to be generating so much traffic while you're traveling! I'm not in any rush here, so feel free to take your time responding... Stanley M. Ho wrote: Hi Bryan, A module can use the ResourceBundle API to retrieve resources from other resource modules, but it can also use the ResourceBundle API to retrieve resources from the (target) module itself. In the latter case, the resources are currently not required to be exported from the target module. I don't think we want to force a module to export its own private resources simply because it wants to use the ResourceBundle API in this case, would you agree? 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 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? Regarding there are differences in the access models between classes and resources, I also prefer symmetry if possible. However, the access model for classes and resources have always been different, and there are built-in JVM support for classes while there is none for resources, so it is unclear if we can completely eliminate this asymmetry after all. 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 - Stanley Bryan Atsatt wrote: I've been assuming that Module private resources should not be visible to *any* class outside of the module. Including ResourceBundle, or any other existing framework classes that do resource lookups (e.g. ServiceLoader, JSF, etc). If resources need to be visible to these existing classes, they must be exported. The very simple check I proposed (immediate caller) is sufficient to make this assertion. I believe your point is that if we used the permission model instead, it would become possible for a module to invoke an external class (e.g. ResourceBundle.getBundle()) and enable *it* to successfully load a private resource from the module. Aside from the permission *grant* mechanism this model would rely on, it is an entirely different model than that used for classes! (Though we haven't explicitly defined this in 294, it seems extremely unlikely that we will rely on permissions--none of the other access modes do so.) Such asymmetry is very disconcerting to me, and, I believe, just plain wrong... Consider that you could grant the ServiceLoader, for example, access to a resource that names a class that it could not instantiate. That class would have to be exported. I believe the resource should be as well. // Bryan