Maven – Create a OSGi bundle using maven-bundle-plugin

In Maven, you can build a OSGi bundle using maven-bundle-plugin.
I find a very useful tutorial which shows you how to create a HelloWorld OSGi bundle.

 

Actually there are many OSGi tutorials at the Apache Felix Website. But those examples did not make use of Maven. So i make the first two examples into Maven projects.

1. Create a Maven project with the following pom.xml

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>felix-tutorial</groupId>
	<artifactId>example-1</artifactId>
	<version>1.0</version>
	<packaging>bundle</packaging>
	<name>Apache Felix Tutorial Example 1</name>
	<description>Apache Felix Tutorial Example 1</description>
	
	<!-- Build Configuration -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<extensions>true</extensions>
				<configuration>
					<instructions>
						<Bundle-SymbolicName>${pom.groupId}.${pom.artifactId}</Bundle-SymbolicName>
						<Bundle-Name>Service listener example</Bundle-Name>
						<Bundle-Description>A bundle that displays messages at startup and when service events occur</Bundle-Description>
						<Bundle-Vendor>Apache Felix</Bundle-Vendor>
						<Bundle-Version>1.0.0</Bundle-Version>
						<Bundle-Activator>tutorial.example1.Activator</Bundle-Activator>
						<Import-Package>org.osgi.framework</Import-Package>
					</instructions>
				</configuration>
			</plugin>
		</plugins>
	</build>
	
	<!-- Dependecies Management -->
	<dependencies>
		<dependency>
			<groupId>org.apache.felix</groupId>
			<artifactId>org.apache.felix.framework</artifactId>
			<version>2.0.4</version>
		</dependency>	
	</dependencies>
</project>

 

2. Create src/main/java/tutorial/example1/Activator.java

/**
 * Apache Felix OSGi tutorial.
**/

package tutorial.example1;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceEvent;

/**
 * This class implements a simple bundle that utilizes the OSGi
 * framework's event mechanism to listen for service events. Upon
 * receiving a service event, it prints out the event's details.
**/
public class Activator implements BundleActivator, ServiceListener
{
    /**
     * Implements BundleActivator.start(). Prints
     * a message and adds itself to the bundle context as a service
     * listener.
     * @param context the framework context for the bundle.
    **/
    public void start(BundleContext context)
    {
        System.out.println(&amp;quot;Starting to listen for service events.&amp;quot;);
        context.addServiceListener(this);
    }

    /**
     * Implements BundleActivator.stop(). Prints
     * a message and removes itself from the bundle context as a
     * service listener.
     * @param context the framework context for the bundle.
    **/
    public void stop(BundleContext context)
    {
        context.removeServiceListener(this);
        System.out.println(&amp;quot;Stopped listening for service events.&amp;quot;);

        // Note: It is not required that we remove the listener here,
        // since the framework will do it automatically anyway.
    }

    /**
     * Implements ServiceListener.serviceChanged().
     * Prints the details of any service event from the framework.
     * @param event the fired service event.
    **/
    public void serviceChanged(ServiceEvent event)
    {
        String[] objectClass = (String[])
            event.getServiceReference().getProperty(&amp;quot;objectClass&amp;quot;);

        if (event.getType() == ServiceEvent.REGISTERED)
        {
            System.out.println(
                &amp;quot;Ex1: Service of type &amp;quot; + objectClass[0] + &amp;quot; registered.&amp;quot;);
        }
        else if (event.getType() == ServiceEvent.UNREGISTERING)
        {
            System.out.println(
                &amp;quot;Ex1: Service of type &amp;quot; + objectClass[0] + &amp;quot; unregistered.&amp;quot;);
        }
        else if (event.getType() == ServiceEvent.MODIFIED)
        {
            System.out.println(
                &amp;quot;Ex1: Service of type &amp;quot; + objectClass[0] + &amp;quot; modified.&amp;quot;);
        }
    }
}

 

3. Run mvn install to build the bundle
 

4. The build file example-1-1.0.jar can be found at the target folder
 

5. Create another Maven project with the following pom.xml

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>felix-tutorial</groupId>
	<artifactId>example-2</artifactId>
	<version>1.0</version>
	<packaging>bundle</packaging>
	<name>Apache Felix Tutorial Example 2</name>
	<description>Apache Felix Tutorial Example 2</description>

	<!-- Build Configuration -->
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.felix</groupId>
				<artifactId>maven-bundle-plugin</artifactId>
				<extensions>true</extensions>
				<configuration>
					<instructions>
						<Bundle-SymbolicName>${pom.groupId}.${pom.artifactId}</Bundle-SymbolicName>
						<Bundle-Name>English dictionary</Bundle-Name>
						<Bundle-Description>A bundle that registers an English dictionary service</Bundle-Description>
						<Bundle-Vendor>Apache-Felix</Bundle-Vendor>
						<Bundle-Version>1.0.0</Bundle-Version>
						<Bundle-Activator>tutorial.example2.Activator</Bundle-Activator>
						<Export-Package>tutorial.example2.service</Export-Package>
						<Import-Package>org.osgi.framework</Import-Package>
					</instructions>
				</configuration>
			</plugin>
		</plugins>
	</build>
	
	<dependencies>
		<dependency>
			<groupId>org.apache.felix</groupId>
			<artifactId>org.apache.felix.framework</artifactId>
			<version>2.0.4</version>
		</dependency>	
	</dependencies>
</project>

 

6. Create src/main/java/tutorial2/service/DictionaryService.java

/**
 * Apache Felix OSGi tutorial.
**/

package tutorial.example2.service;

/**
 * A simple service interface that defines a dictionary service.
 * A dictionary service simply verifies the existence of a word.
**/
public interface DictionaryService
{
    /**
     * Check for the existence of a word.
     * @param word the word to be checked.
     * @return true if the word is in the dictionary,
     *         false otherwise.
    **/
    public boolean checkWord(String word);
}

 

7. Create src/main/java/tutorial/example2/Activator.java

/**
 * Apache Felix OSGi tutorial.
**/

package tutorial.example2;

import java.util.Properties;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

import tutorial.example2.service.DictionaryService;

/**
 * This class implements a simple bundle that uses the bundle
 * context to register an English language dictionary service
 * with the OSGi framework. The dictionary service interface is
 * defined in a separate class file and is implemented by an
 * inner class.
**/
public class Activator implements BundleActivator
{
    /**
     * Implements BundleActivator.start(). Registers an
     * instance of a dictionary service using the bundle context;
     * attaches properties to the service that can be queried
     * when performing a service look-up.
     * @param context the framework context for the bundle.
    **/
    public void start(BundleContext context)
    {
        Properties props = new Properties();
        props.put(&amp;quot;Language&amp;quot;, &amp;quot;English&amp;quot;);
        context.registerService(
            DictionaryService.class.getName(), new DictionaryImpl(), props);
    }

    /**
     * Implements BundleActivator.stop(). Does nothing since
     * the framework will automatically unregister any registered services.
     * @param context the framework context for the bundle.
    **/
    public void stop(BundleContext context)
    {
        // NOTE: The service is automatically unregistered.
    }

    /**
     * A private inner class that implements a dictionary service;
     * see DictionaryService for details of the service.
    **/
    private static class DictionaryImpl implements DictionaryService
    {
        // The set of words contained in the dictionary.
        String[] m_dictionary =
            { &amp;quot;welcome&amp;quot;, &amp;quot;to&amp;quot;, &amp;quot;the&amp;quot;, &amp;quot;osgi&amp;quot;, &amp;quot;tutorial&amp;quot; };

        /**
         * Implements DictionaryService.checkWord(). Determines
         * if the passed in word is contained in the dictionary.
         * @param word the word to be checked.
         * @return true if the word is in the dictionary,
         *         false otherwise.
        **/
        public boolean checkWord(String word)
        {
            word = word.toLowerCase();

            // This is very inefficient
            for (int i = 0; i &amp;lt; m_dictionary.length; i++)
            {
                if (m_dictionary[i].equals(word))
                {
                    return true;
                }
            }
            return false;
        }
    }
}

 

8. Run mvn install to build the second project
 

9. The final projects structure should look like this

 

10. You can found the MANIFEST.MF inside the built .jar file
example-1-1.0.jar/META-INF/MANIFEST.MF

Manifest-Version: 1.0
Export-Package: tutorial.example1;uses:=&amp;quot;org.osgi.framework&amp;quot;
Built-By: ykyuen
Tool: Bnd-0.0.357
Bundle-Name: Service listener example
Created-By: Apache Maven Bundle Plugin
Bundle-Vendor: Apache Felix
Build-Jdk: 1.6.0_16
Bundle-Version: 1.0.0
Bnd-LastModified: 1267592207481
Bundle-ManifestVersion: 2
Bundle-Activator: tutorial.example1.Activator
Bundle-Description: A bundle that displays messages at startup and when service events occur
Bundle-SymbolicName: felix-tutorial.example-1
Import-Package: org.osgi.framework;version=&amp;quot;1.5&amp;quot;

Done =)

Next: Apache Felix – Register OSGi Service

Leave a comment

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