ServiceMix 4 uses the Maven bundle plug-in from Apache Felix. The bundle plug-in is based on the bnd tool from Peter Kriens. It automates the construction of OSGi bundle manifests by introspecting the contents of the classes being packaged in the bundle. Using the knowledge of the classes contained in the bundle, the plug-in can calculate the proper values to populate the Import-Packages and the Export-Package properties in the bundle manifest.

The plug-in also has default values that are used for other required properties in the bundle manifest.

To use the bundle plug-in you will need to do the following:

  1. Add the bundle plug-in to your project's POM file.
  2. Configure the plug-in to correctly populate your bundle's manifest.

Setting Up a FUSE ESB OSGi Project

To set up a project to use the Maven bundle plug-in you do the following:

  1. Add the bundle plug-in to your POM
  2. Instruct Maven to package the results as an OSGi bundle.

Adding the bundle plug-in

Before you can use the bundle plug-in you must add a dependency on Apache Felix. Once you have added the dependency, you can add the bundle plug-in to the plug-in portion of the POM.

Adding the OSGi Bundle Plug-in to Your POM
...
<dependencies>
  <dependency>
    <groupId>org.apache.felix</groupId>
    <artifactId>org.osgi.core</name>
    <version>1.0.0</version>
  </dependency>
  ...
</dependencies>
...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-bundle-plugin</artifactId>
      <configuration>
        <instructions>
          <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
          <Import-Package>*,org.apache.camel.osgi</Import-Package>
          <Private-Package>org.apache.servicemix.examples.camel</Private-Package>
        </instructions>
      </configuration>
    </plugin>
  </plugins>
</build>
...

The instructions element contains the BND directives describing how the bundle is constructed.
The listed ones do the following:

  • Configures the plug-in to use the project's artifact ID as the bundle's symbolic name.
  • Configures the plug-in to include all Java packages imported by the bundled classes and also import the org.apache.camel.osgi package.
  • Configures the plug-in to bundle the listed class, but not include them in the list of exported packages..

Activating the bundle plug-in

In order to instruct Maven to use the bundle plug-in you need to instruct it to package the results of the project as a bundle. You do this by setting the POM's packaging element to bundle.

Configuring the Bundle Plug-In

All of the bundle plug-in's required properties have default settings that will generate a valid OSGi bundle. However, you will likely want to modify some of the values. Most of the properties can be specified inside of the plug-in's instructions element.

Some of the commonly used configuration properties are:

  • Bundle-SymbolicName
  • Bundle-Name
  • Bundle-Version
  • Export-Package
  • Private-Package
  • Import-Package

Setting the bundle's symbolic name

By default the bundle plug-in sets the value for the Bundle-SymbolicName property to groupId+ "." + artifactId, with the following exceptions:

  • If groupId has only one section (no dots) then the first package name with classes is returned.
  • If artifactId is equal to last section of groupId then groupId is used.
  • If artifactId starts with last section of groupId that portion is removed.

To specify your own value for the bundle's symbolic name you add a Bundle-SymbolicName child in the plug-in's instructions element.

Setting the bundle's name

By default the bundle's name is set to ${pom.name}. To specify your own value for the bundle's name you add a Bundle-Name child in the plug-in's instructions element.

Setting the bundle's version

By default a bundle's version is set to ${pom.version}. Any dashes(-) are replaced with dots(.). To specify your own value for the bundle's version you add a Bundle-Version child in the plug-in's instructions element.

Specifying exported packages

By default the OSGi manifest's Export-Package list is populated by all of the packages in your project's class path that matches the pattern Bundle-SymbolicName.*. These packages are also included in the bundle.

Important

If you use a Private-Package element in your plug-in configuration and do not specify a list of packages to export, the default behavior
is to assume that no packages are exported. Only the packages listed in the Private-Package element will be included in the bundle and none of them will be exported.

The default behavior can result in very large packages as well as exporting packages that should be kept private. To change the list of exported packages you can add a Export-Package child to the plug-in's instructions element.

The Export-Package element specifies a list of packages that are to be included in the bundle and be exported. The package names can be specified using the * wildcard.

You can specify packages to be excluded be prefixing the entry with !. When attempting to exclude packages, the order of entries in the list is important. The list is processed in order from the start and contradicting entries are ignored.

Specifying private packages

By default all packages included in a bundle are exported. You will want to include packages in the bundle without exporting them. To specify a list of packages that will be included in a bundle, but not exported, you add a Private-Package child to the plug-in's instructions element.

The Private-Package element works nearly identical to the Export-Package element. You specify a list of packages that are to be
included in the bundle. The bundle plug-in uses the list to find all of the classes on the project's classpath that are to be included in the bundle. These packages are included packaged in the bundle, but not exported.

Important

If a package matches an entry in both the Private-Package element and the Export-Package element, the Export-Package element takes precedent. The package will be added to the bundle and exported.

Specifying the imported packages

By default, the bundle plug-in populates the OSGi manifest's Import-Package property with a list of all the packages referred to by the contents of the bundle and not included in the bundle.

While the default behavior is typically sufficient for most projects, you will find instances where you need to import packages that will not be automatically added to the list. The default behavior can also result in unwanted packages being imported.

To specify a list of packages to be imported by the bundle you add a Import-Package child to the plug-in's instructions element. The syntax for the package list is the same as for both the Export-Package and Private-Package elements.

Important

When you use the Import-Package element, the plug-in does not automatically scan the bundle's contents to determine if there are
any required imports. To ensure that the contents of the bundle are scanned, you must place * as the last entry in the package list.

Useful Maven archetypes

There are a number of Maven archetypes that will generate a project that is preconfigured to use the bundle plug-in:

Spring OSGi

The Spring OSGi archetype creates a vanilla project for building an OSGi project using Spring DM. You invoke the archetype using the following command:

mvn archetype:create -DarchetypeGroupId=org.springframework.osgi \
-DarchetypeArtifactId=spring-osgi-bundle-archetype  \
-DarchetypeVersion=1.12   \
-DgroupId=groupId  \
-DartifactId=artifactId \
-Dversion=version

Apache Camel Bundle

The Apache Camele bundle archetype creates a project for building a route that will be deployed into ServiceMix 4. You invoke the archetype using the following command:

mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling \
-DarchetypeArtifactId=servicemix-osgi-camel-archetype  \
-DarchetypeVersion=2008.01.0.3 \
-DgroupId=groupId  \
-DartifactId=artifactId \
-Dversion=version

Apache CXF Code-First Bundle

The Apache CXF code-first archetype creates a project for building a service from Java. You invoke the archetype using the following command:

mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling   /
-DarchetypeArtifactId=spring-osgi-bundle-archetype  /
-DarchetypeVersion=2008.01.0.3 /
-DgroupId=groupId  /
-DartifactId=artifactId /
-Dversion=version

Apache CXF WSDL-First Bundl

The Apache CXF wsdl-first archetype creates a project for creating a service from WSDL. You invoke the archetype using the following command:

mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling   /
-DarchetypeArtifactId=servicemix-osgi-cxf-wsdl-first-archetype /
-DarchetypeVersion=2008.01.0.3 /
-DgroupId=groupId  /
-DartifactId=artifactId /
-Dversion=version

More information

For more information on configuring the bundle plug-in see:

  • No labels