views:

36

answers:

1

I'm learning OSGi and I'm curious about the following situation:

I want to change (extend mostly) an interface exposed by OSGi, without changing the classname. Is it possible make a bundle that "translates" the old interface to the new.

Below is an example, I hope it is clear enough, just by making use of a few manifest headers. Suppose I have these OSGI bundles:

Bundle-Name: Example Iface1 Implementation
Import-Package: org.osgi.framework
Export-Package: example.interfaces;version="1.0"

Bundle-Name: Example Iface1 User
Import-Package: org.osgi.framework, example.interfaces;version="1.0"

But then I need to update the exposed interface(s). The interface classnames stay the same, but there is functionality added to them. So I create:

Bundle-Name: Example Iface2 Implementation
Import-Package: org.osgi.framework
Export-Package: example.interfaces;version="2.0"

Can I make a bunlde like this to translate the new interface to the old for bundles that need it?

Bundle-Name: Interface Translator
Import-Package: org.osgi.framework, example.interfaces;version="2.0"
Export-Package: example.interfaces;version="1.0"

Because in this case I have no idea how to do the imports in java...

Or is there a much better way to do deal with this situation in OSGi?

+1  A: 

There is no need to do this, but you do need to specify your versions correctly.

Your first version of the bundle exports "example.interfaces" version 1.0. This is fine. The user bundle should import version "[1.0, 2.0)". In other words, 1.0 up to but not including version 2.0.

Now you say you want to add some methods to the interfaces. This kind of change is backwards-compatible for consumers of the interface but not for producers. The way to indicate this kind of change is to bump the second part of the version, i.e, the "minor" segment. So your updated interfaces bundle should export "example.interfaces" version 1.1.

Now your new version of the interface can be used directly by the user bundle because 1.1 falls within the range [1.0, 2.0). There is no need to export the same interface as 1.0 -- in fact you MUST not do this, because that would imply the interface has not changed. But it has changed, in a backwards incompatible way for producers.

For example, suppose you have a producer bundle that implements the original interface. It should use the following import range: [1.0, 1.1). That bundle must NOT see the updated interface because it would not be able to implement the new methods, and indeed it will not see the updated interface because 1.1 is outside of the range [1.0, 1.1). If you write a new producer that supports the updated interface it must use the range [1.1, 1.2).

Please read the OSGi Semantic Versioning paper (PDF warning) for more details of how to specify your export versions and import ranges.

Neil Bartlett