[RSS]

What is a library wrapper module and how do I use it?

If your module uses some external library, you will probably use a wrapper module to make classes from that library available to your module at runtime.

A wrapper module is a module that contains no code - really the only significant thing about it is its manifest, which does two significant things, in addition to the standard module unique ID/version/etc.:

  • Has a Class-Path entry for one or more jars in the subdirectory ext/ of the directory where the module is
  • Declares OpenIDE-Module-Public-Packages followed by a list of the packages from the library that other modules should be able to used

Starting with NB 5.0 you can simply use File | New Project | NetBeans Plug-in Modules | Library Wrapper Module Project to make a library wrapper.

So a wrapper module acts as a proxy to turn a library into a NB module. Since you can't modify the NetBeans classpath directly (nor would you want to), this is the way you let your code use third party libraries. It serves the same function that running with java -cp or setting CLASS_PATH would do in a smaller Java application.

There are other options for packaging libraries described in when to use a wrapper module.

If the above was confusing, read the module dependencies FAQ entry.

Using a wrapper module for an existing project.

If you are developing the library yourself, but decide you want to keep the library project separate from any NB module project, you can do so. Just make a plain Java project for the library and build it; and also create a library wrapper module from its JAR output. Here are two ways to hook them up. The first modifies the project so that when the project is built, it copies the jar to the wrapper module. The second modifies the wrapper module so that the wrapper cleans, builds and picks up the jar.

Method 1

To hook them up (since the library wrapper module wizard just copies the JAR you select), you can make the plain Java project (j2seproject) build into the wrapper. Say your j2seproject is in e.g./src/suite/libs/foo and your NBM wrapper is in /src/suite/foo-wrapper; just edit /src/suite/libs/foo/nbproject/project.properties to specify e.g.:
dist.jar=../../foo-wrapper/release/modules/ext/foo.jar

Now you can just build the j2seproject and it will update the wrapper's JAR file. Also code completion on anything that compiles against the foo library should "see" sources in /src/suite/libs/foo/src (so long as the j2seproject is open).

Method 2

Here's how to have the wrapper module build, clean and pick up the JAR from the j2seproject's original location with source association (even if the j2seproject is not open!). You modify the wrapper's project.xml (to adjust the <class-path-extension>), project.properties (to specify ${extra.module.files} and build.xml (to override the release target) as shown in the following example. harness/README gives the details. See also issue #70894, which would make it easier.

Example: Having the wrapper module clean and build the project.

With these changes to a wrapper module, build/clean on the wrapper, or on the module suite that contains the wrapper, also does build/clean on the project.

For this example, my-wrapper is a library wrapper module for the jar file produced by the regular Java project called my-project. my-project and my-wrapper are in the same directory; this only affects relative path specifications and is not a general requirement. This example was created on NetBeans 5.5. If you have jars from multiple projects in a wrapper, then this example is extended by using <antsub> instead of <ant> and a FileSet in the release target's <copy> task.

Only the my-wrapper project needs modification.

First

In my-wrapper/nbproject/project.xml, change <class-path-extension>'s <binary-origin> to reference the jar created by my-project. This change gives code-completion with javadoc and go-to-source when referencing my-project.
    <binary-origin>../my-project/dist/my-project.jar</binary-origin>

Make sure a ../src directory (relativly to the jar location) containing the corresponding sources of the library exist if you want go to source functionnality of netbeans works.

Second

In my-wrapper/nbproject/project.properties specify where my-project's jar file is installed in the suite's cluster. This puts my-project.jar in the wrapper's NBM; it is needed since the wrapper's release directory is no longer used as a staging area.
extra.module.files=modules/ext/my-project.jar

Third

Delete the directory my-wrapper/release. The original jar file was copied here when the wrapper was created. It will interfere if it is left around.

Fourth

In my-wrapper/build.xml add the following. Customize the first two properties' value= to specify your project's relative location and jar. The release target is replaced; now it builds my-project then copies the jar to the suite's cluster. The clean target first cleans as usual, then cleans my-project.
<property name="original.project.dir" value="../my-project"/>
<property name="original.project.jar"
          value="${original.project.dir}/dist/my-project.jar"/>

<target name="release">
    <echo message="Building ${original.project.dir}"/>
    <ant dir="${original.project.dir}"
         target="jar" inheritall="false" inheritrefs="false"/>
    <echo message="Done building ${original.project.dir}"/>

    <copy todir="${cluster}/modules/ext"
          file="${original.project.jar}"/>
</target>


<target name="clean" depends="projectized-common.clean">
    <echo message="Cleaning ${original.project.dir}"/>
    <ant dir="${original.project.dir}"
         target="clean" inheritall="false" inheritrefs="false"/>
    <echo message="Done cleaning ${original.project.dir}"/>
</target>