News and Notes from the Makers of Nexus | Sonatype Blog

Maven Tips and Tricks: Creating an OSGi Project With Maven

Written by Tim OBrien | September 22, 2009

This post is a quick start guide to using the Maven PAX plugin to create OSGi project and start an OSGi runtime environment (Apache Felix). First, use the Maven Pax Plugin from OPS4J, and call the create-project goal. The following command-line will create a multi-module project with a groupId of org.sonatype.mhandbook, an artifactId of osgi-project, and a version of 1.0-SNAPSHOT:

~/examples/osgi $ mvn org.ops4j:maven-pax-plugin:create-project \
  -DgroupId=org.sonatype.mhandbook \
  -DartifactId=osgi-project \
  -Dversion=1.0-SNAPSHOT
[INFO] Scanning for projects...
[INFO] artifact org.ops4j:maven-pax-plugin: checking for updates from central
[INFO] Building Maven Default Project
[INFO]    task-segment: [org.ops4j:maven-pax-plugin:create-project] (aggregator
-style)
[INFO] [pax:create-project]
[INFO] Selecting latest archetype release within version range [1,2)
[INFO] artifact org.ops4j.pax.construct:maven-archetype-osgi-project: checking
for updates from central
[INFO] Using following parameters for creating Archetype: maven-archetype-osgi-
project:1.0.3
[INFO] Parameter: packageName, Value: org.sonatype.mhandbook.osgi-project
[INFO] Parameter: archetypeVersion, Value: 1.0.3
[INFO] Parameter: groupId, Value: org.sonatype.mhandbook
[INFO] Parameter: archetypeArtifactId, Value: maven-archetype-osgi-project
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: archetypeGroupId, Value: org.ops4j.pax.construct
[INFO] Parameter: basedir, Value: ~/examples/osgi
[INFO] Parameter: package, Value: org.sonatype.mhandbook.osgi-project
[INFO] Parameter: artifactId, Value: osgi-project
[INFO] ********************* End of debug info from resources from generated POM
[INFO] Archetype created in dir: ~/examples/osgi/osgi-project

Once you've generated an OSGi project using the Pax Plugin, you will have the following directory structure:

If you want to verify that you can build the project successfully, run mvn clean install:

~/examples/osgi/osgi-project $ mvn clean install
[INFO] Reactor build order:
[INFO]   org.sonatype.mhandbook.osgi-project (OSGi project)
[INFO]   osgi-project - plugin configuration
[INFO]   osgi-project - wrapper instructions
[INFO]   osgi-project - bundle instructions
[INFO]   osgi-project - imported bundles
[INFO] ------------------------------------------------------------------------
[INFO] Building org.sonatype.mhandbook.osgi-project (OSGi project)
[INFO]    task-segment: [clean, install]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] [site:attach-descriptor]
[INFO] [install:install]
[INFO] Installing ~/examples/osgi/osgi-project/target/pom-transformed.
xml to ~/.m2/repository/org/sonatype/mhandbook/osgi-project/1.0-SNAPS
HOT/osgi-project-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] Building osgi-project - plugin configuration
[INFO]    task-segment: [clean, install]
...

Instead of executing these goals manually, you can also download and install the Pax-Construct scripts which can be used to automate the process of creating a new OSGi project with the Pax plugin. For more information, see the Pax Construct Quickstart page.

The generated multi-module project structure contains a parent project with the supplied groupId, artifactId, and version, and a few submodules:

  • osgi-project/pom.xml
    This is the parent POM
  • osgi-project/poms/compiled/pom.xml
    This POM serves as the parent POM to all of the compiled OSGi components you will add to this osgi-project Maven project.
  • osgi-project/poms/wrappers/pom.xml
    If you can't find a particular library as an OSGi component, the Pax Construct tools allow you to wrap an existing dependency artifact into an OSGi bundle. The configuration for these wrapped bundles is stored in this POM.
  • osgi-project/provision/pom.xml
    This POM configures the Apache Felix runtime environment that you can start by running the pax:provision goal. If you need to import a bundle into your runtime environment, this is the POM that contains a reference to the corresponding Maven dependency.

To start the Apache Felix container, run mvn install pax:provision from the osgi-project/ directory:

~/examples/osgi/osgi-project $ mvn install pax:provision
[INFO] Scanning for projects...
[INFO] Reactor build order:
[INFO]   org.sonatype.mhandbook.osgi-project (OSGi project)
[INFO]   osgi-project - plugin configuration
[INFO]   osgi-project - wrapper instructions
[INFO]   osgi-project - bundle instructions
[INFO]   osgi-project - imported bundles
...
[INFO] [pax:provision]
[INFO] ~~~~~~~~~~~~~~~~~~~
[INFO]  No bundles found!
[INFO] ~~~~~~~~~~~~~~~~~~~
    ______  ________  __  __
   / __  / /  __   / / / / /
  /  ___/ /  __   / _\ \ _/
 /  /    /  / /  / / _\ \
/__/    /__/ /__/ /_/ /_/
Pax Runner (1.0.0) from OPS4J - http://www.ops4j.org
----------------------------------------------------
 -> Using config [classpath:META-INF/runner.properties]
 -> Using only arguments from command line
 -> Scan bundles from [~/examples/osgi/osgi-project/runner/deploy-pom.xml]
 -> Scan bundles from [scan-pom:file:/~/examples/osgi/osgi-project/runner/deplo
y-pom.xml]
 -> Preparing framework [Felix 1.8.0]
 -> Downloading bundles...
 -> Using execution environment [J2SE-1.5]
 -> Runner has successfully finished his job!
Welcome to Felix.
=================
-> 

When you started up Felix, notice that the line directly following the execution of the pax:provision goal says "No bundles found!". By running pax:provision, you've started the Felix OSGi service platform. Felix uses the configuration from a properties file and then scans two deploy-pom.xml files for bundles that it should download and install. Finding none, it presents a simple prompt and awaits orders. At this point, we have an empty container that isn't running any custom logic or downloading any OSGi bundles.

Once you have the console for Felix loaded, you can control the platform, load components from remote repositories, list all of the running components, and start and stop components. Try executing the command help to see a list of available commands:

-> help
bundlelevel <level> <id> ... | <id> - set or get bundle start level.
cd [<base-URL>]                     - change or display base URL.
exports <id> ...                    - list exported packages.
headers [<id> ...]                  - display bundle header properties.
help                                - display impl commands.
imports <id> ...                    - list imported packages.
install <url> [<url> ...]           - install bundle(s).
ps [-l | -s | -u]                   - list installed bundles.
refresh [<id> ...]                  - refresh packages.
requirers <id> ...                  - list requiring bundles.
requires <id> ...                   - list required bundles.
resolve [<id> ...]                  - attempt to resolve the specified bundles.
scr help                            - Declarative Services Runtime
services [-u] [-a] [<id> ...]       - list registered or used services.
shutdown                            - shutdown framework.
start [-t] <id> [<id> <url> ...]    - start bundle(s).
startlevel [<level>]                - get or set framework start level.
stop [-t] <id> [<id> ...]           - stop bundle(s).
uninstall <id> [<id> ...]           - uninstall bundle(s).
update <id> [<url>]                 - update bundle.
version                             - display version of framework.

If you execute the ps command, you can see a list of bundles with IDs that are running in the Felix container. You can start and stop bundles by running start and stop followed by the ID of the specific bundle you want to control. You can also install and uninstall bundles in the running container.

For more information, read the OSGi chapter in the Maven Handbook, it will walk you through the process of creating a new OSGi project and importing OSGi bundles into an OSGi container.