Home » Eclipse Projects » Equinox » How To Avoid Classloader Activating all Bundles?
How To Avoid Classloader Activating all Bundles? [message #111168] |
Fri, 30 May 2008 22:02 |
Mark Melvin Messages: 118 Registered: July 2009 |
Senior Member |
|
|
Hi There,
I have been using a custom classloader for quite some time with a Jython=
=
plug-in I wrote for scripting purposes. This is needed (as far as I can=
=
tell) for Jython to find and load classes from OSGi bundles. However, =
when debugging an issue today I noticed that my classloader seemed to be=
=
causing *all* bundles on its search path (I don't search *all* bundles -=
I =
have an ignore list) to be started. Naturally this is really bad...
Debugging this issue a bit, I found this hunk of code in BundleHost.java=
:
try {
return (loader.loadClass(name));
} catch (ClassNotFoundException e) {
// this is to support backward compatibility in eclipse
// we always attempted to start a bundle even if the class was not fo=
und
if (!(e instanceof StatusException) && (bundledata.getStatus() & =
Constants.BUNDLE_LAZY_START) !=3D 0 && =
!testStateChanging(Thread.currentThread()))
try {
// only start the bundle if this is a simple CNFE
framework.secureAction.start(this, START_TRANSIENT);
} catch (BundleException be) {
framework.adaptor.getFrameworkLog().log(new =
FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, =
FrameworkLogEntry.WARNING, 0, be.getMessage(), 0, be, null));
}
throw e;
}
So, it appears that if a class is not found the bundle is always started=
! =
Is this not defeating the whole purpose of the lazy activation mechanism=
? =
I realize I am the one that cause the CNFE, but I really don't know of a=
ny =
other way to accomplish what I need to do. I guess I could not query th=
e =
bundle if it is not active, but then I won't be able to resolve anything=
=
from bundles that have not yet been activated/started by the workbench.=
=
This is a drag too.
So I guess my question is, is there a way to write a classloader that =
looks for a class in all bundles *without causing all bundles to be =
started*? Basically what I am doing now is this:
Bundle[] loaders =3D getPluginBundles();
if (loaders !=3D null) {
for (int i =3D 0; (i < loaders.length) && (result =3D=3D nu=
ll); i++) =
{
try {
result =3D loaders[i].loadClass(name);
break;
} catch (ClassNotFoundException e) {
// Ignore exception now. If necessary we'll throw
// a ClassNotFoundException caller.
}
}
}
return result;
(The method getPluginBundles() calls =
<mybundle>.getBundleContext().getBundles(), runs them through my ignore =
=
list, and caches the result.)
Thanks,
Mark.
|
|
|
Re: How To Avoid Classloader Activating all Bundles? [message #111189 is a reply to message #111168] |
Fri, 30 May 2008 22:20 |
Mark Melvin Messages: 118 Registered: July 2009 |
Senior Member |
|
|
I just noticed that checking if the bundle is active before trying to lo=
ad =
from it isn't as bad as I thought as <<LAZY>> bundles seem to be ACTIVE=
, =
but I do get a class loading failure for bundles in the RESOLVED state. =
=
Is there anything else I can do here?
(Oh, and I fixed the bug in my originally-posted code... ;-)
Mark.
On Fri, 30 May 2008 18:02:13 -0400, Mark Melvin <mark.melvin@onsemi.com>=
=
wrote:
> Hi There,
>
> I have been using a custom classloader for quite some time with a Jyth=
on =
> plug-in I wrote for scripting purposes. This is needed (as far as I c=
an =
> tell) for Jython to find and load classes from OSGi bundles. However,=
=
> when debugging an issue today I noticed that my classloader seemed to =
be =
> causing *all* bundles on its search path (I don't search *all* bundles=
- =
> I have an ignore list) to be started. Naturally this is really bad...=
>
> Debugging this issue a bit, I found this hunk of code in BundleHost.ja=
va:
>
> try {
> return (loader.loadClass(name));
> } catch (ClassNotFoundException e) {
> // this is to support backward compatibility in eclipse
> // we always attempted to start a bundle even if the class was not =
=
> found
> if (!(e instanceof StatusException) && (bundledata.getStatus() & =
> Constants.BUNDLE_LAZY_START) !=3D 0 && =
> !testStateChanging(Thread.currentThread()))
> try {
> // only start the bundle if this is a simple CNFE
> framework.secureAction.start(this, START_TRANSIENT);
> } catch (BundleException be) {
> framework.adaptor.getFrameworkLog().log(new =
> FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, =
> FrameworkLogEntry.WARNING, 0, be.getMessage(), 0, be, null));
> }
> throw e;
> }
>
> So, it appears that if a class is not found the bundle is always =
> started! Is this not defeating the whole purpose of the lazy activati=
on =
> mechanism? I realize I am the one that cause the CNFE, but I really =
> don't know of any other way to accomplish what I need to do. I guess =
I =
> could not query the bundle if it is not active, but then I won't be ab=
le =
> to resolve anything from bundles that have not yet been =
> activated/started by the workbench. This is a drag too.
>
> So I guess my question is, is there a way to write a classloader that =
=
> looks for a class in all bundles *without causing all bundles to be =
> started*? Basically what I am doing now is this:
>
> Bundle[] loaders =3D getPluginBundles();
> if (loaders !=3D null) {
> for (int i =3D 0; (i < loaders.length) && (result =3D=3D =
null); =
> i++) {
> try {
> result =3D loaders[i].loadClass(name);
> break;
> } catch (ClassNotFoundException e) {
> // Ignore exception now. If necessary we'll throw=
> // a ClassNotFoundException caller.
> }
> }
> }
> return result;
>
> (The method getPluginBundles() calls =
> <mybundle>.getBundleContext().getBundles(), runs them through my ignor=
e =
> list, and caches the result.)
>
> Thanks,
> Mark.
|
|
|
Re: How To Avoid Classloader Activating all Bundles? [message #111326 is a reply to message #111189] |
Mon, 02 June 2008 15:43 |
Mark Melvin Messages: 118 Registered: July 2009 |
Senior Member |
|
|
Actually, after having looked at this for awhile I think I can be much =
smarter about caching which bundles contribute which packages, and filte=
r =
my classloading attempts that way. It should avoid the activations and =
=
speed things up considerably.
Mark.
On Fri, 30 May 2008 18:20:33 -0400, Mark Melvin <mark.melvin@onsemi.com>=
=
wrote:
> I just noticed that checking if the bundle is active before trying to =
=
> load from it isn't as bad as I thought as <<LAZY>> bundles seem to be=
=
> ACTIVE, but I do get a class loading failure for bundles in the RESOLV=
ED =
> state. Is there anything else I can do here?
>
> (Oh, and I fixed the bug in my originally-posted code... ;-)
>
> Mark.
>
>
> On Fri, 30 May 2008 18:02:13 -0400, Mark Melvin <mark.melvin@onsemi.co=
m> =
> wrote:
>
>> Hi There,
>>
>> I have been using a custom classloader for quite some time with a =
>> Jython plug-in I wrote for scripting purposes. This is needed (as fa=
r =
>> as I can tell) for Jython to find and load classes from OSGi bundles.=
=
>> However, when debugging an issue today I noticed that my classloader =
=
>> seemed to be causing *all* bundles on its search path (I don't search=
=
>> *all* bundles - I have an ignore list) to be started. Naturally this=
=
>> is really bad...
>>
>> Debugging this issue a bit, I found this hunk of code in =
>> BundleHost.java:
>>
>> try {
>> return (loader.loadClass(name));
>> } catch (ClassNotFoundException e) {
>> // this is to support backward compatibility in eclipse
>> // we always attempted to start a bundle even if the class was not=
=
>> found
>> if (!(e instanceof StatusException) && (bundledata.getStatus() & =
>> Constants.BUNDLE_LAZY_START) !=3D 0 && =
>> !testStateChanging(Thread.currentThread()))
>> try {
>> // only start the bundle if this is a simple CNFE
>> framework.secureAction.start(this, START_TRANSIENT);
>> } catch (BundleException be) {
>> framework.adaptor.getFrameworkLog().log(new =
>> FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, =
>> FrameworkLogEntry.WARNING, 0, be.getMessage(), 0, be, null));
>> }
>> throw e;
>> }
>>
>> So, it appears that if a class is not found the bundle is always =
>> started! Is this not defeating the whole purpose of the lazy =
>> activation mechanism? I realize I am the one that cause the CNFE, bu=
t =
>> I really don't know of any other way to accomplish what I need to do.=
=
>> I guess I could not query the bundle if it is not active, but then I =
=
>> won't be able to resolve anything from bundles that have not yet bee=
n =
>> activated/started by the workbench. This is a drag too.
>>
>> So I guess my question is, is there a way to write a classloader that=
=
>> looks for a class in all bundles *without causing all bundles to be =
>> started*? Basically what I am doing now is this:
>>
>> Bundle[] loaders =3D getPluginBundles();
>> if (loaders !=3D null) {
>> for (int i =3D 0; (i < loaders.length) && (result =3D=3D=
null); =
>> i++) {
>> try {
>> result =3D loaders[i].loadClass(name);
>> break;
>> } catch (ClassNotFoundException e) {
>> // Ignore exception now. If necessary we'll thro=
w
>> // a ClassNotFoundException caller.
>> }
>> }
>> }
>> return result;
>>
>> (The method getPluginBundles() calls =
>> <mybundle>.getBundleContext().getBundles(), runs them through my igno=
re =
>> list, and caches the result.)
>>
>> Thanks,
>> Mark.
>
|
|
| | |
Re: How To Avoid Classloader Activating all Bundles? [message #111460 is a reply to message #111438] |
Tue, 03 June 2008 19:02 |
Eclipse User |
|
|
|
Originally posted by: erdal.karaca.airbus.com
Did you visit the link provided? - You may find the general purpose
solution ;-)
https://bugs.eclipse.org/bugs/show_bug.cgi?id=232271
Mark Melvin wrote:
> Hi Erdal,
> Thanks for the reply, but I am a little confused as to the particular
> problem you were experiencing. You are in control of when you create
> objects with createExecutableExtension so can you not just create simple
> proxy objects with a reference to the IConfigurationElement of interest
> when you read the extension registry, and only call
> createExecutableExtension when necessary (i.e. on demand and "lazy")? Or
> were you trying to come up with a more general-purpose solution to this?
> Mark.
|
|
| |
Goto Forum:
Current Time: Mon Sep 23 06:31:29 GMT 2024
Powered by FUDForum. Page generated in 0.04156 seconds
|