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.
- Apache Felix Tutorial Example 1: A bundle that listens for OSGi service events.
- Apache Felix Tutorial Example 2: A bundle that implements a dictionary service.
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(&quot;Starting to listen for service events.&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(&quot;Stopped listening for service events.&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(&quot;objectClass&quot;);
if (event.getType() == ServiceEvent.REGISTERED)
{
System.out.println(
&quot;Ex1: Service of type &quot; + objectClass[0] + &quot; registered.&quot;);
}
else if (event.getType() == ServiceEvent.UNREGISTERING)
{
System.out.println(
&quot;Ex1: Service of type &quot; + objectClass[0] + &quot; unregistered.&quot;);
}
else if (event.getType() == ServiceEvent.MODIFIED)
{
System.out.println(
&quot;Ex1: Service of type &quot; + objectClass[0] + &quot; modified.&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(&quot;Language&quot;, &quot;English&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 =
{ &quot;welcome&quot;, &quot;to&quot;, &quot;the&quot;, &quot;osgi&quot;, &quot;tutorial&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 &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:=&quot;org.osgi.framework&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=&quot;1.5&quot;
Done =)
