Fabrizio Giudici is a Senior Java Architect with a long Java experience in the industrial field. He runs Tidalwave, his own consultancy company, and has contributed to Java success stories in a number of fields, including Formula One. Fabrizio often appears as a speaker at international Java conferences such as JavaOne and Devoxx and is member of JUG Milano and the NetBeans Dream Team. Fabrizio is a DZone MVB and is not an employee of DZone and has posted 67 posts at DZone. You can read more from them at their website. View Full User Profile

Releasing for JSE, NetBeans Platform and OSGi in a Single Shot

09.16.2009
| 8156 views |
  • submit to reddit

Generating the NBM for the NetBeans Platform

Also this artifact is created by a specific module (it-tidalwave-imageio-raw, which is the exact name of the .nbm artifact it's going to produce), whose pom is the following:

<?xml version="1.0" encoding="UTF-8"?>
<project ... >

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>it.tidalwave.imageio</groupId>
<artifactId>jrawio</artifactId>
<version>1.6.0-SNAPSHOT</version>
</parent>

<artifactId>it-tidalwave-imageio-raw</artifactId>
<packaging>nbm</packaging>
<name>jrawio - NBM artifact</name>

<dependencies>
<dependency>
<groupId>it.tidalwave.imageio</groupId>
<artifactId>it.tidalwave.imageio.raw</artifactId>
<version>1.6.0-SNAPSHOT</version>
</dependency>
<!-- These dependencies with 'provided' scope won't be embedded in the .nbm -->
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>it.tidalwave.imageio</groupId>
<artifactId>codec</artifactId>
<version>1.6.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>it.tidalwave.imageio</groupId>
<artifactId>processor</artifactId>
<version>1.6.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>nbm-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<publicPackages>
<publicPackage>it.tidalwave.imageio</publicPackage>
<publicPackage>it.tidalwave.imageio.arw</publicPackage>
<publicPackage>it.tidalwave.imageio.cr2</publicPackage>
<publicPackage>it.tidalwave.imageio.crw</publicPackage>
<publicPackage>it.tidalwave.imageio.dcr</publicPackage>
<publicPackage>it.tidalwave.imageio.decoder</publicPackage>
<publicPackage>it.tidalwave.imageio.dng</publicPackage>
<publicPackage>it.tidalwave.imageio.io</publicPackage>
<publicPackage>it.tidalwave.imageio.makernote</publicPackage>
<publicPackage>it.tidalwave.imageio.minolta</publicPackage>
<publicPackage>it.tidalwave.imageio.mrw</publicPackage>
<publicPackage>it.tidalwave.imageio.nef</publicPackage>
<publicPackage>it.tidalwave.imageio.orf</publicPackage>
<publicPackage>it.tidalwave.imageio.pef</publicPackage>
<publicPackage>it.tidalwave.imageio.raf</publicPackage>
<publicPackage>it.tidalwave.imageio.raw</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.arw</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.cr2</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.crw</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.demosaic</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.dng</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.mrw</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.nef</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.orf</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.pef</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.raf</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.raw</publicPackage>
<publicPackage>it.tidalwave.imageio.rawprocessor.srf</publicPackage>
<publicPackage>it.tidalwave.imageio.srf</publicPackage>
<publicPackage>it.tidalwave.imageio.tiff</publicPackage>
<publicPackage>it.tidalwave.imageio.util</publicPackage>
</publicPackages>
</configuration>
</plugin>
</plugins>
</build>
</project>

This looks a bit more complex, but you'll find out that it's just more verbose.

First, note that we are depending on it.tidalwave.imageio.raw, since the job of merging all the classes in a single jar has been performed by that module. After all we're creating a wrapper module around the JSE artifact.

Now, you should notice all these dependencies with scope=provided. Why are they here? The problem is that the nbm-maven-plugin, by default, puts into the artifact all the transitive dependencies; so it would put not only it.tidalwave.imageio.raw, but also codec, processor (and the annotations for jsr305, that are used in the code); scope=provided tells the plugin to not embed them.

Now we have to declare the public packages that will be exported by the nbm artifact. Instead of the OSGi bundler, that accepts wildcards to specify subpackages, we have to enumerate them one by one.

Other parameters are not specified in the pom, but in a specific configuration file, which is placed under src/main/nbm/module.xml:

<nbm>
<moduleType>normal</moduleType>
<codeNameBase>it.tidalwave.imageio.raw/1</codeNameBase>
<cluster>libraries</cluster>
<manifest>src/main/nbm/manifest.mf</manifest>
<homepageUrl>http://jrawio.rawdarkroom.org</homepageUrl>
<author>Fabrizio Giudici</author>
<licenseName>Apache License, Version 2.0</licenseName>
<licenseFile>../../LICENSE.txt</licenseFile>
</nbm>
  • codeNameBase. The fully qualified, unique id of the produced artifact.
  • homePageURL. The URL of the project.
Some more options are specific to the NBM protocol, which is richer than OSGi:
  • moduleType. This is related to the life-cycle of the NetBeans Platform modules.
  • cluster. Clusters are a way that the NetBeans project uses to pack together similar modules. It could be unneeded for single libraries, anyway I've got the habit of putting libraries in a cluster with the same name.
  • author. The author of the code.
  • licenseName. The name of the license.
  • licenseFile. The full text of the license.

I'm not an expert of OSGi yet. I can't exclude that similar attributes are also available in the OSGi world.

In addition to those items of information, I also need to put or override some attributes in the NBM manifest; on that purpose, I can just specify them in a fragment of MANIFEST.MF that is pointed by the manifest entry:

OpenIDE-Module-Java-Dependencies: Java > 1.5
OpenIDE-Module-Display-Category: Libraries
OpenIDE-Module-Name: Libraries - jrawio
AutoUpdate-Show-In-Client: true

Everything that is in this fragment won't be overridden by the plugin. The produced manifest is:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: fritz
Build-Jdk: 1.5.0_20
Implementation-Build: 86e32fde717a+
OpenIDE-Module-Java-Dependencies: Java > 1.5
OpenIDE-Module-Display-Category: Libraries
OpenIDE-Module-Name: Libraries - jrawio
AutoUpdate-Show-In-Client: true
OpenIDE-Module-Specification-Version: 1.6.0
OpenIDE-Module-Implementation-Version: 1.6.0-20090916
OpenIDE-Module-Build-Version: 200909161113
OpenIDE-Module: it.tidalwave.imageio.raw/1
OpenIDE-Module-Public-Packages: it.tidalwave.imageio.*, it.tidalwave.i
mageio.arw.*, it.tidalwave.imageio.cr2.*, it.tidalwave.imageio.crw.*,
it.tidalwave.imageio.dcr.*, ...
OpenIDE-Module-Requires: org.openide.modules.ModuleFormat1
OpenIDE-Module-Short-Description: Camera raw support in Java
OpenIDE-Module-Long-Description: Camera raw support in Java
Class-Path: ext/it.tidalwave.imageio.raw-1.6.0-SNAPSHOT.jar
As you can see by looking at the Class-Path attribute, we have generated a wrapper module - that is, it just embeds the original jar, adding another manifest. There are different solutions, such as creating a regular nbm, or even re-using the existing jar, where the OpenIDE-Module-* attributes have been added to the manifest. This sounds as extremely interesting, as it would allow me to release a single jar artifact for all the three environments; but I've still to learn a few details (in particular, the co-existence with OSGi stuff), and furthermore I preferred this intermediate step for testing (I just replaced the Maven-generated jrawio nbm in blueMarine and checked that everything still worked). Any improvement will go in future versions of jrawio.
Published at DZone with permission of Fabrizio Giudici, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Fabrizio Giudici replied on Wed, 2009/09/16 - 12:14pm

An important integration, to save a headache. In order to have the nbm-maven-plugin to work, you need this in the pom:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<useDefaultManifestFile>true</useDefaultManifestFile> <!-- required since nbm-plugin 3.0-->
</configuration>
</plugin>
</plugins>
</build>

You don't see this section in the above examples since in jrawio it has been configured in the master pom.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.