views:

130

answers:

4

Hi,

I am trying to get my head around OSGi Services. The main question I keep asking myself is: What's the benefit of using services instead of working with bundles and their exported packages?

As far as I know it seems the concept of Late Binding has something to do with it. Bundle dependencies are wired together at bundle start, so they are pretty fixed I guess. But with services it seems to be almost the same. A bundle starts and registers services or binds to services. Of course services can come and go whenever they want and you have to keep track of these chances. But the core idea doesn't seem that different to me.

Another aspect to this seems to be that services are more flexible. There could be many implementations for one specific Interface. On the other hand there can be a lot of different implementations for a specific exported package too.

In another text I read that the disadvantage of using exported packages is that they make the application more fragile than services. The author wrote that if you remove one bundle from the dependency graph other dependencies would no longer be met, thus possibly causing a domino effect on the whole graph. But couldn't the same happen if a service would go offline? To me it looks like service dependencies are no better than bundle dependencies.

So far I could not find a blog post, book or presentation that could clearly describe why services are better than just exposing functionality by exporting and importing packages.

To sum my questions up:

What are the key benefits of using OSGi Services that make them superior to exporting and importing packages?


Addition

I have tried to gather further information about this issue and come up with some kind of comparison between plain export/import of packages and services. Maybe this will help us to find a satisfying answer.

  1. Start/Stop/Update

    Both, bundles (hence packages) and services, can be started and stopped. In addition to that they can be kind of updated. Services are also tied to the bundle life cycle itself. But in this case I just mean if you can start and stop services or bundles (so that the exported packages "disappear").

  2. Tracking of changes

    ServiceTracker and BundleTracker make it possible to track and react to changes in the availability of bundles and services.

  3. Specific dependencies to other bundles or services.

    If you want to use an exported package you have to import it.

    Import-Package: net.jens.helloworld
    

    Would net.jens.helloworld provide a service I would also need to import the package in order to get the interface.

    So in both cases their would be some sort of "tight coupling" to a more or less specific package.

  4. Ability to have more than one implementation

    Specific packages can be exported by more than one bundle. There could be a package net.jens.twitterclient which is exported by bundle A and bundle B. The same applies to services. The interface net.jens.twitterclient.TwitterService could be published by bundle A and B.

To sum this up here a short comparison (Exported packages/services):

  1. YES/YES
  2. YES/YES
  3. YES/YES
  4. YES/YES

So there is no difference.

Additionally it seems that services add more complexity and introduce another layer of dependencies (see image below).

alt text

So if there is no real difference between exported packages and services what is the benefit of using services?

My explanation:

The use of services seems more complex. But services themselves seem to be more lightweight. It should be a difference (in terms of performance and resources) if you start/stop a whole bundle or if you just start and stop a specific service.

From a architectural standpoint I also guess that bundles could be viewed as foundation of the application. A foundation shouldn't change often in terms of starting and stopping bundles. The functionality is provided by services of this packages in some kind of dynamic layer above the "bundle layer". This "service layer" could be subject to frequent changes. For example the service for querying a database is unregistered if the database is going offline.


What's your opinion? Am I starting to get the whole point of services or am I still thinking the wrong way? Are there things I am missing that would make services far more attractive over exported packages?

A: 

I think this excellent article could answer a lot of your questions:OSGi, and How It Got That Way.

Julien Nicoulaud
I already read this article. Neil does a good job at explaining OSGi. I came across a lot of his work in the past weeks. But even he does not really make the point why services are the better choice. Maybe a long-time Java programmer will instantly see the benefits. But I am relatively new to Java, so I need a little bit of extra explaining ;)
Jens
+2  A: 

When you start with OSGi, it is always easier to start with an export-package approach it certainly feels more java-like. But when your application starts growing and you need a bit of dynamicity, services are the way to go.

Export-package only does the resolution on startup, whereas services is an on-going resolution (which you may want or not). From a support point of view having services can be very scary (Is it deterministic? How can I replicate problems?), but it is also very powerful.

Peter Kriens explains why he thinks that Services are a paradigm shift in the same way OO was in its time. see µServices and Duct Tape.

In all my OSGi experience I haven't had yet the occasion to implement complex services (i.e. more than one layer), and certainly annotations seem the way to go. You can also use Spring dynamic module to ease the pain of dealing with service trackers. (and many other options like iPOJO, and Blueprint)

Patrick Roumanoff
+1  A: 

I'd recommend purchasing this book. It does an excellent job explaining services and walking through the construction of a non-trivial application that makes use of OSGi Services.

http://equinoxosgi.org/

My company routinely builds 100+ bundle applications using services. The primary benefits we gain from using services are:

1) Loose coupling of producer/consumer implementation

2) Hot swappable service providers

3) Cleaner application architecture

James Branigan
I've done some more investigations on services. To me it still seems that from a technical standpoint you can achieve the same amount of dynamicity with export/import as you can with services. But! I'm starting to think that services are the better choice because a) they are more manageable and b) more lightweight. What is your opinion? As your company seems to do some serious OSGi stuff, do you think that a relatively fixed base of bundles with dynamic services is better than starting and stopping bundles (like services) and tracking them with BundleTracker?
Jens
Feel free to send me an email, since the comment box isn't enough space. My company has come to the following best practices:Bundles only export packages containing Java Interfaces.(This ensures no implementation binding)All Java code has NO references to OSGi defined classes.(We do all application design using POJOs - Plain Old Java Objects)Services are published and injected using Declarative Services.(Simple XML file and 1 line in the manifest; Plus the tooling for it is awesome in Eclipse 3.5 and up)Running out of space, ping me if you want more detail.
James Branigan
A: 

Its quite simple: Bundles are just providing classes you can use. Using Imports/Exports you can shield visibility and avoid (for example) versioning conflicts. Services are instances of classes that satisfy a certain contract (interfaces).

So, when using Services you don't have to care about the origin of a implementation nor of implementation details. They may even change while you are using a certain service.

When you just want to rely on the Bundle Layer of OSGi, you easily introduce crosscutting dependencies to concrete implementations which you usually never want. (read below about DI)

This is not an OSGi thing only - just good practice.

In non OSGi worlds you may use Dependency Injection (DI) frameworks like Guice, Spring or similar. OSGi has the Service Layer built into the framework and lets higher level frameworks (Spring, Guice) use this layer. - so in the end you usually dont use the OSGi Service API directly but DI adapters from user friendly frameworks (Spring-->Spring DM,Guice-->Peaberry etc).

HTH, Toni

Toni Menzel