Bug 119069 - ClassCircularityError in BundleCombinedPermission
Summary: ClassCircularityError in BundleCombinedPermission
Status: RESOLVED FIXED
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: Framework (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2 M4   Edit
Assignee: Thomas Watson CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed
Depends on:
Blocks:
 
Reported: 2005-12-02 12:38 EST by Simon Kaegi CLA
Modified: 2006-08-23 15:20 EDT (History)
0 users

See Also:


Attachments
adds EMPTY_ENUMERATION constant for elements() to return (1.61 KB, patch)
2005-12-02 13:04 EST, Simon Kaegi CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Kaegi CLA 2005-12-02 12:38:40 EST
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.
Comment 1 Simon Kaegi CLA 2005-12-02 13:04:50 EST
Created attachment 31051 [details]
adds EMPTY_ENUMERATION constant for elements() to return
Comment 2 Thomas Watson CLA 2005-12-02 16:47:32 EST
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.
Comment 3 Thomas Watson CLA 2005-12-02 17:00:52 EST
[contributed patch applied]
Fixed in HEAD for 3.2 M4
Comment 4 Simon Kaegi CLA 2005-12-03 18:40:18 EST
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.



Comment 5 Thomas Watson CLA 2006-08-23 15:20:17 EDT
adding "contributed" keyword to patches contributed by the community.