Bug 389408 - addingBundle method of BundleTracker class may cause lazy bundle activation to loop forever
Summary: addingBundle method of BundleTracker class may cause lazy bundle activation t...
Status: RESOLVED WORKSFORME
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: Framework (show other bugs)
Version: 3.6.2   Edit
Hardware: Other other
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: equinox.framework-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: needinfo
Depends on:
Blocks:
 
Reported: 2012-09-12 10:33 EDT by Ben Cox CLA
Modified: 2012-09-28 10:49 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ben Cox CLA 2012-09-12 10:33:43 EDT
Posted on behalf of a colleague.

if the implementation of addingBundle fails to load a bundle class (common case is when the class is not found), a loop is created which makes the bundle activation hang (with obvious severe consequences). I'm putting below an excerpt of Java traces showing the loop:
	
	...
	at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1207)
	at com.ibm.cics.osgi.impl.CICSMainProxy.<init>(CICSMainProxy.java:117)
	at com.ibm.cics.osgi.impl.CICSMainClassTracker$CICSMainClassBundleTracker.addingBundle(CICSMainClassTracker.java:459)
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:482)
	at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:1)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:262)
	at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:234)
	at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:457)
	at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
	at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
	at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
	at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEventPrivileged(Framework.java:1523)
	at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEvent(Framework.java:1459)
	at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEvent(Framework.java:1454)
	at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:356)
	at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299)
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:440)
	at org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:268)
	at org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:236)
	at org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1207)
	at com.ibm.cics.osgi.impl.CICSMainProxy.<init>(CICSMainProxy.java:117)
	at com.ibm.cics.osgi.impl.CICSMainClassTracker$CICSMainClassBundleTracker.addingBundle(CICSMainClassTracker.java:459)
	...

I realize that trying to load a class the first time addingBundle is called means to collapse the 2 activation phases of a lazy activation policy bundle and make it behave as a normal bundle. However we need to do that.
It looks like that addingBundle is called twice during the bundle activation: the first time when the bundle is moved to starting status and the second time when the class is loaded and the bundle is moving to activate; why is that?

I did some testing using addingBundle and modifiedBundle, and playing with the state and event that are passed as input parameters. However I couldn't find an easy fix to detect the second activation phase of the lazy bundle. It looks like modifiedBundle is never called and the reported status and event in each of the addingBundle calls are always 8 (STARTING) and 512 (LAZY_ACTIVATION) respectively.

For any information, please contact me at elisafla@uk.ibm.com or reply to this bug. I tried to open an account with this email address several times but it didn't work.
Thank you,
Elisabetta
Comment 1 BJ Hargrave CLA 2012-09-12 11:31:44 EDT
(In reply to comment #0)
> I realize that trying to load a class the first time addingBundle is called
> means to collapse the 2 activation phases of a lazy activation policy bundle
> and make it behave as a normal bundle. However we need to do that.
> It looks like that addingBundle is called twice during the bundle
> activation: the first time when the bundle is moved to starting status and
> the second time when the class is loaded and the bundle is moving to
> activate; why is that?

Because the bundle is not added yet. The method is *adding* not added. Until this method returns a non-null value, the bundle is not tracked. This method makes to decision to track the bundle.

> I did some testing using addingBundle and modifiedBundle, and playing with
> the state and event that are passed as input parameters. However I couldn't
> find an easy fix to detect the second activation phase of the lazy bundle.

In this cause, your customizer will need to keep track of the potential bundle being added to detect the recursive call. So you may need a Set to which you add the bundle on entry and remove on exit from addingBundle. If the add on entry indicates the bundle is already in the Set, you have recursed and should return null to allow the original call to regain control.

> It looks like modifiedBundle is never called and the reported status and
> event in each of the addingBundle calls are always 8 (STARTING) and 512
> (LAZY_ACTIVATION) respectively.

modifiedBundle wont be called unless addingBundle has returned a non-null value.

Finally, the BundleTracker code is from OSGi. Eclipse just reships it. So you should open bugs for OSGi code at https://www.osgi.org/bugzilla/
Comment 2 Thomas Watson CLA 2012-09-13 16:29:05 EDT
(In reply to comment #0)
> Posted on behalf of a colleague.
> 
> if the implementation of addingBundle fails to load a bundle class (common
> case is when the class is not found), a loop is created which makes the
> bundle activation hang (with obvious severe consequences). 

When you say hang, do you it endless recurses and ends up with a stack overflow?  Or does it literally hang in deadlock? or does it timeout after about 5 seconds with an exception?

At this line:

org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:236)

A check is done here to see if the current thread is in the process of activating the and it should not try to start the bundle again from the same thread.  It seems you are seeing it try to activate the same bundle recursively from the same thread.  If that is happening then it is an issue that should be addressed in equinox.  Do you have a reproducible testcase we can try?
Comment 3 Thomas Watson CLA 2012-09-28 10:49:32 EDT
Need more information to proceed here.  Please reopen when you respond to comment 2.