Question

Is it possible in OSGi to keep bundle wirings even across restarts of the system where even if now there's a new, higher version available we stay with the old one? The point is that if something works we don't want to risk it by wiring the old bundles to the new dependency. In other words, we are trying to isolate updates as much as possible so that an update in a component doesn't affect AT ALL other components (since the old bundles will still be used to satisfy already-wired dependencies)

As an example, let's say A depends on B with range [1.0.0, 2.0.0). We deploy version 1.0.0 of B so now A is wired to B_1.0.0
Now we create a bundle C that depends on a logic change so it depends on B with a range [1.0.1, 2.0.0). So we deploy B_1.0.1. Now if we restart the system, C and A will be wired to 1.0.1 since it is in the dependency range of both and it is in theory a "better" match for A than 1.0.0. Is there any way to tell OSGi to not do this and keep wirings as long as possible (say, until the old bundle is actually removed, in which case it would be ok to go with the highest version in the range)

What we currently do is we disallow ranges, so dependencies are like [1.0.0, 1.0.0]. This gives us the update isolation we want but at the cost that we basically lose modularity; to update a dependency we need to update the dependents even if the code in the dependents didn't change. I think it is a huge anti-pattern to disallow ranges so i'm trying to propose a better alternative with ranges but that would give the update isolation that we need and my first idea is to disallow rewirings even across sessions

If it matters, we are not using OSGi services. They are all plain bundles

Was it helpful?

Solution

The answer to the question in the first paragraph is simply: yes, this is the default behaviour of OSGi. If you stop and restart the framework without performing any bundle updates or package refresh operations, then the wiring state will be the same next time you start.

However you change things in the second paragraph. You now have 2 exports of B with different versions, and both A and C depend on it, with non-identical but overlapping ranges. The overlap is the key here. OSGi always tries to minimise the number of independent exports of the same package, so if you have two bundles importing with overlapping ranges then the framework will try to wire them to the same version rather than two separate versions. The version that falls within the overlap here is 1.0.1 so both A and C will wire to 1.0.0.

You should not try to change this. If bundle A is actually compatible with the range [1.0.0, 2.0.0) then why would you oppose it being wired to version 1.0.1?? On the other hand if A is really only compatible with version 1.0.0 and not 1.0.1, then you should specify a very tight range, i.e. [1.0.0, 1.0.1).

Finally... your last paragraph makes me sad. Plain bundles use services!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top