Community
Participate
Working Groups
I'm working in an environment where a Security Manager is already set. I get the following stack trace: java.lang.ClassCircularityError: org/eclipse/osgi/framework/internal/core/BundleCombinedPermissions$1 org.eclipse.osgi.framework.internal.core.BundleCombinedPermissions.elements(BundleCombinedPermissions.java:99) sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1219) sun.security.provider.PolicyFile.implies(PolicyFile.java:1166) java.security.ProtectionDomain.implies(ProtectionDomain.java:195) java.security.AccessControlContext.checkPermission(AccessControlContext.java:249) java.security.AccessController.checkPermission(AccessController.java:427) java.lang.SecurityManager.checkPermission(SecurityManager.java:532) java.lang.SecurityManager.checkRead(SecurityManager.java:871) java.util.zip.ZipFile.<init>(ZipFile.java:199) java.util.jar.JarFile.<init>(JarFile.java:132) java.util.jar.JarFile.<init>(JarFile.java:97) org.apache.catalina.loader.WebappClassLoader.openJARs(WebappClassLoader.java:1561) org.apache.catalina.loader.WebappClassLoader.findResourceInternal(WebappClassLoader.java:1792) org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1587) org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:856) org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1305) java.lang.ClassLoader.loadClass(ClassLoader.java:299) java.lang.ClassLoader.loadClass(ClassLoader.java:251) java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) org.eclipse.osgi.framework.internal.core.BundleCombinedPermissions.elements(BundleCombinedPermissions.java:99) sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1219) sun.security.provider.PolicyFile.implies(PolicyFile.java:1166) java.security.ProtectionDomain.implies(ProtectionDomain.java:195) java.security.AccessControlContext.checkPermission(AccessControlContext.java:249) java.security.AccessController.checkPermission(AccessController.java:427) java.lang.SecurityManager.checkPermission(SecurityManager.java:532) java.lang.SecurityManager.checkRead(SecurityManager.java:871) java.io.FileInputStream.<init>(FileInputStream.java:100) org.eclipse.core.internal.registry.TableReader.openInputFile(TableReader.java:85) org.eclipse.core.internal.registry.TableReader.<init>(TableReader.java:79) org.eclipse.core.internal.registry.RegistryObjectManager.load(RegistryObjectManager.java:304) org.eclipse.core.internal.registry.RegistryObjectManager.basicGetObject(RegistryObjectManager.java:186) org.eclipse.core.internal.registry.RegistryObjectManager.getObject(RegistryObjectManager.java:178) org.eclipse.core.internal.registry.ExtensionHandle.getExtension(ExtensionHandle.java:26) org.eclipse.core.internal.registry.ExtensionHandle.getConfigurationElements(ExtensionHandle.java:57) ... -- Here's BundleCombinedPermissions.elements() declaration public Enumeration elements() { // TODO return an empty enumeration for now; // It does not seem possible to do this properly with multiple exports and conditional permissions. return new Enumeration() { public boolean hasMoreElements() { return false; } public Object nextElement() { throw new NoSuchElementException(); } }; } I think the problem might be the timing of when the empty enumeration class is defined. To change the timing perhaps we could define a static member to hold the empty enumeration. e.g. something like private static final Enumeration EMPTY_ENUMERATION = new Enumeration() { public boolean hasMoreElements() { return false; } public Object nextElement() { throw new NoSuchElementException(); } ... and then return this when elements() is called. In this way the Enumeration is defined when BundleCombinedPermissions is defined instead of when elements() is called. What do you think? I can put together a quick patch.
Created attachment 31051 [details] adds EMPTY_ENUMERATION constant for elements() to return
yup, it looks to be caused by the inner class being loaded recursively, causing the circularity error. We had a very similar issue in the implementation of the FrameworkSecurityManager. To solve it there we forced the loading of the inner classes in a static block. I assume this patch solves the problem in your env Simon? But I'm confused by the the following part of the stacktrace sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1219) sun.security.provider.PolicyFile.implies(PolicyFile.java:1166) java.security.ProtectionDomain.implies(ProtectionDomain.java:195) java.security.AccessControlContext.checkPermission (AccessControlContext.java:249) The only way this can occur is if the ProtectionDomain has non-static permissions. But the fwk only creates ProtectionDomains with static permissions (the permissions are actually dynamic, but are controled by the permission collection not the domain) so the PolicyFile should never get delegated to unless the security check is being done as a result of fwk code. But then the permission collection could not be of type BundleCombinedPermissions. Simon, if you could provide any insite to this I would appriciate it. In any event I think your solution to the problem is acceptable, and heck it is even a performace enhancement :) I will release the patch.
[contributed patch applied] Fixed in HEAD for 3.2 M4
Hmm... good question. A quick bit of extra info... The rest of the stack shows an incoming call through the app server. Also, I suspect the WebAppClassLoader's ProtectionDomain uses policy (and adds a few other file read permissions) Any way... I know that still doesn't really explain how the BundleCombinedPermissions got in there but I think it's very possible that we're looking at the magic of AccessControlContext optimization and the DomainCombiner.
adding "contributed" keyword to patches contributed by the community.