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!