OSGi Declarative Services

OSGi Declarative Services

For those of you who don’t know, the Eclipse SDK now ships an implementation of OSGi Declarative Services (DS). I love DS when working with OSGi services and recommend it to people over using the brittle ServiceTracker mechanism. I’m a big proponent of having people learn by example. To help people understand DS a bit more, PDE includes a DS template now. To access the template, simply create a new project and select the template:

DS Template

Since the template is based on a simple dictionary service, you can fill out some sample words to be in the dictionary:

DS Template 2

Once you click finish, PDE will generate a sample project for you. Inside that sample project, there will be a DictionaryService that allows you to register dictionaries (Dictionary):

package org.eclipse.equinox.ds.example;

public interface Dictionary {
	
    /**
     * Returns the language of the dictionary
     *
     * @return the language of the dictionary
     */
    public String getLanguage();
	
    /**
     * Check for the existence of a word in the dictionary
     * 
     * @param word the word to be checked.
     * @return true if the word is in the dictionary
     */
    public boolean check(String word);

}

You will also notice that the MANIFEST.MF has an entry of ‘OSGI-INF/*.xml’ for the Service-Component header that lists the required DS files. If we take a peak at the component that registers a sample dictionary, it looks like this:



   
   
      
   

The Java code equivalent of registering the sample dictionary without DS would look something like this:

...
service = new DictionaryImpl();
// register the service
context.registerService(DictionaryService.class.getName(), service, null);
...

Great, less code we have to write! Now let’s look at a more complicated example of declaring a component that both needs and registers a service:



   
   
      
   
   

If we had to write this in code, it would involve a ServiceTracker to track the dictionary service, registering our component’s CommandProvider service implementation and code to track dictionary implementations. All in all, it would be quite a chunk of code to keep track of everything. It would get more complicated if we allowed for different cardinality types.

As a reminder, you can also use the DS Tooling in PDE to help craft these component definitions:

PDE DS Editor

Let’s test this example now by launching a new self-hosted instance and checking out the console:

Equinox Console

Cool, we can now check for the existence of words in our dictionary using the Equinox console.

Here’s the code used in this example. To test, simply use the ‘Dictionary Example’ launch configuration included:

DS Launch Configuration

For a bonus tip, there are console commands to help you debug DS:

---Service Component Runtime---
     list/ls [-c] [bundle id] - Lists all components; add -c to display the complete info for each component;
     use [bundle id] to list the components of the specified bundle
     component/comp  - Prints all available information about the specified component;
     enable/en  - Enables the specified component;
     disable/dis  - Disables the specified component;

Also, I highly recommend using ‘-Dequinox.ds.print=true’ for extra debug information while debugging components that aren’t working like you expect them.

Good luck and I hope this helps! If you want more in depth knowledge of DS, I highly recommend checking out the new Equinox book which showcases an in depth chapter on DS.

7 Comments
  • Posted at 7:10 pm, May 12, 2009

    Cool Chris…I see you separated out the Dictionary from the provider…thanks. Now…should we add a Distributed Dictionary template? Also…could you point me at the new dictionary example template source?

  • Gary
    Reply
    Posted at 8:23 pm, June 16, 2009

    What version of Eclipse(DS) is the template available? I’m running 3.4 and I don’t see the template..

    Thanks!
    Gary

  • Gary
    Reply
    Posted at 9:30 pm, June 16, 2009

    Ok.. So i did some digging and see the DS templates in 3.5.. I’ll have to get the latest 3.5 RC installed!

    One other question though related to the example above.. When I read the above it says to me that I don’t need the Activator code to register the service.. I can’t seem to get that to work.. If I include just the DS xml file (and it’s reference in the manifest) my service does not get registered (at least the other service which is listening for it doesn’t get notified).. But if I include code in the Activator to register the service my “listener” gets notified of thru it’s “bind” method.. So am I reading this wrong or do I still need the Activator code to register the service?

    Thanks!
    Gary

  • Luke Patterson
    Reply
    Posted at 10:55 pm, November 5, 2009

    Had same problem as Gary, services not being registered, dropped to console and ran “services” (Equinox), the service in question doesn’t show up until I start the service-containing bundle. Any ideas?

  • Wolfgang Lux
    Reply
    Posted at 1:42 pm, April 27, 2010

    As I understand the example, the activator
    1. creates a DictionaryService instance
    2. registers the DictionaryService
    3. adds itself as service listener for Dictionary
    4. gets a reference to the DictionaryService instance using the service tracker it created before

    Is there a real need for the service tracker?
    If yes: why is there no need for the tracker methods addingService and removedService?
    My idea: Is this an example, to be split into several bundles, later?

Post a Comment

Comment
Name
Email
Website