Archive for the ‘OSGi’ Category

JAX-RS applications in OSGi – whiteboard style

Saturday, August 20th, 2011

There are various ways to publish a JAX-RS application when running inside OSGi. Some use Blueprint or Spring, and I’m sure there are other methods. I’d like to show how you can publish JAX-RS applications using the whiteboard pattern.

(more…)

OSGi Bundle Utility 1.0 released

Thursday, November 18th, 2010

Writing OSGi bundle manifests by hand is nothing anyone wants to do, although some entries will always need to be added explicitely. The most prominent of tools for automatically getting imports and exports right is Peter Kriens’ Bnd. However, I found Bnd difficult to manage and to get to work right with Apache Ant. I wanted something simpler because in most cases, you don’t need all the flexibility Bnd provides. Finally, I wanted the bundle descriptor to be written in XML. So, I wrote my own tool. It turned out to work quite well, and it was a good way for me to learn more about OSGi. I’ve finally taken some time to document it and make it available to anyone interested. Please note that it does not aim to handle all possible cases. The idea is to follow the 80:20 rule to ensure ease of use for most use cases.

So, if you produce OSGi bundles using Apache Ant and you’re not quite happy with Bnd or writing bundle metadata by hand, my OSGi Bundle Utility might be something for you. The utility is published under the Apache License v2.0. Source and Binary distributions and documentation is available here.

Hopefully, I’ve followed all the best practice and it is useful to some people. I’ve been using it for over a year now for dozens of bundles and for converting third-party JARs to OSGi bundles. Feedback is welcome!

OSGi Declarative Services: Configuring multiple instances of a component

Thursday, April 22nd, 2010

Declarative Services are a nice way to create services in the OSGi environment, but there are some subtleties that are not always easy to get under control. Imagine you have a component that observes a directory and acts on the presence of new files (a “hotfolder”, much like the Apache Felix FileInstall bundle). You may have multiple such directories which you want to observe, which you want to configure. You could create a ManagedServiceFactory but there’s a simpler way with Declarative Services once you’ve figured out the subtleties.
Let’s first define a very simple service interface:

public interface Greeter {
    void sayHello();
}

Then let’s implement this interface:

public class GreeterImpl implements Greeter {

    private ComponentContext context;

    protected void activate(ComponentContext context) {
        this.context = context;
        System.out.println("Creating new greeter for " + getName()
                + ": " + context.getComponentInstance().toString());
    }

    protected void deactivate(ComponentContext context) {
        System.out.println("Deactivating greeter for " + getName()
                + ": " + context.getComponentInstance().toString());
        this.context = null;
    }

    public void sayHello() {
        System.out.println("Hello, I'm " + getName());
    }

    private String getName() {
        return (String)this.context.getProperties().get("name");
    }

}

Through the activate(ComponentContext) method, we’ll get the component’s configuration once an instance is activated.
Now, we need the component descriptor for our Greeter component (OSGI-INF/component.xml):

<?xml version="1.0" encoding="UTF-8"?>
<component name="demo.scr.componentfactory.greeter">
  <!-- No factory attribute here! -->
  <implementation class="demo.scr.componentfactory.impl.GreeterImpl"/>
  <service>
    <provide interface="demo.scr.componentfactory.Greeter"/>
  </service>
  <property name="service.description"
      value="A nice component that can say hello"/>
</component>

If you know a little bit about Declarative Services, you might at first expect a factory attribute on the component, since we’re going to create multiple instances, but it would really just wrong with the approach I’m showing here. The final missing clue to make this work with multiple configurations lies with the MetaType descriptor we need to build (OSGI-INF/metatype/metatype.xml):

<?xml version="1.0" encoding="UTF-8"?>
<metatype:MetaData xmlns:metatype="http://www.osgi.org/xmlns/metatype/v1.0.0"
    localization="OSGI-INF/metatype/metatype">
  <metatype:OCD id="demo.scr.componentfactory.greeter"
      name="SCR Component Factory Demo">
    <metatype:AD id="name" type="String"
        name="%name.name" description="%name.desc"/>
  </metatype:OCD>
  <metatype:Designate pid="demo.scr.componentfactory.greeter"
      factoryPid="demo.scr.componentfactory.greeter">
    <metatype:Object ocdref="demo.scr.componentfactory.greeter"/>
  </metatype:Designate>
</metatype:MetaData>

Note especially the “Designate” Element which has both a “pid” and a “factoryPid” attribute. The important part is the “factoryPid” attribute which will enable the desired “factory” functionality.
If you want, a properties file with the translations (OSGI-INF/metatype/metatype.properties):

name.name=Name
name.desc=The name. D'oh!

Just for completeness and illustration, here’s the effective bundle manifest:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: DemoScrComponentFactory
Bundle-SymbolicName: demo.scr.componentfactory
Bundle-Version: 1.0.0
Export-Package: demo.scr.componentfactory
Import-Package: org.osgi.framework,
 org.osgi.service.cm,
 org.osgi.service.component,
Service-Component: OSGI-INF/component.xml

If you deploy the resulting bundle in Felix, for example, you should see our new component in the dropdown list of factory configurations on the configuration page of Felix’s WebConsole.
Besides the UI in the WebConsole, you can also use Apache Felix FileInstall’s configuration feature. Just create a properties file (ex. “demo.scr.componentfactory.greeter-C3PO.cfg”) in the directory observed by FileInstall:

name=C3PO, human cyborg relations

Just use the component’s PID followed by a dash and a name of your choosing. You can create as many configuration files as you like. For each one, SCR will create a service for you.

Update, 2010-05-19:
There may be a little problem with the above. If there are no configurations in ConfigurationAdmin, one component instance will still always be activated which may have unwanted side-effects if your component depends on certain values in the configuration. If you experience that, you can switch to the version 1.1 of Declarative Services and use the configuration policy to control this. The following example will require at least one configuration in the ConfigurationAdmin before the component is activated:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
    name="demo.scr.componentfactory.greeter"
    configuration-policy="require">
[..]
</scr:component>