Getting the benefits of maven-bundle-plugin in other project types

Getting the benefits of maven-bundle-plugin in other project types


Note: This information is partially available at http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html

The goal here is to be able to use a different packaging type than "bundle", say "war" packaging, and still get benefits of the maven-bundle-plugin. The major benefit is of course having the manifest being generated by the BND tool.

If your project is packaged as "war", you can still use the maven-bundle-plugin to generate the manifest if you add "war" to supportedProjectTypes:

<plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <configuration> <supportedProjectTypes> <supportedProjectType>jar</supportedProjectType> <supportedProjectType>bundle</supportedProjectType> <supportedProjectType>war</supportedProjectType> </supportedProjectTypes>

Here is a more complete configuration that I use for generating a manifest using BND and adding it to the WAR:

<project xmlns="http://maven.apache.org/POM/4.0.0" ...> ... <properties> <bundle.symbolicName>myartifact</bundle.symbolicName> <bundle.namespace>myartifact</bundle.namespace> </properties> <modelVersion>4.0.0</modelVersion> <groupId>mygroup</groupId> <artifactId>myartifact</artifactId> <version>1.0-SNAPSHOT</version> <name>${bundle.symbolicName}</name> <packaging>war</packaging> <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <configuration> <archive> <!-- add the generated manifest to the war --> <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <executions> <execution> <id>bundle-manifest</id> <phase>process-classes</phase> <goals> <goal>manifest</goal> </goals> </execution> </executions> <configuration> <supportedProjectTypes> <supportedProjectType>jar</supportedProjectType> <supportedProjectType>bundle</supportedProjectType> <supportedProjectType>war</supportedProjectType> </supportedProjectTypes> <instructions> <Bundle-SymbolicName>${bundle.symbolicName}</Bundle-SymbolicName> <Bundle-Version>${pom.version}</Bundle-Version> <!-- | assume public classes are in the top package, and private classes are under ".internal" --> <Export-Package>!${bundle.namespace}.internal.*,${bundle.namespace}.*;version="${pom.version}"</Export-Package> <Private-Package>${bundle.namespace}.internal.*</Private-Package> <!-- | each module can override these defaults in their osgi.bnd file --> <_include>-osgi.bnd</_include> </instructions> </configuration> </plugin> </plugins> </build>

Now we can get a bundle with a BND-generated manifest installed in the repo as a .war.

For JAR packaging, you'd replace appropriate parts of above with:

<plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <!-- add the generated manifest to the archive --> <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> </archive> </configuration> </plugin>

Embedding Dependencies

If you use at least maven-bundle-plugin version 1.4.3, it should apply the Embed-Dependency
instruction for both the bundle and manifest goals - however, because the manifest goal doesn't
actually end up building the final bundle then you might find some minor differences.

But you can definitely use this to generate the Bundle-ClassPath even with "war" packaging.

You can configure Embed-Dependency to match the location the WAR plugin uses.

For example perhaps something like:

<configuration> <supportedProjectTypes> <supportedProjectType>jar</supportedProjectType> <supportedProjectType>bundle</supportedProjectType> <supportedProjectType>war</supportedProjectType> </supportedProjectTypes> <instructions> <Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath> <Embed-Directory>WEB-INF/lib</Embed-Directory> <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> <Import-Package>*;resolution:=optional</Import-Package> </instructions> </configuration>

Example

Hendy Irawan has created a project to demonstrate:

  • Apache CXF

  • OSGi

  • Pax Web Service

  • Pax Web Extender War

  • Maven

  • Maven Bundle Plugin

  • configuring it for WAR project

  • Maven Pax Plugin

Checkout from here: (Subversion)

https://scm.ops4j.org/repos/ops4j/laboratory/users/ceefour/cxf-osgi-sample

This might be helpful with regards to the above, or how to mix and match the combinations.

Note that this is not an official sample, just a contribution.