Enterprise Java

OSGi – Simple Hello World with services

In this post, we’ll develop a simple Hello World application with OSGi. We will use Felix as OSGi container. In the next post, we’ll continue with this application and use Spring Dynamic Modules to improve it.

To make the development interesting, we will create two bundles:

  • A bundle providing a service of HelloWorld
  • A bundle consuming the service to print hello at regular interval time.

So let’s start with the first bundle. What we need first is a very simple service providing a simple print in the console :

package com.bw.osgi.provider.able;
 
public interface HelloWorldService {
    void hello();
}
package com.bw.osgi.provider.impl;
 
import com.bw.osgi.provider.able.HelloWorldService;
 
public class HelloWorldServiceImpl implements HelloWorldService {
    @Override
    public void hello(){
        System.out.println("Hello World !");
    }
}

We cannot make easier. Then, we need to export the Service using an activator :

package com.bw.osgi.provider;
 
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
 
import com.bw.osgi.provider.able.HelloWorldService;
import com.bw.osgi.provider.impl.HelloWorldServiceImpl;
 
public class ProviderActivator implements BundleActivator {
    private ServiceRegistration registration;
 
    @Override
    public void start(BundleContext bundleContext) throws Exception {
        registration = bundleContext.registerService(
                HelloWorldService.class.getName(),
                new HelloWorldServiceImpl(),
                null);
    }
 
    @Override
    public void stop(BundleContext bundleContext) throws Exception {
        registration.unregister();
    }
}

A lot more code here. For those who aren’t confident with OSGi, some explanations. The start method will be called when the module is started and the stop when it’s stopped. In the start method, we register our service in the bundle context using the name of the interface as the name of the exported service. The third parameter, null, indicate that we doesn’t give any configuration for this service. In the stop method, we just unregister the service.

Now, our first bundle is ready. We can build it. For that we’ll use Maven and the maven-bundle-plugin to build the OSGi Bundle directly. Here is the pom.xml file for the project.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>OSGiDmHelloWorldProvider</groupId>
    <artifactId>OSGiDmHelloWorldProvider</artifactId>
    <version>1.0</version>
 
    <dependencies>
        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>1.4.0</version>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
 
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>OSGiDmHelloWorldProvider</Bundle-SymbolicName>
                        <Export-Package>com.bw.osgi.provider.able</Export-Package>
                        <Bundle-Activator>com.bw.osgi.provider.ProviderActivator</Bundle-Activator>
                        <Bundle-Vendor>Baptiste Wicht</Bundle-Vendor>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build> 
</project> 

And then, use mvn install to build it.

We’ll work in a folder called osgi, so we’ll copy this new bundle in the osgi folder.

We can already test it in the OSGi container. If you dont’ have already Felix, let’s download it here. You have to choose the “Felix Distribution”.

Then extract it to the osgi folder we created before. You must now have this folder structure :

osgi
  - felix
  - OSGiDmHelloWorldProvider-1.0.jar

So we can go in the felix folder and launch Felix :

wichtounet@Linux-Desktop:~/Desktop/osgi/felix$ java -jar bin/felix.jar
_______________
Welcome to Apache Felix Gogo

g! 

And install our bundle :

g! install file:../OSGiDmHelloWorldProvider-1.0.jar
Bundle ID: 5

The install is good installed, we can try to start it and see its status :

g! start 5
g! bundle 5
Location             file:../OSGiDmHelloWorldProvider-1.0.jar
State                32
Version              1.0.0
LastModified         1279124741320
Headers              [Tool=Bnd-0.0.357, Bundle-Activator=com.bw.osgi.provider.ProviderActivator, Export-Package=com.bw.osgi.provider.able, Build-Jdk=1.6.0_20, Bundle-Version=1.0.0, Created-By=Apache Maven Bundle Plugin, Bundle-ManifestVersion=2, Manifest-Version=1.0, Bundle-Vendor=Baptiste Wicht, Bnd-LastModified=1279124686551, Bundle-Name=Unnamed - OSGiDmHelloWorldProvider:OSGiDmHelloWorldProvider:bundle:1.0, Built-By=wichtounet, Bundle-SymbolicName=OSGiDmHelloWorldProvider, Import-Package=com.bw.osgi.provider.able,org.osgi.framework;version="1.5"]
BundleContext        org.apache.felix.framework.BundleContextImpl@2353f67e
BundleId             5
SymbolicName         OSGiDmHelloWorldProvider
RegisteredServices   [HelloWorldService]
ServicesInUse        null

All is fine. Our service is good registered

Now we’ll try to consume this service in our second bundle. Our consumer class will be very simple :

package com.bw.osgi.consumer;
 
import javax.swing.Timer;
 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import com.bw.osgi.provider.able.HelloWorldService;
 
public class HelloWorldConsumer implements ActionListener {
    private final HelloWorldService service;
    private final Timer timer;
 
    public HelloWorldConsumer(HelloWorldService service) {
        super();
 
        this.service = service;
 
        timer = new Timer(1000, this);
    }
 
    public void startTimer(){
        timer.start();
    }
 
    public void stopTimer() {
        timer.stop();
    }
 
    @Override
    public void actionPerformed(ActionEvent e) {
        service.hello();
    }
}

And now, we must create the activator to get the service and then give it to the consumer. That will give use something like this :

package com.bw.osgi.consumer;
 
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
 
import com.bw.osgi.provider.able.HelloWorldService;
 
public class HelloWorldActivator implements BundleActivator {
    private HelloWorldConsumer consumer;
 
    @Override
    public void start(BundleContext bundleContext) throws Exception {
        ServiceReference reference = bundleContext.getServiceReference(HelloWorldService.class.getName());
 
        consumer = new HelloWorldConsumer((HelloWorldService) bundleContext.getService(reference));
        consumer.startTimer();
    }
 
    @Override
    public void stop(BundleContext bundleContext) throws Exception {
        consumer.stopTimer();
    }
}

We get a service reference from the bundle context using the name of the class. After that, we get the service instance from the bundle context.

We create also a little pom.xml file to build the bundle :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>OSGiDmHelloWorldConsumer</groupId>
    <artifactId>OSGiDmHelloWorldConsumer</artifactId>
    <version>1.0</version>
    <packaging>bundle</packaging>
 
    <dependencies>
        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>1.0.0</version>
        </dependency>
 
        <dependency>
            <groupId>OSGiDmHelloWorldProvider</groupId>
            <artifactId>OSGiDmHelloWorldProvider</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
 
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>OSGiDmHelloWorldConsumer</Bundle-SymbolicName>
                        <Bundle-Activator>com.bw.osgi.consumer.HelloWorldActivator</Bundle-Activator>
                        <Bundle-Vendor>Baptiste Wicht</Bundle-Vendor>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Then, we use mvn install to create the bundle and we install it in the container :

g! start 6
g! Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
g! stop 6

And here we are We’ve created our first application using OSGi. With that technology you can build modules really independant.

In the next post about OSGi, we’ll see how to use Spring to make the OSGi development easier and to concentrate our effort on the application not OSGi.

The sources of the two bundles are available here :

Reference: OSGi – Simple Hello World with services from our JCG partner Baptiste Wicht at @Blog(“Baptiste Wicht”).

Related Articles :

Baptiste Wicht

Baptiste Wicht is a swiss computer science student. He's very interested in Java, C++, Assembly, Compiler Theory, ... He also is the developer of the EDDI programming language.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
jason Macdonald
jason Macdonald
11 years ago

Too many assumptions:

You state: “Now, our first bundle is ready. We can build it. For that we’ll use Maven and the maven-bundle-plugin to build the OSGi Bundle directly. Here is the pom.xml file for the project.”

Your tutorials would be much better if you did not assume everyone ready knows everything about maven – you should give guidance on the actual Maven command to use and even have a link to setup maven.

José Ricardo
José Ricardo
11 years ago

Good Tutorial, thanks!

Alok
Alok
9 years ago

Where is the link to the next tutorial- OSGi with Spring?

HERLE
HERLE
5 years ago

I have tried working with this and found that the code is not working. May be some plugins and the dependency are not available int the maven repository.

Baptiste Wicht
5 years ago
Reply to  HERLE

Hello HERLE,

You’re right, this is quite outdated. Unfortunately, I haven’t used OSGi in years and I don’t have plans to update it in the near future.

Sorry about that. You may take a look at the source article, there was a few issues raised in the comments and a few solutions. Not sure if that applies to you.

sanatan swain
sanatan swain
4 years ago

Hi Baptiste,

Thanks you for this example.I run my first OSGI program.

Back to top button