Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 333189 - Provide bundle install hook
Summary: Provide bundle install hook
Status: CLOSED WONTFIX
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: Framework (show other bugs)
Version: 3.7   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: equinox.framework-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 333667
Blocks: 330776 333193
  Show dependency tree
 
Reported: 2010-12-24 07:13 EST by Glyn Normington CLA
Modified: 2011-02-02 17:14 EST (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 Glyn Normington CLA 2010-12-24 07:13:51 EST
While changing Virgo to implement its region support in terms of framework hooks rather than composite bundles, the need for a bundle install hook has become apparent. There are two specific requirements.

FAIL INSTALL REQUIREMENT

When the framework property org.osgi.framework.bsnversion is set to "multiple" and multiple bundles are installed with a given bundle symbolic name and bundle version, a new location must be provided in order to create a new Bundle instance. If the same location is used, then the existing Bundle instance is returned, regardless of any filtering being performed by the bundle find hook.

This has some downsides for scenarios in which the framework hooks are attempting to provide isolation between "regions" of a framework. A region in this context is simply a set of bundles.

Consider an application running in a region R. Suppose a bundle B is installed with a given location in another region S. Suppose also that the bundle find hook filters out bundle B (in region S) from region R. Then the application cannot see bundle B when it lists all bundles. However, suppose the application
installs bundle B using the same given location. The install succeeds and the existing Bundle the region S is returned.

The application may then wrongly assume that B is available for use in region R.

There are a couple of workarounds, but these require code in the application.

The requirement on an install hook is to fail the install in cases like the one above.

DETERMINE INSTALLING BUNDLE REQUIREMENT

An install hook is necessary to determine the target region when a bundle is installed, particularly when this is outside the control of the region management code. For example, an application bundle running in the user region may use BundleContext.installBundle to create a bundle and it is important that the new bundle is installed in the same region as the application.

The current techniques for determining which region to install a bundle into depend on region contents being static. The other alternatives race-prone, e.g. tagging a bundle as belonging to a particular region can race with the find hook.

The install hook needs to be passed the bundle context of the "origin" bundle doing the install so the hook can determine into which region the bundle should be installed.

SUGGESTED INTERFACE

public interface BundleInstallHook {
    void event(Bundle origin, Bundle bundleBeingInstalled) throws BundleException;
}

package org.osgi.framework.hooks.bundle;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

/**
 * OSGi Framework Bundle Context Hook Service.
 * 
 * <p>
 * Bundles registering this service will be called during framework bundle install
 * operations.
 * 
 * @ThreadSafe
 */
public interface InstallHook {
	/**
	 * Install hook method. This method is called during the bundle install operation
	 * (for example, {@link BundleContext#installBundle(String) installBundle}) before the
         * bundle is added to the framework's collection of bundles.
         * This method can fail the install operation.
	 * 
	 * @param origin The bundle context of the bundle performing the install
	 *        operation.
	 * @param bundleBeingInstalled the bundle being installed
         * @throws BundleException if the install is to be failed
	 */
	void install(BundleContext origin, Bundle bundleBeingInstalled) throws BundleException;
}

BUNDLE LIFECYCLE HOOK

Although this enhancement is for a bundle install hook, it may be satisfied by a more general bundle lifecycle hook which could ultimately be standardised. OSGi Alliance members, please see OSGi bug 1839.

Alternatively, a bundle install hook could be implemented first and then generalised and possibly standardised later.

BUNDLE WATCHER

The existing BundleWatcher hook does not satisfy the above requirements. The origin is not passed to the hook and the hook cannot fail the install.
Comment 1 Glyn Normington CLA 2010-12-24 07:16:26 EST
Apologies for typos in the suggested interface. It should have read:

SUGGESTED INTERFACE

package org.osgi.framework.hooks.bundle;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

/**
 * OSGi Framework Bundle Context Hook Service.
 * 
 * <p>
 * Bundles registering this service will be called during framework bundle
 * install operations.
 * 
 * @ThreadSafe
 */
public interface InstallHook {
    /**
     * Install hook method. This method is called during the bundle install
     * operation
     * (for example, {@link BundleContext#installBundle(String) installBundle}) 
     * before the bundle is added to the framework's collection of bundles.
     * This method can fail the install operation.
     * 
     * @param origin The bundle context of the bundle performing the install
     *        operation.
     * @param bundleBeingInstalled the bundle being installed
     * @throws BundleException if the install is to be failed
     */
    void install(BundleContext origin, Bundle bundleBeingInstalled) throws
        BundleException;
}
Comment 2 Thomas Watson CLA 2011-01-04 10:34:19 EST
Some questions:

Does this hook get called for install operations that reuse an existing location where a bundle is already installed?  If so how does a hook know that the bundleBeingInstalled is an already installed Bundle or a newly installed Bundle?  I guess it could call BundleContext.getBundle(bundleBeingInstalled.getBundleId()) to see if it returns non-null, but even then the bundle find hook could have filtered out the bundle from the caller.

This brings up questions about leaking out Bundle objects before they are really installed.

- What is the state of such a bundle? INSTALLED seems strange.
- Is the bundle already added to the resolver state? Initial thought is no.
- Is the bundle state locked?  For example, you cannot call any methods that may change the state of the bundle (e.g. start, stop, uninstall etc.).  Initial thought is no lifecycle operations are allowed in the hook.

If we are going to consider this should we attempt to provide all the lifecycle hooks?  For example, start, stop, update, uninstall.  Keep in mind the install case is the only case where we can determine the origin BundleContext.

Should we consider passing BundleEvent objects instead of the bundleBeingInstalled for events that will be fired AND a hook may prevent by throwing a BundleException.  For example, the following events could be considered:

INSTALLED - This BundleEvent will return the origin bundle from BundleEvent.getOrigin()

STARTING
STOPPING
UPDATED
UNINSTALLED


This would make the proposed interface look like this:


package org.osgi.framework.hooks.bundle;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

/**
 * OSGi Framework Bundle Lifecycle Hook Service.
 * 
 * <p>
 * Bundles registering this service will be called during framework bundle
 * lifecycle operations.
 * 
 * @ThreadSafe
 */
public interface LifecycleHook {
    /**
     * Bundle Lifecycle hook method. This method is called during bundle 
     * lifecycle operations
     * (for example, {@link BundleContext#installBundle(String) installBundle}) 
     * before the bundle is added to the framework's collection of bundles.
     * This method can fail the lifecycle operation.
     * @param BundleEvent the event that will be fired if the operation succeeds
     * @throws BundleException if the operation is to be failed
     */
    void begin(BundleEvent bundleOperation) throws
        BundleException;
}


The begin method would be called for the following event types:

INSTALLED

Event type used during a BC.installBundle call.  The BundleEvent.getOrigin() would return the Bundle object of the BC used to call installBundle on.  The Bundle object is in the INSTALLED state but the bundle is not actually visible in the framework yet and no lifecycle operations may be performed.  

The only exception to this is if a bundle is already installed at the given location during the install operation.  (This last bit is strange since no BundleEvent would actually get fired in this case)

STARTING

Event type used just before calling the BundleActivator.start

STOPPING

Event type used just before calling the BundleActivator.stop

UNINSTALLED

Event type used during Bundle.uninstall.  The hook is called before any action is taken for the target bundle.  For example, if the bundle is active the hook is called before stopping the target bundle.  This allows a hook to fail the uninstall before the framework does any other lifecycle changes to the bundle.

UPDATED

Event type used during Bundle.update.  The hook is callec before any action is tagen for the target bundle.  For example, if the bundle is active the hook is called before stopping the target bundle.  This allows a hook to fail the update before the framework does any other lifecycle changes to the bundle.

This is quite awkward for update.  The hook will not have access to the new bundle content at all, it is just being informed about an existing bundle being updated.  Not sure if we need to provide an input stream or something else here.
Comment 3 Thomas Watson CLA 2011-01-04 10:39:35 EST
(In reply to comment #1)
> Apologies for typos in the suggested interface. It should have read:
> 
> SUGGESTED INTERFACE
> 
> package org.osgi.framework.hooks.bundle;

Since we are not going to add this to the OSGi specification for R4.3 a different package name would be required.
Comment 4 Glyn Normington CLA 2011-01-04 11:48:55 EST
(In reply to comment #2)
> Some questions:
> 
> Does this hook get called for install operations that reuse an existing
> location where a bundle is already installed?
Perhaps not. How about this?...

It may be better in this case if the bundle find hook is driven first.

If the bundle find hook filters out the bundle, then the install will fail with a bundle exception. The big question is how meaningful this exception can be made. The exception message would have to be something like "install cannot return existing bundle because the bundle find hook prevented this", which might be too cryptic.

If the bundle find hook does not filter out the bundle, then it is returned without driving the bundle install hook (since an install is not really happening).

> If so how does a hook know that
> the bundleBeingInstalled is an already installed Bundle or a newly installed
> Bundle?  I guess it could call
> BundleContext.getBundle(bundleBeingInstalled.getBundleId()) to see if it
> returns non-null, but even then the bundle find hook could have filtered out
> the bundle from the caller.

Hopefully we can avoid this. See above.

> 
> This brings up questions about leaking out Bundle objects before they are
> really installed.
> 
> - What is the state of such a bundle? INSTALLED seems strange.

Seems ok to me since only the lifecycle hook will see this.

> - Is the bundle already added to the resolver state? Initial thought is no.

Fair enough. Seems premature to add it before the hook has had a chance to fail the install.

> - Is the bundle state locked?  For example, you cannot call any methods that
> may change the state of the bundle (e.g. start, stop, uninstall etc.).  Initial
> thought is no lifecycle operations are allowed in the hook.

Sounds good.

> 
> If we are going to consider this should we attempt to provide all the lifecycle
> hooks?  For example, start, stop, update, uninstall.  Keep in mind the install
> case is the only case where we can determine the origin BundleContext.

Hmmm. We cannot standardise this with the OSGi Alliance until we have all the lifecycle events covered, but that seems a little premature in terms of the current use cases. So I think we should limit the implementation to those lifecycle events that will actually be used and thereby validated.

> 
> Should we consider passing BundleEvent objects instead of the
> bundleBeingInstalled for events that will be fired AND a hook may prevent by
> throwing a BundleException.

If the above suggestion works, we might be able to avoid the need for the hook to fail install. :-)

> For example, the following events could be
> considered:
> 
> INSTALLED - This BundleEvent will return the origin bundle from
> BundleEvent.getOrigin()
> 
> STARTING
> STOPPING
> UPDATED
> UNINSTALLED
> 
> 
> This would make the proposed interface look like this:
> 
> 
> package org.osgi.framework.hooks.bundle;
> 
> import org.osgi.framework.Bundle;
> import org.osgi.framework.BundleContext;
> 
> /**
>  * OSGi Framework Bundle Lifecycle Hook Service.
>  * 
>  * <p>
>  * Bundles registering this service will be called during framework bundle
>  * lifecycle operations.
>  * 
>  * @ThreadSafe
>  */
> public interface LifecycleHook {
>     /**
>      * Bundle Lifecycle hook method. This method is called during bundle 
>      * lifecycle operations
>      * (for example, {@link BundleContext#installBundle(String) installBundle}) 
>      * before the bundle is added to the framework's collection of bundles.
>      * This method can fail the lifecycle operation.
>      * @param BundleEvent the event that will be fired if the operation
> succeeds
>      * @throws BundleException if the operation is to be failed
>      */
>     void begin(BundleEvent bundleOperation) throws
>         BundleException;
> }
> 
> 
> The begin method would be called for the following event types:
> 
> INSTALLED
> 
> Event type used during a BC.installBundle call.  The BundleEvent.getOrigin()
> would return the Bundle object of the BC used to call installBundle on.  The
> Bundle object is in the INSTALLED state but the bundle is not actually visible
> in the framework yet and no lifecycle operations may be performed.  
> 
> The only exception to this is if a bundle is already installed at the given
> location during the install operation.  (This last bit is strange since no
> BundleEvent would actually get fired in this case)

This last paragraph goes away if the above suggestion works.

> 
> STARTING
> 
> Event type used just before calling the BundleActivator.start
> 
> STOPPING
> 
> Event type used just before calling the BundleActivator.stop
> 
> UNINSTALLED
> 
> Event type used during Bundle.uninstall.  The hook is called before any action
> is taken for the target bundle.  For example, if the bundle is active the hook
> is called before stopping the target bundle.  This allows a hook to fail the
> uninstall before the framework does any other lifecycle changes to the bundle.
> 
> UPDATED
> 
> Event type used during Bundle.update.  The hook is callec before any action is
> tagen for the target bundle.  For example, if the bundle is active the hook is
> called before stopping the target bundle.  This allows a hook to fail the
> update before the framework does any other lifecycle changes to the bundle.
> 
> This is quite awkward for update.  The hook will not have access to the new
> bundle content at all, it is just being informed about an existing bundle being
> updated.  Not sure if we need to provide an input stream or something else
> here.

Failing an update sounds really messy and I'm not sure we need it.
Comment 5 Glyn Normington CLA 2011-01-04 11:49:10 EST
(In reply to comment #3)
> (In reply to comment #1)
> > Apologies for typos in the suggested interface. It should have read:
> > 
> > SUGGESTED INTERFACE
> > 
> > package org.osgi.framework.hooks.bundle;
> 
> Since we are not going to add this to the OSGi specification for R4.3 a
> different package name would be required.

Agreed.
Comment 6 Thomas Watson CLA 2011-01-04 13:25:08 EST
(In reply to comment #4)
> (In reply to comment #2)
> > Some questions:
> > 
> > Does this hook get called for install operations that reuse an existing
> > location where a bundle is already installed?
> Perhaps not. How about this?...
> 
> It may be better in this case if the bundle find hook is driven first.
> 
> If the bundle find hook filters out the bundle, then the install will fail with
> a bundle exception. The big question is how meaningful this exception can be
> made. The exception message would have to be something like "install cannot
> return existing bundle because the bundle find hook prevented this", which
> might be too cryptic.
> 
> If the bundle find hook does not filter out the bundle, then it is returned
> without driving the bundle install hook (since an install is not really
> happening).

This seems reasonable.  Note that the find hooks would have to be driven by an equivalent call to BC.getBundle(long id) since BC.getBundle(String location) does not drive the find hooks.  If we decide this is the correct approach we should attempt have to have the R4.3 specification updated to reflect this behavior.

> 
> > 
> > If we are going to consider this should we attempt to provide all the lifecycle
> > hooks?  For example, start, stop, update, uninstall.  Keep in mind the install
> > case is the only case where we can determine the origin BundleContext.
> 
> Hmmm. We cannot standardise this with the OSGi Alliance until we have all the
> lifecycle events covered, but that seems a little premature in terms of the
> current use cases. So I think we should limit the implementation to those
> lifecycle events that will actually be used and thereby validated.

Should we attempt to make the hook API general by using a BundleEvent object as I suggest?  For now we can only spec the behavior for the INSTALLED case.

> 
> > 
> > Should we consider passing BundleEvent objects instead of the
> > bundleBeingInstalled for events that will be fired AND a hook may prevent by
> > throwing a BundleException.
> 
> If the above suggestion works, we might be able to avoid the need for the hook
> to fail install. :-)

I think it is inevitable that there will be cases where a hook wants to prevent an installation.  For example, a hook could be used to check that the bundle is trusted and fail the install if not.

> > 
> > UPDATED
> > 
> > Event type used during Bundle.update.  The hook is callec before any action is
> > tagen for the target bundle.  For example, if the bundle is active the hook is
> > called before stopping the target bundle.  This allows a hook to fail the
> > update before the framework does any other lifecycle changes to the bundle.
> > 
> > This is quite awkward for update.  The hook will not have access to the new
> > bundle content at all, it is just being informed about an existing bundle being
> > updated.  Not sure if we need to provide an input stream or something else
> > here.
> 
> Failing an update sounds really messy and I'm not sure we need it.

Yeah, update is messy.  I would like us to keep this case in mind when developing an API because we will eventually need to handle the update case.
Comment 7 Glyn Normington CLA 2011-01-05 03:34:00 EST
(In reply to comment #6)
> (In reply to comment #4)
> > (In reply to comment #2)
> > > Some questions:
> > > 
> > > Does this hook get called for install operations that reuse an existing
> > > location where a bundle is already installed?
> > Perhaps not. How about this?...
> > 
> > It may be better in this case if the bundle find hook is driven first.
> > 
> > If the bundle find hook filters out the bundle, then the install will fail with
> > a bundle exception. The big question is how meaningful this exception can be
> > made. The exception message would have to be something like "install cannot
> > return existing bundle because the bundle find hook prevented this", which
> > might be too cryptic.
> > 
> > If the bundle find hook does not filter out the bundle, then it is returned
> > without driving the bundle install hook (since an install is not really
> > happening).
> 
> This seems reasonable.  Note that the find hooks would have to be driven by an
> equivalent call to BC.getBundle(long id) since BC.getBundle(String location)
> does not drive the find hooks.  If we decide this is the correct approach we
> should attempt have to have the R4.3 specification updated to reflect this
> behavior.

Agreed.

> 
> > 
> > > 
> > > If we are going to consider this should we attempt to provide all the lifecycle
> > > hooks?  For example, start, stop, update, uninstall.  Keep in mind the install
> > > case is the only case where we can determine the origin BundleContext.
> > 
> > Hmmm. We cannot standardise this with the OSGi Alliance until we have all the
> > lifecycle events covered, but that seems a little premature in terms of the
> > current use cases. So I think we should limit the implementation to those
> > lifecycle events that will actually be used and thereby validated.
> 
> Should we attempt to make the hook API general by using a BundleEvent object as
> I suggest?  For now we can only spec the behavior for the INSTALLED case.

Seems reasonable.

> 
> > 
> > > 
> > > Should we consider passing BundleEvent objects instead of the
> > > bundleBeingInstalled for events that will be fired AND a hook may prevent by
> > > throwing a BundleException.
> > 
> > If the above suggestion works, we might be able to avoid the need for the hook
> > to fail install. :-)
> 
> I think it is inevitable that there will be cases where a hook wants to prevent
> an installation.  For example, a hook could be used to check that the bundle is
> trusted and fail the install if not.

Agreed.

> 
> > > 
> > > UPDATED
> > > 
> > > Event type used during Bundle.update.  The hook is callec before any action is
> > > tagen for the target bundle.  For example, if the bundle is active the hook is
> > > called before stopping the target bundle.  This allows a hook to fail the
> > > update before the framework does any other lifecycle changes to the bundle.
> > > 
> > > This is quite awkward for update.  The hook will not have access to the new
> > > bundle content at all, it is just being informed about an existing bundle being
> > > updated.  Not sure if we need to provide an input stream or something else
> > > here.
> > 
> > Failing an update sounds really messy and I'm not sure we need it.
> 
> Yeah, update is messy.  I would like us to keep this case in mind when
> developing an API because we will eventually need to handle the update case.

Fair enough.
Comment 8 Thomas Watson CLA 2011-01-06 11:15:50 EST
(In reply to comment #7)
> > This seems reasonable.  Note that the find hooks would have to be driven by an
> > equivalent call to BC.getBundle(long id) since BC.getBundle(String location)
> > does not drive the find hooks.  If we decide this is the correct approach we
> > should attempt have to have the R4.3 specification updated to reflect this
> > behavior.
> 
> Agreed.
> 

This was discussed in CPEG and agreed upon.  I am implementing it in bug333667.
Comment 9 Glyn Normington CLA 2011-01-07 11:44:31 EST
Please note that this bug is required for a complete solution to bug 330776. What is the likelihood of this making M5?
Comment 10 Thomas Watson CLA 2011-01-07 14:05:10 EST
(In reply to comment #9)
> Please note that this bug is required for a complete solution to bug 330776.
> What is the likelihood of this making M5?

I can take a look next week at this, but it is going to be tight for M5.  I want to make sure I understand the limitations without this feature.  If I understand correctly the current R4.3 API allows you to determine the region (BundleContext) for which a bundle install operation is originated from by using the new BundleEvent.getOrigin() method.

But you only get access to the BundeEvent.getOrigin() method by using a BundleListener and tracking the INSTALLED event.  The issue here is that the BundleEvent.INSTALLED event is fired after the actual Bundle object becomes available in the system (BC.getBundles(), resolver State etc.).  So there is a timing issue with using a BundleListener to automatically assign a bundle to a region because there will be a window of time where the bundle is available before you have had a chance to assign it to a region.  So in theory a resolution operation may occur before you have properly isolated the bundle in a region.
Comment 11 Glyn Normington CLA 2011-01-10 03:59:58 EST
(In reply to comment #10)
> (In reply to comment #9)
> > Please note that this bug is required for a complete solution to bug 330776.
> > What is the likelihood of this making M5?
> 
> I can take a look next week at this, but it is going to be tight for M5.  I
> want to make sure I understand the limitations without this feature.  If I
> understand correctly the current R4.3 API allows you to determine the region
> (BundleContext) for which a bundle install operation is originated from by
> using the new BundleEvent.getOrigin() method.
> 
> But you only get access to the BundeEvent.getOrigin() method by using a
> BundleListener and tracking the INSTALLED event.  The issue here is that the
> BundleEvent.INSTALLED event is fired after the actual Bundle object becomes
> available in the system (BC.getBundles(), resolver State etc.).  So there is a
> timing issue with using a BundleListener to automatically assign a bundle to a
> region because there will be a window of time where the bundle is available
> before you have had a chance to assign it to a region.  So in theory a
> resolution operation may occur before you have properly isolated the bundle in
> a region.

Yes, a resolution operation could observe that anomaly, but also the bundle find and event hooks could fail to operate correctly in that situation.

We could perhaps use a synchronous bundle listener as a temporary workaround, but this doesn't solve the problem - it merely reduces the size of the window. So I'm not inclined to waste time on it.
Comment 12 Thomas Watson CLA 2011-01-10 08:39:50 EST
(In reply to comment #11)
> We could perhaps use a synchronous bundle listener as a temporary workaround,
> but this doesn't solve the problem - it merely reduces the size of the window.
> So I'm not inclined to waste time on it.


I would not suggest the use of a synch bundle listener because this still has timing issues.  Instead I was going to suggest that your ResolverHook implementation to remove any revisions it is not aware of yet and does not know what region it belongs to in org.osgi.framework.hooks.resolver.ResolverHook.filterResolvable(Collection<BundleRevision>)

This would plug the hole for resolve operations.  It would also plug the hole for service operations since the bundle would not be able to start until after it is recognized by your resolver hook and allowed to resolve.  But it still has timing issues for bundle events and bundle find hooks.  Would could decide to "hide" the bundle from everything until your bundle listener recognizes the bundle.

A synch bundle listener may be able to help with that, but only if there are no synch bundle listeners registered from a region bundle that are ahead of your synch bundle listener.
Comment 13 Glyn Normington CLA 2011-01-10 08:50:15 EST
(In reply to comment #12)
> (In reply to comment #11)
> > We could perhaps use a synchronous bundle listener as a temporary workaround,
> > but this doesn't solve the problem - it merely reduces the size of the window.
> > So I'm not inclined to waste time on it.
> 
> 
> I would not suggest the use of a synch bundle listener because this still has
> timing issues.  Instead I was going to suggest that your ResolverHook
> implementation to remove any revisions it is not aware of yet and does not know
> what region it belongs to in
> org.osgi.framework.hooks.resolver.ResolverHook.filterResolvable(Collection<BundleRevision>)
> 
> This would plug the hole for resolve operations.  It would also plug the hole
> for service operations since the bundle would not be able to start until after
> it is recognized by your resolver hook and allowed to resolve.  But it still
> has timing issues for bundle events and bundle find hooks.  Would could decide
> to "hide" the bundle from everything until your bundle listener recognizes the
> bundle.
> 
> A synch bundle listener may be able to help with that, but only if there are no
> synch bundle listeners registered from a region bundle that are ahead of your
> synch bundle listener.

Yeah. Like I said, I'm not inclined to waste time on this workaround.
Comment 14 Glyn Normington CLA 2011-01-25 05:57:55 EST
This hook can be used to close the window in org.eclipse.virgo.kernel.osgi.region.internal.BundleIdBasedRegion. See the comments in that class which refer to this bug. The class is currently in Virgo kernel branch bug330776-framework-hooks.
Comment 15 Glyn Normington CLA 2011-02-02 00:07:25 EST
I'm starting to wonder if we can do without this hook.

As you suggested earlier, the bundle event hook could assign a bundle to the appropriate region *before* deciding which bundle listeners to drive. So the correct bundle listeners will be driven.

Also, my concern about a bundle "find" operation seeing the bundle after it is added to the framework but before it is assigned to a region can be worked around by the bundle find hook filtering out bundles which are not yet assigned to regions. Then this looks like the "find" operation won the race with the thread installing the bundle.

So I would like to understand if there are any callbacks to application code on the thread installing a bundle between the bundle being added to the framework and the bundle event hook being driven as such a callback could observe the bundle in the inconsistent state (of being present in the framework but not belonging to a region). Are there any such callbacks?

If not, can you think of any other holes in this approach? If not, I think we can close this bug (and re-open it if and when we find such a hole).
Comment 16 Glyn Normington CLA 2011-02-02 09:49:54 EST
BJ noted that another bundle find event hook would be such a hole, but this isn't an issue as such hooks are very specialised.

I replaced the synchronous bundle listener in Virgo with code in the bundle event hook and all the tests pass, so this bug is ripe for closing as soon as Tom confirms.
Comment 17 Thomas Watson CLA 2011-02-02 17:14:42 EST
(In reply to comment #16)
> BJ noted that another bundle find event hook would be such a hole, but this
> isn't an issue as such hooks are very specialised.
> 
> I replaced the synchronous bundle listener in Virgo with code in the bundle
> event hook and all the tests pass, so this bug is ripe for closing as soon as
> Tom confirms.

Yes, this is what I attempted to do in comment 10 and comment 12 ;-)  but I did not think of using the actual bundle event hook to get the INSTALLED event with the source for figuring out the region before firing the event to all the other listeners.  I think this is a good approach to go forward with.

I will close as wontfix.  Thanks Glyn!