Annotations for OSGi Declarative Services

19

Recently I took a deeper look at OSGi Declarative Services (DS), Spring Dynamic Modules, iPOJO and Peaberry. I have to admit that I like DS a lot (and even more in the upcoming OSGi 4.2 spec). But one thing I particularly liked about iPOJO was the possibility to either use XML or Java annotations. So, just for fun, I wrote a little Java 6 annotation processor for DS. The benefits I see are:

  • Easier to use: Most Java programmers are familiar using annotations but probably don’t want to deal with XML
  • Better refactoring support: The annotation processor takes care of it, like the renaming of bind/unbind methods
  • Annotations know about the attributes of a class/method etc. and can make assumptions about the intention of the developer

I would like to give you an example. Let’s consider a simple use case: We have a Java POJO (TestComponent) that wants to be a DS Service component, provides two service interfaces (ITestService, ITestService2) and depends on another service (ITestReference). The corresponding Java class looks like this:

a4ds-1.png

The corresponding XML for DS looks like this:

a4ds-6.png
If you use Eclipse 3.5M5 you could easily edit this file using the new Service Component Editor, but with annotations you could create it automatically from a Java source. In my prototype I have created annotations for components and bindings. The annotated source code looks like this:

a4ds-5.png
Using this file as input, my annotation processor generates exactly the above XML file. Let’s explain the above code a bit. The annotation processor knows about the class and the interfaces the class implements. From the fully qualified class name, both the component name and the implementation class are derived. Another convenience is: if no services interfaces are stated explicitly, the processor assumes that all implemented interfaces are supposed to be services this component wants to provide. I took this idea from iPOJO since I like it a lot and I guess this is a very common scenario. The bind annotation interprets the method’s parameter to be a service reference. In my prototype I just put the cardinality “1..1” and the policy “dynamic” as default values for the corresponding attributes of the annotation.

To use my annotation processor in Eclipse, I just had to extend the extension point org.eclipse.jdt.apt.core.annotationProcessorFactory and deploy my plug-in to the dropins folder of my current Eclipse IDE. If I want to use these annotations in a Java 6 project, I just have to enable the Java Compiler/Annotation Processing properties of that project and add my processor. Now, after every save of any Java file in that project, the annotations are processed and the XML files for DS are generated.

Before I continue the put more effort in this I would appreciate feedback from the community. So, please let me know if you would find this useful (and let me also know if you find this completely stupid :))

If someone would be interested in seeing the sources for the annotation processor, I could publish them shortly after a bit cleanup.

Have Fun!

Kai

19 Comments

  1. Tom SchindlFebruary 18, 2009

    Awsome

  2. David IllsleyFebruary 18, 2009

    For me, one of the attractions of DS is the ability to provide/use services without a dependency on additional org.osgi classes etc. For that reason, while I think this is cool, I think I’d continue to use the javadoc based serviceComponent.xml generation provided by the felix maven-scr-plugin[1]

    [1] http://felix.apache.org/site/apache-felix-maven-scr-plugin.html

  3. Kai TödterFebruary 18, 2009

    David,

    Good point! OSGi annotations like these are only useful if you target a Java 5 or 6 environment anyway. But these annotations are only needed at compile time so there would be no technical need to have a runtime dependency. But I did not find a solution for this issue yet.

  4. Kai TödterFebruary 18, 2009

    Thanx Tom, you saved my day 🙂

  5. John ConlonFebruary 18, 2009

    I’ve used the service frameworks iPojo, DS and Spring DM, but I can’t comment on Peabody. I favor the DS for several reasons, the first being the standardization within OSGi. The second being the tooling that is coming with Eclipse 3.5. Kai you’ve provided me with a third!

  6. Gunnar WagenknechtFebruary 18, 2009

    Kai, that’s great stuff! BTW, if you annotate the annotation with @Retention(RetentionPolicy.SOURCE) the annotations should be discarded by the compiler and not appear in the generated byte code.

  7. ekkeFebruary 18, 2009

    Kai,
    great idea 🙂
    …think I can test it next week
    ekke

  8. Kai TödterFebruary 19, 2009

    Gunnar,

    that’s exactly what I was testing before I went home today 🙂 I will keep you posted.

  9. Christian KihmFebruary 19, 2009

    Hi Kai,

    I really like this idea. Especially because I have to use the 3.4 release and therefore have to live without the Service Component Editor.

    I’m looking forward to give it a try.

  10. Stuart McCullochFebruary 19, 2009

    Interesting, perhaps you could open an RFP to standardize these annotations in OSGi, then iPOJO and other frameworks could share them. Kind of like the AOP Alliance types used in various DI frameworks.

  11. Jörg MatysiakFebruary 20, 2009

    Hi Kai,

    very cool!

    This is exactly what I’m missing in the current DS implementation. Would be nice to have the thing as ant plug-in. 🙂

    Having all the information in one file (the java source file) is much simpler to manage
    than the current way using component.xml.

    Although the new service component editor is a big help to find problems, you still have to keep at least two files in sync.

  12. Scott StanchfieldFebruary 20, 2009

    Hehehe… I just did something like this the other day. Mine looks like

    @Component(name=”sampleService”, immediate=true,
    services={@Service(IService.class)},
    references={
    @ServiceReference(name=”x”, iface=ActionListener.class,
    bind=”addActionListener”,
    unbind=”removeActionListener”,
    cardinality=Cardinality.ZeroOrMore
    )
    }
    )

    This generates a separate component.xml for each service class.

    The problem is that if you have more than one service class, updating the manifest.mf gets wonky.

    If you’re doing a full build, the annotation processor knows about all the services and can properly set up the Service-Component header in the manifest.

    If you’re doing an incremental build, it only knows about the classes that require rebuild…

    I could have it add to Service-Component if it doesn’t exist, but then there’s no good way to remove obsolete entries.

    Any thoughts?

    If you’re interested in seeing what I’ve got, please email me: scott@javadude.com

  13. Philipp KursaweFebruary 25, 2009

    Does the AP also modify the MANIFEST.MF?

  14. Kai TödterFebruary 25, 2009

    @Philipp,

    Not yet, but it could. Currently you have to specify the header manually in the MANIFEST.MF:
    Service-Component: OSGI-INF/*
    This leads to the loading of all xml files in the OSGI-INF directory

  15. Kai TödterFebruary 26, 2009

    I wrote a Wiki page with instructions how to browse and test the examples, see http://max-server.myftp.org/trac/pm/wiki/a4ds

  16. Jose GApril 16, 2009

    I like this idea, very very nifty feature. To be honest, the XML way to declare services looks like a small step ahead if you compare it with the annotations way. I definitively give support to this idea and I hope to see it included in the specs very soon.

  17. 3 variations on OSGi themes: part 5 « CodingAndBeyondJuly 23, 2009

    […] Declarative Services (DS) exist in OSGi Compendium specifications since release 4 and continue evolving in later releases. Perhaps, the earliest practical introduction to DS can be found in Neil Bartlett’s ‘point-free blog’ (see Getting Started with OSGi, parts 7, 8). Reference implementation of DS is provided by Equinox OSGi (see Equinox bundles), so it was a natural choice for me to use Eclipse IDE for developing this version of the code. Existing OSGi DS implementation uses XML descriptors, as specified in the OSGi Compendium document. There are also early attempts to introduce annotations for OSGi DS (see Kai’s Blog), but in this project, I’m going to use standard implementation. […]

  18. 3 variations on OSGi themes « CodingAndBeyondJuly 25, 2009

    […] Declarative Services (DS) exist in OSGi Service Compendium specifications since release 4 and continue evolving in later releases. Perhaps, the earliest practical introduction to DS can be found in Neil Bartlett’s ‘point-free blog’ (see Getting Started with OSGi, parts 7, 8). Reference implementation of DS provided by Equinox OSGi (see Equinox bundles) utilizes XML descriptors, as specified in the OSGi Service Compendium document. There are also early attempts to introduce annotations for OSGi DS (see Kai’s Blog), but in this project, I’m going to use standard Equinox implementation. […]

  19. 3 variations on OSGi themes: part 8 « CodingAndBeyondAugust 15, 2009

    […] First impressions. From the OSGi application developer’s point of view, the most attractive from the three systems is OSGi DS, because it adds bare minimum to the OSGi framework to free application developers from the need to use ‘native’ OSGi API. In particular, it eliminates the need for bundle activators and service trackers or listeners for a relatively small price. On the good side of OSGi DS is flexible dynamic control over service dependencies, including service availability monitoring and configurable restart of importer component when imported service is updated. On the bad side, hovewer, is that component classes are not really POJOs. Another advantage is that OSGi DS specifications are included in the standard OSGi Compendium, so it’s expected to be available as a part of OSGi Framework implementation. Indeed, Equinox 3.5.0 has already included DS in its standard configuration. One useful improvement that can be added to OSGi DS is implementing support for Java annotations, as proposed, for instance, by Kai Tödter. […]

Leave a Reply

I accept the Privacy Policy