On Mon, Sep 27, 2010 at 4:56 AM, Glyn Normington <
gnormington@xxxxxxxxxx<mailto:
gnormington@xxxxxxxxxx>> wrote:
Hi Dmitry
"delegate instanceof BundleLoader" is of course the _expression_ to probe.
You observe in the debugger that delegate is an instance of BundleLoader, but the big question is whether this is the same BundleLoader runtime type that package admin sees.
Use the debugger (while in the stack frame for getBundle) to evaluate the following expressions.
delegate.getClassLoader.loadClass("org.eclipse.osgi.internal.loader.BundleLoader")
and
this.getClass.getClassLoader.loadClass("org.eclipse.osgi.internal.loader.BundleLoader")
If the expressions yield distinct class instances, then that will be why the instanceof is failing and you'll need to try to determine why those are distinct. Read on.
BundleLoader.class.getClassLoader will return Equinox's class loader which is the JRE's application class loader, as you observe. Next, take a look at:
delegate.getClassLoader.loadClass("org.eclipse.osgi.internal.loader.BundleLoader").getClassLoader
to get the defining class loader of that instance of the BundleLoader class.
(If the expressions yield the same class instance, then I cannot explain why the instanceof is failing, but will think harder if that turns out to be the case!)
Hope that helps!
Regards,
Glyn
On 24 Sep 2010, at 19:56, Dmitry Sklyut wrote:
Glyn,
I finally got time to dig into this. Here is what I see (a bit mind numbing btw)
I have a logback.xml in the root of the bundle.
I make a call to LoggerFactory.getLog("someLog").info(....).
This call finally gets to org.eclipse.virgo.medic.log.impl.StandardCallingBundleResolver.getCallingBundle().
That internally figures out the first stack frame that is not from logging packages and tries to figure out the bundle that loaded that by calling into:
packageAdmin.getBundle(loggingCallersClass);
In packageAdmin (equinox impl):
// code from the getBundle().
Bundle getBundlePriv(Class clazz) {
ClassLoader cl = clazz.getClassLoader();
if (cl instanceof BundleClassLoader) {
ClassLoaderDelegate delegate = ((BundleClassLoader) cl).getDelegate();
if (delegate instanceof BundleLoader)
return ((BundleLoader) delegate).getBundle();
}
if (cl == getClass().getClassLoader())
return framework.systemBundle;
return null;
}
This is where fun starts. The check for "if (delegate instanceof BundleLoader)" always returns "false"...
The classloader for the class passed into packageAdmin.getBundle() is KernelBundleClassLoader: [bundle=my.bundle.this.or.that_1.2.0.BUILD-SNAPSHOT]
This passes first check "if (cl instanceof BundleClassLoader)".
delegate: my.bundle.this.or.that_1.2.0.BUILD-SNAPSHOT and looking in debugger is of type org.eclipse.osgi.internal.loader.BundleLoader
Classloaders for both my class and delegate are identical instances of org.eclipse.virgo.userregion.internal.equinox.KernelBundleClassLoader. Both reference object id 171 (from debugger info).
But evaluating this chunk of code: BundleLoader.class.getClassLoader() results in sun.misc.Launcher$AppClassLoader@1f7182c1
Not sure who is right here and how to address this. Maybe try FrameworkUtils.getBundle()???
Any thoughts on how to start tackling this?
Regards,
Dmitry