Maven 2 Pax Plugin: Usage

Adding the Pax Plugin to your build

To use the current release in an existing project, you need to add the following to your POM:

  <build>
    <plugins>
      <plugin>
        <groupId>org.ops4j</groupId>
        <artifactId>maven-pax-plugin</artifactId>
        <version>1.4</version>
      </plugin>
    </plugins>
  </build>

Using the Pax Plugin from the command line

The following example demonstrates various ways to build and deploy an OSGi project. We start by creating a project to contain the various bundles and move on to wrap the commons-logging jar, as well as its dependencies. The javax.* and com.sun.jdmk.comm packages are marked optional, as they are not available in some execution environments.

Next we create a simple API bundle, with an example service API, but no internals. The example implementation goes in another bundle, which doesn't contain an API, so we need to import the API before it can build. We also embed the junit library inside the bundle, just to demonstrate how easy this can be.

Finally we build and provision the project onto an OSGi framework.

(NOTE: the extra quotes are in case you want to try this in the Windows command shell, which requires quotes around arguments containing '=')

mvn org.ops4j:maven-pax-plugin:create-project "-DgroupId=my.example" "-DartifactId=project"

cd project

mvn pax:wrap-jar "-DartifactId=commons-logging" "-Dversion=1.1" -DwrapTransitive \
                 "-DimportPackage=javax.*|com.sun.jdmk.comm;resolution:=optional,*"

mvn pax:create-bundle "-DbundleName=simple-api" "-Dpackage=org.example.simple" "-Dinternals=false"
mvn pax:create-bundle "-DbundleName=simple-impl" "-Dpackage=org.example.simple" "-Dinterface=false"

cd simple-impl
mvn pax:embed-jar "-DartifactId=junit" "-Dversion=3.8.2"
mvn pax:import-bundle "-DartifactId=simple-api"
cd ..

mvn clean install pax:provision

Save your keyboard and fingers - use the scripts!

You can save a lot of typing by using the Pax-Construct scripts, which also provide basic help text (-h):

pax-create-project -g my.example -a project

cd project

pax-wrap-jar -a commons-logging -v 1.1 -- -DwrapTransitive "-DimportPackage=javax.*|com.sun.jdmk.comm;resolution:=optional,*"

pax-create-bundle -n simple-api -p org.example.simple -- "-Dinternals=false"
pax-create-bundle -n simple-impl -p org.example.simple -- "-Dinterface=false"

cd simple-impl
pax-embed-jar -a junit -v 3.8.2
pax-import-bundle -a simple-api
cd ..

mvn clean install pax:provision

Using the Pax Plugin inside a POM

Here's the same example, but this time using the Maven2 Invoker Plugin with the Pax Plugin to build and deploy an OSGi project:

<?xml version="1.0" encoding="UTF-8"?>
<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>examples</groupId>
  <artifactId>sample-project</artifactId>
  <version>0.2.0</version>

  <name>TEST ${artifactId}</name>

  <packaging>pom</packaging>

  <properties>
    <sandpit>target/example</sandpit>
  </properties>

  <build>
    <plugins>
      <plugin>
        <groupId>org.ops4j</groupId>
        <artifactId>maven-pax-plugin</artifactId>
        <version>1.4</version>
        <executions>
          <execution>
            <phase>package</phase>
<!-- ======================================================================    
            CREATE NEW OSGi PROJECT
     ====================================================================== -->
            <goals>
              <goal>create-project</goal>
            </goals>
            <configuration>
              <!--
                don't create intermediate poms
              -->
              <attachPom>false</attachPom>
              <groupId>my.example</groupId>
              <artifactId>project</artifactId>
              <targetDirectory>
                ${sandpit}/${artifactId}
              </targetDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-invoker-plugin</artifactId>
        <executions>
          <execution>
            <id>wrap-logging</id>
            <phase>package</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <pom>${sandpit}/${artifactId}/project/pom.xml</pom>
              <noLog>true</noLog>
<!-- ======================================================================    
              WRAP COMMONS LOGGING AS WELL AS ITS DEPENDENCIES
     ====================================================================== -->
              <goals>
                <goal>pax:wrap-jar</goal>
              </goals>
              <properties>
                <artifactId>commons-logging</artifactId>
                <version>1.1</version>
                <wrapTransitive>true</wrapTransitive>
                <importPackage>javax.\*\|com.sun.jdmk.comm\;resolution:=optional,\*</importPackage>
              </properties>
            </configuration>
          </execution>
          <execution>
            <id>api-bundle</id>
            <phase>package</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <pom>${sandpit}/${artifactId}/project/pom.xml</pom>
              <noLog>true</noLog>
<!-- ======================================================================    
              CREATE SIMPLE API OSGi BUNDLE
     ====================================================================== -->
              <goals>
                <goal>pax:create-bundle</goal>
              </goals>
              <properties>
                <bundleName>simple-api</bundleName>
                <package>org.example.simple</package>
                <internals>false</internals>
              </properties>
            </configuration>
          </execution>
          <execution>
            <id>impl-bundle</id>
            <phase>package</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <pom>${sandpit}/${artifactId}/project/pom.xml</pom>
              <noLog>true</noLog>
<!-- ======================================================================    
              CREATE SIMPLE IMPLEMENTATION OSGi BUNDLE
     ====================================================================== -->
              <goals>
                <goal>pax:create-bundle</goal>
              </goals>
              <properties>
                <bundleName>simple-impl</bundleName>
                <package>org.example.simple</package>
                <interface>false</interface>
              </properties>
            </configuration>
          </execution>
          <execution>
            <id>embed-jar</id>
            <phase>package</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <pom>${sandpit}/${artifactId}/project/simple-impl/pom.xml</pom>
              <noLog>true</noLog>
<!-- ======================================================================    
              EMBED JUNIT INSIDE THE IMPLEMENTATION BUNDLE
     ====================================================================== -->
              <goals>
                <goal>pax:embed-jar</goal>
              </goals>
              <properties>
                <artifactId>junit</artifactId>
                <version>3.8.2</version>
              </properties>
            </configuration>
          </execution>
          <execution>
            <id>import-api</id>
            <phase>package</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <pom>${sandpit}/${artifactId}/project/simple-impl/pom.xml</pom>
              <noLog>true</noLog>
<!-- ======================================================================    
              IMPORT API INTO THE IMPLEMENTATION BUNDLE
     ====================================================================== -->
              <goals>
                <goal>pax:import-bundle</goal>
              </goals>
              <properties>
                <artifactId>simple-api</artifactId>
              </properties>
            </configuration>
          </execution>
          <execution>
            <id>build</id>
            <phase>package</phase>
            <goals>
              <goal>run</goal>
            </goals>
            <configuration>
              <pom>${sandpit}/${artifactId}/project/pom.xml</pom>
              <noLog>true</noLog>
<!-- ======================================================================    
              BUILD OSGi PROJECT
     ====================================================================== -->
              <goals>
                <goal>install</goal>
              </goals>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Copy and paste the above XML to a new pom.xml file, then run the following commands to deploy the example on the Felix framework:

mvn clean install

mvn pax:provision -f target/example/sample-project/project/pom.xml