The Maven Cookbook

1.8. Deploying OSGi Bundles to a Maven Repository

1.8. Deploying OSGi Bundles to a Maven Repository

1.8.1. Task

You need to configure your project to deploy your own custom OSGi bundles to a Maven repository.

1.8.2. Action

The solution is to download an install Nexus Professional, and configure your Maven environment to deploy snapshot and release artifacts to a Hosted Maven repository. To install Nexus Professional, complete the following steps:

  1. Download Nexus Professional from http://www.sonatype.com/products/downloads.

  2. Unpack the Nexus Professional archive on your local workstation, or on the machine that will host Nexus Professional for your workgroup or organization.

  3. Start Nexus Professional by running the startup script in ${nexus_install_dir}/bin/jsw/<platform>/nexus start where <platform> is replaced with the appropriate platform-specific directory.

The following commands will install and start Nexus Professional 1.3.5:

~/programs $ cp ~/Downloads/nexus-professional-webapp-1.3.5-bundle.tar.gz ~/programs
~/programs $ tar xvzf nexus-professional-webapp-1.3.5-bundle.tar.gz
~/programs $ cd nexus-professional-webapp-1.3.5
~/programs/nexus-professional-webapp-1.3.5 $ ./bin/jsw/macosx-universal-32/nexus start
Starting Sonatype Nexus Repository Manager...
Started Sonatype Nexus Repository Manager.

Create a ~/.m2/settings.xml and copy the XML from Example 1.5, “settings.xml to configure deployment credentials and mirrors for Nexus” into this new Maven Settings XML file.

Example 1.5. settings.xml to configure deployment credentials and mirrors for Nexus

<settings>
  <mirrors>
    <mirror>
      <!--This sends everything else to /public -->
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <url>http://localhost:8081/nexus/content/groups/public</url>
    </mirror>
  </mirrors>
  <profiles>
    <profile>
      <id>nexus</id>
      <!--Enable snapshots for the built in central repo to direct -->
      <!--all requests to nexus via the mirror -->
      <repositories>
        <repository>
          <id>central</id>
          <url>http://central</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </repository>
      </repositories>
     <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <url>http://central</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>
  <servers>
    <server>
      <id>nx-snapshots</id>
      <username>deployment</username>
      <password>deployment123</password>
    </server>
    <server>
      <id>nx-releases</id>
      <username>deployment</username>
      <password>deployment123</password>
    </server>
  </servers>
  <activeProfiles>
    <!--make the profile active all the time -->
    <activeProfile>nexus</activeProfile>
  </activeProfiles>
</settings>

Now, go into the osgi-project example project from the previous labs and add the XML from Example 1.6, “Distribution Management Settings for the osgi-project Project” into the top-level parent in ~/examples/osgi/osgi-project/pom.xml. You can add the distributionManagement element as a child of the project element after all of the existing children.

Example 1.6. Distribution Management Settings for the osgi-project Project

<project>
  ...
  <distributionManagement>
    <repository>
      <id>nx-releases</id>
      <name>Nexus Releases</name>
      <url>http://localhost:8081/nexus/content/repositories/releases</url>
    </repository>
    <snapshotRepository>
      <id>nx-snapshots</id>
      <name>Nexus Snapshots</name>
      <url>http://localhost:8081/nexus/content/repositories/snapshots</url>
    </snapshotRepository>
  </distributionManagement>
</project>

Now, deploy the bundle from your osgi-project to the Nexus Snapshots repository by running mvn deploy -DremoteOBR.

~/osgi/osgi-project $ mvn deploy -DremoteOBR
[INFO] Scanning for projects...
...
[INFO] [deploy:deploy]
[INFO] Retrieving previous build number from nx-snapshots
Uploading: http://localhost:8081/nexus/content/repositories/snapshots/org/sonatype/mcookbook/osgi-project/\
           1.0-SNAPSHOT/osgi-project-1.0-20090715.030835-2.pom
2K uploaded  (osgi-project-1.0-20090715.030835-2.pom)
[INFO] Retrieving previous metadata from nx-snapshots
[INFO] Uploading repository metadata for: 'artifact org.sonatype.mcookbook:osgi-project'
[INFO] Retrieving previous metadata from nx-snapshots
[INFO] Uploading repository metadata for: 'snapshot org.sonatype.mcookbook:osgi-project:1.0-SNAPSHOT'
...
[INFO] [deploy:deploy]
[INFO] Retrieving previous build number from nx-snapshots
Uploading: http://localhost:8081/nexus/content/repositories/snapshots/org/sonatype/mcookbook/osgi-project/\
           build/shared-plugin-settings/1.0-SNAPSHOT/shared-plugin-settings-1.0-20090715.030835-2.pom
2K uploaded  (shared-plugin-settings-1.0-20090715.030835-2.pom)
[INFO] Retrieving previous metadata from nx-snapshots
[INFO] Uploading repository metadata for: 'artifact \
       org.sonatype.mcookbook.osgi-project.build:shared-plugin-settings'
[INFO] Retrieving previous metadata from nx-snapshots
[INFO] Uploading repository metadata for: 'snapshot \
       org.sonatype.mcookbook.osgi-project.build:shared-plugin-settings:1.0-SNAPSHOT'
...
[INFO] [deploy:deploy]
[INFO] Retrieving previous build number from nx-snapshots
Uploading: http://localhost:8081/nexus/content/repositories/snapshots/org/sonatype/mcookbook/osgi-project/\
           build/wrapper-bundle-settings/1.0-SNAPSHOT/wrapper-bundle-settings-1.0-20090715.030835-2.pom
1K uploaded  (wrapper-bundle-settings-1.0-20090715.030835-2.pom)
[INFO] Retrieving previous metadata from nx-snapshots
[INFO] Uploading repository metadata for: 'artifact \
       org.sonatype.mcookbook.osgi-project.build:wrapper-bundle-settings'
[INFO] Retrieving previous metadata from nx-snapshots
[INFO] Uploading repository metadata for: 'snapshot \
       org.sonatype.mcookbook.osgi-project.build:wrapper-bundle-settings:1.0-SNAPSHOT'
...
[INFO] [deploy:deploy]
[INFO] Retrieving previous build number from nx-snapshots
...
[INFO] [bundle:deploy]
[INFO] LOCK http://localhost:8081/nexus/content/repositories/snapshots/repository.xml
[INFO] Downloading repository.xml
[INFO] Parsing file:/var/folders/qR/qRpEDfQcFPmRZpsXgPHOok+++TM/-Tmp-/12476273209637081490707781551794.xml
[INFO] Deploying org/sonatype/mcookbook/osgi-project/org.sonatype.mcookbook/1.0-SNAPSHOT/\
       org.sonatype.mcookbook-1.0-20090715.030835-2.jar
[INFO] Writing OBR metadata
[INFO] Uploading repository.xml
[INFO] UNLOCK http://localhost:8081/nexus/content/repositories/snapshots/repository.xml

To summarize, you downloaded and installed Nexus Professional, configured your Maven Settings to supply the default credentials for the deployment user, you added the snapshots and releases repositories to your project's pom.xml, and then you deployed your project's SNAPSHOT artifacts to he snapshot repository and updated an OBR-compatible repository.xml file also stored in the Nexus-hosted Maven repository.

Warning

We skipped some extremely important setup tasks for Nexus Professional, namely changing all of the default passwords. This example uses the default username and password for the deployment user (deployment/deployment123). To change this password, log into the Nexus interface by going to http://localhost:8081/nexus, logging in with the default administrative credentials (admin/admin123), clicking on Users under Security in the left navigation menu, and then right-clicking on the deployment user in the list of users. Once you right-click on the deployment user, select "Set Password" and then supply a new password. Don't leave Nexus unprotected with the default username and password.

1.8.3. Detail

To verify that your artifacts made it into the Snapshots repository on your local Nexus instance, go to the Nexus interface at http://localhost:8081/nexus and login as the administrative user. The default administrative credentials are the username "admin" and the password "admin123". Once you login as the admin user, click on Repositories in the left navigation menu, and then select the Snapshots repository. If you browse the contents of the repository you should see contents similar to the contents shown in Figure 1.6, “The Contents of the Snapshots Repository after Deployment”.

The Contents of the Snapshots Repository after Deployment

Figure 1.6. The Contents of the Snapshots Repository after Deployment


You can see from Figure 1.6, “The Contents of the Snapshots Repository after Deployment” that the repository contains the org.sonatype.mcookbook OSGi bundle under the org.sonatype.mcookbook.osgi-project groupId and that the Pax plugin took care of creating an OSGi bundle repository XML file at repository.xml.

If you want to test how easy it would be to install this component directly from Nexus:

  1. Download Apache Felix from http://www.apache.org/dist/felix/felix-1.8.0.tar.gz.

  2. Unpack the Felix distribution on your local workstation.

  3. Change directory to the Felix directory.

  4. Start Apache Felix with java -jar ./bin/felix.jar

  5. Add the Snapshots repository as an OBR repository by copying the URL to the repository.xml and passing it to the obr command: obr add-url http://localhost:8081/nexus/content/repositories/snapshots/repository.xml

  6. List the contents of the OBR repository.

  7. Deploy the org.sonatype.mcookbook bundle.

  8. List the installed bundles.

These commands are captured in the following screen listing:

~/programs $ wget http://www.apache.org/dist/felix/felix-1.8.0.tar.gz
--2009-07-14 22:46:19--  http://www.apache.org/dist/felix/felix-1.8.0.tar.gz
Resolving www.apache.org... 140.211.11.130
Connecting to www.apache.org|140.211.11.130|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 901620 (880K) [application/x-gzip]
Saving to: `felix-1.8.0.tar.gz'
2009-07-14 22:46:20 (924 KB/s) - `felix-1.8.0.tar.gz' saved [901620/901620]

~/programs $ tar xvzf felix-1.8.0.tar.gz 
felix-1.8.0/
felix-1.8.0/bin/
felix-1.8.0/bin/felix.jar
...
felix-1.8.0/NOTICE
~/programs $ cd felix-1.8.0
~/programs/felix-1.8.0 $ java -jar ./bin/felix.jar 

Welcome to Felix.
=================

-> obr add-url http://localhost:8081/nexus/content/repositories/snapshots/repository.xml
-> obr list
org.sonatype.mcookbook (1.0.0.SNAPSHOT)
-> obr deploy org.sonatype.mcookbook
Target resource(s):
-------------------
   org.sonatype.mcookbook (1.0.0.SNAPSHOT)

Deploying...done.
-> ps 
START LEVEL 1
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (1.8.0)
[   1] [Active     ] [    1] Apache Felix Shell Service (1.2.0)
[   2] [Active     ] [    1] Apache Felix Shell TUI (1.2.0)
[   3] [Active     ] [    1] Apache Felix Bundle Repository (1.4.0)
[   4] [Installed  ] [    1] org.sonatype.mcookbook (1.0.0.SNAPSHOT)
-> start 4
STARTING org.sonatype.mcookbook
REGISTER org.sonatype.mcookbook.ExampleService
-> 

In summary, you've deployed an OSGi bundle to a Maven repository using the Pax plugin from OPS4J and you've successfully deployed it to an independent instance of Apache Felix directly from your Nexus instance. This is a powerful demonstration because it provides a model for how deployment to production of staging can work once you've standardized on a Maven repository manager and OSGi as a deployment framework.

Note

You can also setup and install Nexus Open Source, and rely on the first-class support that the the Pax plugin provides for OSGi bundles stored in a standard Maven repository. In the context of OSGi development, the main difference between Nexus Professional and Nexus Open Source is that Nexus Professional provides direct support for OBR repositories, allowing you to proxy, host, and group OSGi bundle repositories and convert existing Maven repositories to OSGi bundle repositories.