DevFaqWrapperModules

(Difference between revisions)
(Added 3rd method)
(fixes build when j2seproject depends on other j2seproject, see also http://www.symphonious.net/2010/01/25/ant-subant-and-basedir/)
 
(6 intermediate revisions not shown)
Line 14: Line 14:
So a wrapper module acts as a proxy to turn a library into a NB module.
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 ([[DevFaqNetBeansClasspath | DevFaqNetBeansClasspath]]),
+
Since you can't modify the NetBeans classpath directly ([[DevFaqNetBeansClasspath]]),
nor would you want to,
nor would you want to,
this is the way you let your code use third-party libraries.
this is the way you let your code use third-party libraries.
Line 30: Line 30:
do so. Just make a plain Java project for the library and build it;
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
and also create a library wrapper module from its JAR output. Here are
-
three ways to hook them up.
+
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
-
* The first modifies the project so that when the project is built, it builds the target jarfile directly in the wrapper-module's target directory instead of in the original project's <tt>dist</tt> directory copies the jar to the wrapper module.
+
second modifies the wrapper module so that the wrapper cleans, builds
-
 
+
and picks up the jar.
-
* The second modifies the wrapper module so that the wrapper cleans, builds and picks up the jar.
+
-
 
+
-
* The third modifies the library project's <tt>build.xml</tt> to copy the library jarfile to into the wrapper-module's target directory, replacing the (outdated) copy already residing there.
+
-
 
+
-
The first and third methods may be considered '''push''' methods that work to push the new jarfile to the wrapper module whenever the library gets rebuilt; the second method may be considered a '''pull''' method where you have to remember to rebuild the wrapper-module whenever you rebuild the library.
+
-
 
+
-
{|- border="1"
+
-
!
+
-
!Pro
+
-
!Con
+
-
|- valign="top"
+
-
|Method 1
+
-
| Wrapper module automatically updated when the library gets rebuilt; nothing to remember.
+
-
| The library jarfile is no longer available in the library/<tt>dist</tt> directory for other external projects or components.
+
-
|- valign="top"
+
-
|Method 2
+
-
| No changes needed to the library project.
+
-
| Must remember to rebuild wrapper module whenever the library gets rebuilt.
+
-
|- valig="top"
+
-
|Method 3
+
-
| Wrapper module automatically updated when the library gets rebuilt; nothing to remember.
+
-
| Library project's <tt>build.xml</tt> gains an awareness of the wrapper-module's location, meaning that changes to directory locations may break the library-project build.
+
-
|}
+
-
 
+
-
===Method 1===
+
 +
===Method 1 <br>===
To hook them up (since the library wrapper module wizard just
To hook them up (since the library wrapper module wizard just
copies the JAR you select), you can make the plain Java SE project
copies the JAR you select), you can make the plain Java SE project
Line 76: Line 52:
<tt>/src/suite/libs/foo/src</tt> (so long as the Java SE project is open).
<tt>/src/suite/libs/foo/src</tt> (so long as the Java SE project is open).
-
===Method 2===
+
===Method 2 <br>===
-
 
+
Here's how to have the wrapper module build/clean the Java SE project
-
Here's how to have the wrapper module build, clean and pick
+
and then pick
-
up the JAR from the Java SE project's original location with source
+
up the JAR from the Java SE project's original location. This method provides
-
association (even if the Java SE project is not open!). You  
+
source association (even if the Java SE project is not open!). You  
-
modify the wrapper's
+
modify a few things in the wrapper project
-
<tt>project.xml</tt> (to adjust the <tt><class-path-extension></tt>),
+
# <tt>project.xml</tt>         <br/>adjust the <tt><class-path-extension></tt>
-
<tt>project.properties</tt> (to specify <tt>extra.module.files</tt>)
+
# <tt>project.properties</tt> <br/> specify <tt>extra.module.files</tt>
-
and <tt>build.xml</tt> (to override the <tt>release</tt> target)
+
# remove the wrapper's release directory
-
as shown in the following example. <tt>harness/README</tt> gives the details.
+
# <tt>build.xml</tt>           <br/> to override the <tt>release</tt> target
 +
The following example demonstrates these steps.
 +
<tt>harness/README</tt> gives the details.
See also {{iz|70894}}, which would make it easier.
See also {{iz|70894}}, which would make it easier.
-
===Method 3===
+
====Example using method 2: Having the wrapper module clean and build the project====
-
Add the following target to the <tt>build.xml</tt> for the '''library''' project:
+
-
<pre>
+
-
<target name="-post-jar">
+
-
    <copy todir="../model-wrapper/release/modules/ext">
+
-
        <fileset dir="${dist.dir}" includes="*.jar"/>
+
-
    </copy>
+
-
</target>
+
-
</pre>
+
-
(Adjust the <tt>todir</tt> attribute in the <tt>copy</tt> task to match the correct directory for your wrapper-module.)
+
-
 
+
-
===Examples===
+
-
 
+
-
====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.
+
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, <tt>my-wrapper</tt> is a library wrapper module for the JAR file produced by the regular Java project called <tt>my-project</tt>. <tt>my-project</tt> and <tt>my-wrapper</tt> are in the same directory; this only
+
For this example, <tt>my-wrapper</tt> is a library wrapper module for the JAR file
-
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 <tt><antsub></tt> instead of <tt><ant></tt> and a <tt>FileSet</tt> in the <tt>release</tt>
+
produced by the regular Java project called <tt>my-project</tt>.
 +
<tt>my-project</tt> and <tt>my-wrapper</tt> 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
 +
<tt><antsub></tt> instead of <tt><ant></tt> and a <tt>FileSet</tt> in the <tt>release</tt>
target's <tt><copy></tt> task.
target's <tt><copy></tt> task.
''Only the <tt>my-wrapper</tt> project needs modification.''
''Only the <tt>my-wrapper</tt> project needs modification.''
-
=====First=====
+
====First====
In <tt>my-wrapper/nbproject/project.xml</tt>, change  
In <tt>my-wrapper/nbproject/project.xml</tt>, change  
<tt><class-path-extension></tt>'s <tt><binary-origin></tt> to
<tt><class-path-extension></tt>'s <tt><binary-origin></tt> to
Line 124: Line 96:
library exists if you want Go to Source functionality to work.''
library exists if you want Go to Source functionality to work.''
-
=====Second=====
+
====Second====
In <tt>my-wrapper/nbproject/project.properties</tt> specify where
In <tt>my-wrapper/nbproject/project.properties</tt> specify where
<tt>my-project</tt>'s JAR file is installed in the suite's cluster. This
<tt>my-project</tt>'s JAR file is installed in the suite's cluster. This
Line 133: Line 105:
</pre>
</pre>
-
=====Third=====
+
====Third====
Delete the directory <tt>my-wrapper/release</tt>. The original JAR file was
Delete the directory <tt>my-wrapper/release</tt>. The original JAR file was
copied here when the wrapper was created.
copied here when the wrapper was created.
''It will interfere if it is left around.''
''It will interfere if it is left around.''
-
=====Fourth=====
+
====Fourth====
In <tt>my-wrapper/build.xml</tt> add the following.  Customize the first
In <tt>my-wrapper/build.xml</tt> add the following.  Customize the first
two properties' <tt>value=</tt> to specify your project's relative location and JAR.
two properties' <tt>value=</tt> to specify your project's relative location and JAR.
Line 151: Line 123:
<target name="release">
<target name="release">
     <echo message="Building ${original.project.dir}"/>
     <echo message="Building ${original.project.dir}"/>
-
     <ant dir="${original.project.dir}"
+
     <ant dir="${original.project.dir}" usenativebasedir="true"
         target="jar" inheritall="false" inheritrefs="false"/>
         target="jar" inheritall="false" inheritrefs="false"/>
     <echo message="Done building ${original.project.dir}"/>
     <echo message="Done building ${original.project.dir}"/>
Line 162: Line 134:
<target name="clean" depends="projectized-common.clean">
<target name="clean" depends="projectized-common.clean">
     <echo message="Cleaning ${original.project.dir}"/>
     <echo message="Cleaning ${original.project.dir}"/>
-
     <ant dir="${original.project.dir}"
+
     <ant dir="${original.project.dir}" usenativebasedir="true"
         target="clean" inheritall="false" inheritrefs="false"/>
         target="clean" inheritall="false" inheritrefs="false"/>
     <echo message="Done cleaning ${original.project.dir}"/>
     <echo message="Done cleaning ${original.project.dir}"/>
Line 179: Line 151:
===How do I include more that one jar in my library wrapper module? ===
===How do I include more that one jar in my library wrapper module? ===
-
As explained in this [http://www.netbeans.org/servlets/ReadMsg?listName=nbusers&msgNo=64026 mail] and in this [http://www.netbeans.org/source/browse/apisupport/harness/release/Attic/README?rev=1.64&hideattic=0&view=markup README] the library wrapper creation wizard will only add one jar. To add more you need to copy the jars to release/modules/ext/ and edit nbproject/project.xml to add extra <class-path-extension> elements.  
+
With the library wrapper creation wizard it's possible to choose more than one jar (use the CTRL key to select more than one file in the file dialog). Or enter absolute file paths divided by the path separator (e.g. ; for windows systems) into the (very small) file input field.
-
<pre>
+
To add later more, use the project's properties dialog.
-
          <class-path-extension>
+
-
              <runtime-relative-path>ext/extra1.jar</runtime-relative-path>
+
-
              <binary-origin>release/modules/ext/extra1.jar</binary-origin>               
+
-
          </class-path-extension>
+
-
          <class-path-extension>
+
-
              <runtime-relative-path>ext/extra2.jar</runtime-relative-path>
+
-
              <binary-origin>release/modules/ext/extra2.jar</binary-origin>
+
-
          </class-path-extension>
+
-
</pre>
+
----
----
-
Applies to: NetBeans 5.5, 6.x
+
Applies to: NetBeans 6.8 and later

Current revision as of 15:53, 29 November 2010

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, conventionally 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 use.

You can use File > New Project > NetBeans Modules > Library Wrapper Module 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 (DevFaqNetBeansClasspath), 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 CLASSPATH would do in a smaller Java application.

There are other options for packaging libraries described in DevFaqWhenUseWrapperModule.

If the above was confusing, read DevFaqModuleDependencies.

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 SE project build into the wrapper. Say your Java SE project 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 Java SE project 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 Java SE project is open).

Method 2

Here's how to have the wrapper module build/clean the Java SE project and then pick up the JAR from the Java SE project's original location. This method provides source association (even if the Java SE project is not open!). You modify a few things in the wrapper project

  1. project.xml
    adjust the <class-path-extension>
  2. project.properties
    specify extra.module.files
  3. remove the wrapper's release directory
  4. build.xml
    to override the release target

The following example demonstrates these steps. harness/README gives the details. See also Issue 70894, which would make it easier.

Example using method 2: 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 (relative to the JAR location) containing the corresponding sources of the library exists if you want Go to Source functionality to work.

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}" usenativebasedir="true"
         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}" usenativebasedir="true"
         target="clean" inheritall="false" inheritrefs="false"/>
    <echo message="Done cleaning ${original.project.dir}"/>
</target>

How do I include native libraries (*.so or *.dll) in my library wrapper module?

Some libraries come with a native counterpart. The current Library Wrapper wizard doesn't cater to this. As per the JNI section in this document, you simply need to create a lib directory under <my-wrapper>/release/modules (which gets created by the wizard), alongside the ext directory mentioned earlier in this document. This directory is where you place your native libraries.

How do I include more that one jar in my library wrapper module?

With the library wrapper creation wizard it's possible to choose more than one jar (use the CTRL key to select more than one file in the file dialog). Or enter absolute file paths divided by the path separator (e.g. ; for windows systems) into the (very small) file input field.

To add later more, use the project's properties dialog.


Applies to: NetBeans 6.8 and later

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo