Community
Participate
Working Groups
We're using org.eclipse.osgi 3.15.300 Equinox OSGi runtime for our OSGi based application. We want to load resources from a fragment but the EquinoxClassLoader returns the wrong resource content due to a coding error in org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalEntry(String, ClasspathEntry[], int, int[]) To reproduce consider the following construct with some bundle and a fragment attached to it. I will only list here the parts that cause the issue: Bundle-SymbolicName: some.bundle Bundle-ClassPath: ., lib/resource.jar $ jar tf lib/resource.jar META-INF/services/some.bundle.Factory Now the fragment: Bundle-SymbolicName: some.fragment Fragment-Host: some.bundle Bundle-ClassPath: ., lib/resource.jar $ jar tf lib/resource.jar META-INF/services/some.bundle.Factory Both files some.bundle.Factory in both resource.jar have different content. Getting the URLs for the resource 'META-INF/services/some.bundle.Factory' works as expected and the result is something like the following: bundleresource://16.fwk1625901537/META-INF/services/some.bundle.Factory bundleresource://16.fwk1625901537:2/META-INF/services/some.bundle.Factory Doing then 'url.openStream()' on both URLs results then in two times the content of the file from the bundle and not one from the bundle and one from the fragment. The reason for that is a coding error in org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalEntry(String, ClasspathEntry[], int, int[]) This method is called for the second URL with parameters - /META-INF/services/some.bundle.Factory - ClasspathEntry[] contains the . classpath and lib/resource.jar of the BUNDLE - classPathIndex: 2 - currIndex[0]: 0 This is the call to the method for the bundle classpath entries and not for the fragment classpath entries. 'result = cpEntry.findEntry(path)' finds an entry and result gets the value of ZipBundleEntry of the lib/resource.jar of the bundle. In the following if statement the classPathIndex does not match. After having both classpath entries of the bundle iterated the execution reaches the last line of the method and result still has the ZipBundleEntry value, which is then return although null should have been returned as the classPathIndex didn't match. Essential for this behaviour is, that the resource.jar in the Bundle-Classpath entry is the last entry. Then the behavior of the ClasspathManager.findLocalEntry() method is wrong and it returns a found result (due to same name) but with wrong classPathIndex. To fix this issue, the last line of the method should be return null;
Our workaround is now to have the lib/resource.jar Bundle-Classpath entry not to be the last entry but instead the '.' entry.
org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalResourceImpl(String, ClasspathEntry[], Module, int, int[]) has last line reading return null;
This is a regression introduced by the fix in bug 537701.
New Gerrit change created: https://git.eclipse.org/r/c/equinox/rt.equinox.framework/+/166901
Gerrit change https://git.eclipse.org/r/c/equinox/rt.equinox.framework/+/166901 was merged to [master]. Commit: http://git.eclipse.org/c/equinox/rt.equinox.framework.git/commit/?id=16056e80642d4dc9708672243c05b3917b764ecd