Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 331454 - PackageAdmin.refreshPackages() refreshes all updated bundles, not only those in the export package graph
Summary: PackageAdmin.refreshPackages() refreshes all updated bundles, not only those ...
Status: RESOLVED FIXED
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: Framework (show other bugs)
Version: 3.6.1   Edit
Hardware: PC Windows XP
: P3 minor (vote)
Target Milestone: 3.7 M3   Edit
Assignee: equinox.framework-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-11-30 11:49 EST by KP CLA
Modified: 2010-12-01 08:22 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 KP CLA 2010-11-30 11:49:22 EST
Build Identifier: 3.6.1.R36x_v20100806

From the OSGi spec on PackageAdmin.refreshPackages(Bundle[] bundles):

"Forces the update (replacement) or removal of packages exported by the specified bundles."

and, if the bundles argument is not null:

"Compute a graph of bundles starting with the specified bundles" ... "Add to the graph any bundle that is wired to a package that is currently exported by a bundle in the graph. The graph is fully constructed when there is no bundle outside the graph that is wired to a bundle in the graph. "

As we understand it, conceptually a graph is built starting from the specified bundle, following the *exported* packages. This would mean that bundles the specified bundle imports from would not be taken into account.
(Of course, when the bundles argument is null, all changed bundles can be considered, as stated in the spec)


However, it seems that Equinox always considers ALL bundles that are updated since the last call -- which is not what the spec suggests. Also, Apache Felix seems to acts as documented in the spec, which is different than Equinox.

Reproducible: Always

Steps to Reproduce:
E.g. consider:
* bundleA : exports a package imported by bundle1 - no other imports/exports in both
* bundleB : exports a package imported by bundle2 - no other imports/exports in both

Scenario 1:
1. update bundleA
2. refresh bundle1
When trying this in Apache Felix, only bundle1 is restarted.
Now Equinox refreshes both bundleA and bundle1. However: bundle1 does NOT export to bundleA. Or, to use the terminology of the spec: bundleA is not wired to any package currently exported by a bundle in the graph (bundle1). It seems Equinox also follows relations in the other direction...?


Scenario 2:
1. update bundleA AND bundleB
2. refresh bundleA
In Apache Felix: bundleA and the dependent bundle1 are refreshed. Indeed, starting from bundleA, there's only a relation to bundle1
Now in Equinox, ALL bundles are refreshes. Yes, both bundleA and bundleB have been updated, but we explicitly specified 'refresh bundleA'. Starting from bundleA, there's never an export-package relation to bundleB and/or bundle2.

It seems Equinox always refreshes all bundles that have been updated since the last call... which is not what the spec. suggests, nor what Felix seems to do.
Comment 1 BJ Hargrave CLA 2010-11-30 13:00:38 EST
You will also note the spec says: "The technique by which this is accomplished may vary among different Framework implementations. One permissible implementation is to stop and restart the Framework." This means that it is compliant to refresh all bundles.

So I don't think you can argue a framework is not compliant if it refreshes more bundles than are necessary. It is not-compliant if it refreshes less bundles than are necessary. That is, the spec specifies the lower bound for the bundles to be refreshed, not the upper bound.

Thus I think Equinox complies properly with the spec here.
Comment 2 Thomas Watson CLA 2010-11-30 13:22:38 EST
I agree that this is not intuitive behavior.  I also agree with BJ that it is not in violation of the specification.  I noticed this odd behavior while working on bug326011.  The resolver was pulling in all removal pending bundles no matter what was passed to refreshPackages.  Now we only pull in all removal pending bundles when you pass null.

Please test out the latest 3.7 integration build.
Comment 3 KP CLA 2010-12-01 08:22:15 EST
(In reply to comment #1)
> You will also note the spec says: "The technique by which this is accomplished
> may vary among different Framework implementations. One permissible
> implementation is to stop and restart the Framework." This means that it is
> compliant to refresh all bundles.
> 
> So I don't think you can argue a framework is not compliant if it refreshes
> more bundles than are necessary. It is not-compliant if it refreshes less
> bundles than are necessary. That is, the spec specifies the lower bound for the
> bundles to be refreshed, not the upper bound.
> 
> Thus I think Equinox complies properly with the spec here.

Well, that's indeed where the spec seems a bit ambiguous. I know that it says something about the framework being free to choose its implementation (even allowing it to simply restart), BUT, that is only in the paragraph "If no bundles are specified,....". Which suggest this is only related to the cases where the bundles argument is null.

Or maybe not, but then this may be something that should be clarified by the OSGi Alliance (and made more clear in their spec, just to avoid confusion) ?

As T.Watson states in the previous comment, the behavior Equinox showed wasn't intuitive when reading the current spec. The current spec has an (extended) explanation based on the export-package relations, so it's strange that Equinox would do something different (i.e. have a number of undocumented/unspecified side-effects).