About 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.

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 :
Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

2 Responses to "OSGi – Simple Hello World with services"

  1. jason Macdonald says:

    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.

  2. José Ricardo says:

    Good Tutorial, thanks!

Leave a Reply


− 3 = one



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close