// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= DevFaqWrapperModules
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqWrapperModules
:description: Apache NetBeans wiki DevFaqWrapperModules
:toc: left
:toc-title:
:syntax: true

=== 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 (link:DevFaqNetBeansClasspath.asciidoc[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 link:DevFaqWhenUseWrapperModule.asciidoc[DevFaqWhenUseWrapperModule].

If the above was confusing, read link:DevFaqModuleDependencies.asciidoc[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.:

[source,java]
----

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 , 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`.

[source,xml]
----

<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.

[source,java]
----

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`.

[source,xml]
----

<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 link:http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#jni[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.

<hr/>
Applies to: NetBeans 6.8 and later

=== Apache Migration Information

The content in this page was kindly donated by Oracle Corp. to the
Apache Software Foundation.

This page was exported from link:http://wiki.netbeans.org/DevFaqWrapperModules[http://wiki.netbeans.org/DevFaqWrapperModules] , 
that was last modified by NetBeans user Mwisnicki 
on 2010-11-29T15:53:52Z.


*NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed.
