INTRODUCTION
------------

This build harness permits modules outside of the netbeans.org CVS tree to be
built against a NetBeans-based application: the NB platform, the NB IDE, or any
derivative product. The semantics of configuration files is synchronized with
the NBM project type module, so that you can open any module in the NB IDE and
work with it naturally: build and test it using Ant, use Java code completion,
and so on.

Questions and comments should go to: dev@openide.netbeans.org

BASIC FILE LAYOUT
-----------------

Within the netbeans.org CVS tree, modules are detected as projects of the "NBM"
(NetBeans module) type. The project directory may be top-level (e.g. "beans"),
second-level (e.g. "ant/project"), or third-level (e.g.
"objectbrowser/navigator/javanavigation"). The project.xml for the project must
specify

    <type>org.netbeans.modules.apisupport.project</type>

to indicate that it is an NBM project, and the configuration must be

    <data xmlns="http://www.netbeans.org/ns/nb-module-project/2">

Note that this schema is a change from the /1 schema used in NetBeans 4.0 and
4.1. (As of this writing, the XML schema is not yet published externally, but it
will be soon.)

Outside of the netbeans.org CVS tree, modules can take two forms. They may be
marked with

    <standalone/>

in which case they can build into a platform binary but not refer to any other
source modules. Or they may be marked with

    <suite-component/>

in which case they are contained within a module suite. The suite enumerates
modules it contains, and each module points back to the suite that contains it.

The meaning of the project.xml elements, as well as property names in
project.properties and other files, will be discussed later.

The project directory should contain "manifest.mf" (more on this later),
"build.xml" (more later), a directory "src" with the main package root of the
module's classes, optionally "test/unit/src" with unit tests, and perhaps some
other files.

If there is a subdirectory "javahelp" it is used to keep JavaHelp documentation,
which will be built automatically.

If there is a file "module-auto-deps.xml" it will automatically be used to
upgrade modules depending on you to new dependencies, as described in the
Modules API.

STANDALONE MODULES: CONFIGURATION FILES
---------------------------------------

Standalone modules may keep configuration in several properties files, in the
following order of loading:

${basedir}/nbproject/private/platform-private.properties
${basedir}/nbproject/platform.properties
${user.properties.file}
[definition of 'harness.dir' and 'netbeans.dest.dir' based on value of ${nbplatform.active}]
${basedir}/nbproject/private/private.properties
${basedir}/nbproject/project.properties

The properties 'harness.dir' and 'netbeans.dest.dir' must be defined by the
project. Usually this is accomplished by defining the property
'nbplatform.active' in platform.properties, and ${user.properties.file}
(normally build.properties in the user directory, usually defined in
platform-private.properties) can define properties like
'nbplatform.NAME.netbeans.dest.dir' (this would be used for 'netbeans.dest.dir'
in case ${nbplatform.active} had the value 'NAME').

MODULE SUITES: CONFIGURATION FILES
----------------------------------

Modules in a suite have a slightly more complicated list of properties files in
which they may keep configuration:

${basedir}/nbproject/private/suite-private.properties
${basedir}/nbproject/suite.properties
${suite.dir}/nbproject/private/platform-private.properties
${suite.dir}/nbproject/platform.properties
${user.properties.file}
[definition of 'harness.dir' and 'netbeans.dest.dir' based on value of ${nbplatform.active}]
${basedir}/nbproject/private/private.properties
${basedir}/nbproject/project.properties

'suite.dir' is normally defined in suite-private.properties (or suite.properties
in case it is a relative path). platform-private.properties and
platform.properties are then used to define the NB platform in the same way as
for standalone modules.

The suite itself (the project located in ${suite.dir}) can load properties from:

${basedir}/nbproject/private/platform-private.properties
${basedir}/nbproject/platform.properties
${user.properties.file}
[definition of 'harness.dir' and 'netbeans.dest.dir' based on value of ${nbplatform.active}]
${basedir}/nbproject/private/private.properties
${basedir}/nbproject/project.properties

It must define a property 'modules' enumerating modules it contains (in path
format, with each entry being a module project directory). This is usually done
in project.properties, perhaps also with private.properties to help with
absolute paths.

USING A RELATIVE PATH FOR THE PLATFORM WITH A MODULE SUITE
----------------------------------------------------------

Though not directly supported by the GUI, it is possible to set up a module
suite in such a way that the path to the NetBeans platform is given as relative,
and sharable in VCS. This may be helpfully especially for multi-developer teams
who frequently develop against new NetBeans builds (or build NetBeans from CVS
sources). You need to:

1. Make sure that each module's suite.properties specifies 'suite.dir' as
relative to its base directory, not as a bare relative path, e.g.

    suite.dir=${basedir}/..

2. Edit the suite's platform.properties to give a fallback value for 'suite.dir'
(so the suite's own master build script can work), and define *both*
netbeans.dest.dir and harness.dir in terms of the suite directory, e.g.:

    suite.dir=${basedir}
    netbeans.dest.dir=${suite.dir}/../nb_sources/nbbuild/netbeans
    harness.dir=${netbeans.dest.dir}/harness

The platform.properties should *not* define 'nbplatform.active' in this case.

Relative-path source and Javadoc associations for the platform is not yet
supported in this scenario (#70876). Each developer with a checkout of the suite
may need to configure a platform (with an arbitrary name) in the NetBeans
Platform Manager dialog with a binary location matching the value you gave for
${netbeans.dest.dir}, and with source and/or Javadoc associations of their
choice. However, as a convenience, special associations may be predefined in the
IDE in the special case that the destination directory is the subsubdirectory
"nbbuild/netbeans" of a netbeans.org CVS checkout (i.e. if you build NetBeans
from sources and then build your suite against that).

"CHAINING" SUITES (INTER-SUITE DEPENDENCIES HOWTO)
--------------------------------------------------

Suppose you have one platform P1, say the bare NetBeans Platform. Then you have
a module suite S1 with modules M1a...M1z which uses P1. Now it may happen that
you want another suite S2 with modules M2a...M2z to depend on S1 as well as P1.
This is possible, though not yet trivial to set up. Basically, you will make a
new platform P2 by building S1 + P1. Here's what you need to do in brief:

1. Set up S1 with P1 in the normal way.

2. Edit S1/build.xml to include a target to make a platform P2. For example:

    <target name="create-platform" depends="build-zip">
        <mkdir dir="${p2}"/>
        <unzip src="dist/${app.name}.zip" dest="${p2}"/>
    </target>

where S1/nbproject/project.properties or S1/nbproject/private/private.properties
defines:

    p2=...path.../myplatform

Note that the ZIP will currently contain S1's ${app.name} as its top-level dir,
so you can either move the unpacked files up one dir, or use the dir p2/s1name
as the actual platform location.

3. Now configure S2 to use P2 as its platform. If an absolute path, you can use
the Platform Manager, else for relative paths see the preceding section.

4. To associate sources with binaries for P2, you will need to use the Platform
Manager. You can select multiple source associations. In this case, use a
netbeans.org CVS checkout or source download for the P1 (NetBeans platform)
portion of P2, and use S1 (the suite directory) for the M1a...M1z modules in P2.

5. In an S2 module like M2a you should be able to depend on any module in P2,
including both NetBeans modules and modules from S1 like M1a. Code completion,
popup Javadoc, etc. should work if source associations have been correctly
configured in step #5.

6. In case S1 was an application module with configured branding, you might wish
to use S1's launchers in S2 rather than making a new app for S2. Or, in place of
a suite S2 you might have a standalone module M2. In either case, you can use
S1's launchers by making sure that the 'bin/' and 'etc/' directories get copied
into the P2 platform (i.e. do not specifically exclude them in step #2); and
configure nbproject/project.properties in S2 (or standalone module M2):

    run.app.exe=bin\\s1.exe
    run.app.sh=bin/s1

where 's1' was the branding name you chose for S1. This will permit Run, Reload,
etc. on S2 and its modules like M2a, or standalone module M2, to work correctly.

netbeans.org MODULES: CONFIGURATION FILES
-----------------------------------------

Modules inside the netbeans.org CVS tree need not define a platform; it is
always "nbbuild/netbeans" in the CVS tree. They also do not have an explicit
harness; they use various files located in "nbbuild". Unlike external modules
which by default always use the cluster "devel", netbeans.org modules usually
specify a cluster in "nbbuild/cluster.properties" ("extra" by default).

PLATFORM DEFINITIONS
--------------------

The file build.properties in the user directory is used to store all information
about NetBeans platforms. Each platform has an ID string; the default platform's
ID is 'default'. The available properties for each platform are:

1. nbplatform.ID.netbeans.dest.dir (mandatory) - absolute path to the
destination directory (i.e. NetBeans platform installation).

2. nbplatform.ID.harness.dir (mandatory) - path to the build harness. Normally
will be "${nbplatform.ID.netbeans.dest.dir}/harness".

3. nbplatform.ID.sources (optional) - see next section.

4. nbplatform.ID.javadoc (optional) - see next section.

SOURCE AND JAVADOC ASSOCIATIONS
-------------------------------

Modules inside the netbeans.org CVS tree need not do anything special to
associate sources with binaries (the module JAR files under "nbbuild/netbeans");
it is automatic. Javadoc may be associated with an API-providing module just by
building its Javadoc (into "nbbuild/build/javadoc"), or by downloading the
NetBeans API Documentation module, which will cause 'nbplatform.default.javadoc'
to be defined in build.properties in the user directory (to the location of a
ZIP of Javadoc).

For external modules, sources and Javadoc may be associated with the active
platform by defining in build.properties in the user directory these properties:

1. nbplatform.ID.sources - an Ant-style path (e.g. ':' separated) containing
source roots you wish to associate with the binary modules in
${nbplatform.ID.netbeans.dest.dir}. Entries may be a checkout of the
netbeans.org CVS tree, or source roots of other module suites which are included
in the platform in binary form. Defining a source association permits you to
step through sources while debugging, use Go To Class, get popup Javadoc in code
completion, etc.

2. nbplatform.ID.javadoc - a path containing roots of Javadoc for API-providing
modules in the platform. Useful in case you wish to get Javadoc in View |
Documentation Indices; or in the code completion popup (if you do not have
sources). Each root may be a directory or a ZIP file. Within a root, the API for
org.netbeans.modules.foo is expected to be inside the subdir named
"org-netbeans-modules-foo".

For examples of complete and functioning "external" module suites, see
apisupport/project/test/unit/data/example-external-projects in netbeans.org
sources.

FORMAT OF YOUR project.xml's MAIN CONFIGURATION SECTION
-------------------------------------------------------

You must specify the "code name base" of your module. This is the value of
OpenIDE-Module in manifest.mf, *except* without any major release version (e.g.
"/1"). In the future OpenIDE-Module might be generated from this, but not yet.

    <code-name-base>org.netbeans.modules.foo</code-name-base>

For external modules, you must specify either <suite-component/> or
<standalone/>; for netbeans.org modules, you must not. See above discussion of
file layout.

Specify your dependencies on other modules:

    <module-dependencies>
        <dependency>
            <!-- The code name base, *not* with any major release version: -->
            <code-name-base>some.other.module</code-name-base>
            <!-- Usually, include this to say that it needs to be built -->
            <!-- *before* your module, if in the same suite: -->
            <build-prerequisite/>
            <!-- Usually also include this, to say that it needs to be in your module's classpath: -->
            <compile-dependency/>
            <!-- Always include this, to say that the module system should register a dependency: -->
            <run-dependency>
                <!-- Optional; use if and only if the other module uses e.g. /1 in its code name: -->
                <release-version>1</release-version>
                <!-- Optional; request a minimum version of another module: -->
                <specification-version>3.9</specification-version>
            </run-dependency>
        </dependency>
        <!-- and others as you need them... -->
        <!-- use org.openide for openide.jar -->
    </module-dependencies>

In a <run-dependency> you can also use just

    <implementation-version/>

in place of <specification-version>, meaning to declare an implementation
dependency on another module. The actual version is taken directly from that
module's current JAR so you do not need to keep track of it. *Important*: if you
either *export* or *import* any implementation dependencies, you should probably
use spec.version.base (see below).

Declare any public API/SPI packages you export:

    <public-packages>
        <package>org.netbeans.api.foo</package>
        <package>org.netbeans.spi.foo</package>
    </public-packages>

If you do not export any API, say so:

    <public-packages/>

If you export an API to selected modules only, you can use (NB 5.0+ only!):

    <friend-packages>
        <friend>org.netbeans.modules.brother</friend>
        <package>org.netbeans.modules.foo.spi</package>
    </friend-packages>

If you bundle a special library which you want to expose to modules depending on
you, you need not enumerate every package explicitly:

    <public-packages>
        <subpackages>javax.foo</subpackages>
    </public-packages>

Exported implementation "APIs" do not need to be declared; anyone depending on
your module with an implementation dependency gets access to *all* your
packages. Be careful and avoid this situation whenever possible.

If your module bundles one or more third-party libraries, declare them:

    <class-path-extension>
        <!-- Deployed path, relative to dir containing module: -->
        <runtime-relative-path>ext/foolib.jar</runtime-relative-path>
        <!-- Path of library in your own sources, relative to project basedir: -->
        <binary-origin>external/foolib.jar</binary-origin>
    </class-path-extension>

You still need to separately copy the JAR to the output directory (see below).
This just declares that Class-Path in your module's manifest should be defined,
and adds a compile-time classpath entry for your module and modules depending on
it.

If your bundled library is built from sources, just use

    <class-path-extension>
        <runtime-relative-path>ext/foolib.jar</runtime-relative-path>
    </class-path-extension>

Sometimes a module will produce some extra JARs (in modules/ext/ for Class-Path,
in ant/nblib/, etc.), or will just need to have some extra sources for
miscellaneous purposes (e.g. custom Ant tasks). You can declare them, somewhat
similarly to how freeform projects permit compilation units to be declared; you
will still need to explicitly compile and JAR them in your build.xml. For
example, for in-IDE automatic Ant tasks you might use:

    <extra-compilation-unit>
        <!-- Root of Java packages, relative to project basedir: -->
        <package-root>antsrc</package-root>
        <!-- Compile-time classpath: -->
        <classpath>${ant.home}/lib/ant.jar:${openide.dir}/core/openide.jar</classpath>
        <!-- Places where classes are deposited: -->
        <built-to>build/antclasses</built-to>
        <built-to>${cluster}/ant/nblib/${code.name.base.dashes}.jar</built-to>
    </extra-compilation-unit>

Or for a Class-Path extension built from sources, you might use:

    <extra-compilation-unit>
        <package-root>libsrc</package-root>
        <classpath/>
        <built-to>build/libclasses</built-to>
        <built-to>${cluster}/modules/ext/foolib.jar</built-to>
    </extra-compilation-unit>

A custom Ant task (or set of tasks) you use only during your own build might
look like:

    <extra-compilation-unit>
        <package-root>antsrc</package-root>
        <classpath>${ant.home}/lib/ant.jar</classpath>
        <built-to>build/antclasses</built-to>
        <built-to>build/tasks.jar</built-to>
    </extra-compilation-unit>

Note that <classpath> may contain Ant property references, so for a complex
classpath, define it once in project.properties and use that property in
<classpath> as well as in your Ant script.

If you export some API (declared in <public-packages> or <friend-packages>) and
wish to be able to build Javadoc, just specify

    <javadoc/>

PROPERTIES WHICH MAY BE DEFINED IN YOUR project.properties
----------------------------------------------------------

If needed, these properties may also be defined in private.properties (to make
them applicable to only your own checkout of sources). Only selected properties
are listed here; others may be interpreted, but see the Ant script for details.

Unless otherwise noted, properties listed here *are* available for use in
selected fields in project.xml, *are* available for use in your build.xml
(depend on some init target to make sure), and *are not* available for use when
defining other properties in project.properties (unless you defined them in
private.properties).

basedir - you cannot define this; it is always the project directory of the
module (as in any Ant script). Available in all other properties files.

build.classes.dir - "build/classes", used to send compiled classes to.

build.compiler.debug - default "true" to include debugging info when compiling
(needed if you want to step through sources).

build.compiler.debuglevel - default "source,lines,vars" to include all debugging info.

build.compiler.deprecation - default "true" to display deprecation warnings when
compiling. If you want to disable deprecations, it is recommended you use
private.properties:

    build.compiler.deprecation=false

build.test.unit.classes.dir - "build/test/unit/classes", where unit tests are
compiled to.

buildnumber - generated timestamp for use in
OpenIDE-Module-Implementation-Version (or OpenIDE-Module-Build-Version if
OpenIDE-Module-Implementation-Version was explicitly defined in the manifest).

cluster - cluster directory your module is to be built into. For netbeans.org
modules, this is a subdirectory of nbbuild/netbeans/; the subdirectory name is
defined automatically from nbbuild/cluster.properties, with a fallback to
"extra". For suite component modules, it defaults to
"${suite.dir}/build/cluster", though you could override it if you wanted (e.g.
in platform.properties); similarly, for standalone modules, it defaults to
"${basedir}/build/cluster". Available in project.properties for netbeans.org
modules only.

code.name.base.dashes - your code name base as org-netbeans-modules-foo

code.name.base.slashes - ditto, as org/netbeans/modules/foo

cp.extra - extra JARs you have to compile module sources against. Rarely needed
any more.

extra.module.files - list of special files you build alongside your module JAR
which you want to register for update tracking and include in your NBM.
*Everything* you put into your cluster should be enumerated. Paths are relative
to the cluster directory. Example:

    extra.module.files=\
        ext/foolib.jar,\
        docs/FooAPI.zip

(You do *not* need to include: the module JAR itself; your JavaHelp JAR if you
build one; your module declaration file; any module-auto-deps.xml; an
ant/nblib/*.jar corresponding to your module; or any files in ${release.dir}.
These are all included by default.)

foo/bar.dir - absolute path of cluster directory to which the netbeans.org
module "foo/bar" is built. Only defined for netbeans.org modules, and only if
foo/bar was *already* built before yours (specify <build-dependency/>).
Available in project.properties.

harness.dir - location of the build harness (for external modules). Usually
"${netbeans.dest.dir}/harness".

is.autoload and is.eager - default false, but if true, make this module an
autoload or eager module.

javac.compilerargs [since 5.0u1] - default none; additional arguments to pass
to the Java compiler, e.g. "-Xlint:unchecked".

javac.source - default "1.4"; to use JDK 1.5 features like generics:

    javac.source=1.5

javac.target - default ${javac.source}; controls version of generated bytecode

javadoc.apichanges - optional location of an API changes list. Currently for
netbeans.org modules only.

javadoc.arch - optional location of an architecture XML description. Highly
recommended as it makes your module self-documenting.

    javadoc.arch=${basedir}/arch.xml

javadoc.overview - optional location of a Javadoc overview page. Discouraged
since it disables the default content which links to various generated documents
which you would need to manually add to your own overview.

javadoc.title - title for Javadoc build. Optional for external modules.
DEPRECATED since 5.0u1; taken from other module metadata.

javahelp.base - "${code.name.base.slashes}/docs" by default; directory
containing your help set, under "javahelp/".

javahelp.excludes - optionally, list of file name patterns to exclude from
JavaHelp search index construction.

javahelp.jar - "modules/docs/${code.name.base.dashes}.jar". Do not override.
Constructed from ${javahelp.jar.basename} and ${javahelp.jar.dir}.

javahelp.search - "JavaHelpSearch" by default; name of search database
directory, relative to your help set. Must match what your help set specifies.

jhall.jar - for external modules, if you wish to build JavaHelp, you must define
the location of jhall.jar from the JavaHelp distribution, as this is needed to
run the search indexer. DEPRECATED since 5.0u1; the 5.0u1 harness now includes
jsearch-*.jar so you do not need to specify this property any longer.

keystore - Key store for signing NBMs. A candidate for private.properties - you
do *not* want to share this file! Also ${nbm_alias} and ${storepass} are used in
the NBM signing process.

license.file - optional. Location of license text to use when creating an NBM.
(External modules only.)

manifest.mf - JAR manifest location. Avoid overriding.

module.auto.deps.xml - "module-auto-deps.xml" in your project directory by
default. Optional configuration file.

module.classpath - your main module source's compile-time classpath, according
to <module-dependencies>. Since 5.0u1 uses public-package-only JARs where
appropriate.

module.run.classpath [since 5.0u1] - your main module source's run-time
classpath, according to <module-dependencies>. Currently identical to
${module.classpath} except does not use public-package-only JARs.

module.jar - location of module JAR relative to cluster directory. Do not
override directly; override ${module.jar.basename} (default
"${code.name.base.dashes}.jar") and/or ${module.jar.dir} (default "modules") if
necessary (not without a good reason!).

module.javadoc.packages - comma-separated list of packages to be included in
Javadoc. Defaulted according to <public-packages> or <friend-packages>, but if
you used <subpackages> (or if you have not specified any public or friend
packages at all) you will need to specify it explicitly.

nbm.distribution - optional URL to location where your NBM can be downloaded
from.

nbm.homepage - optional URL to HTML homepage for background about the module.

nbm.is.global - set to "true" if NBM cannot be installed in user directory.

nbm.module.author - author info for an NBM.

nbm.needs.restart - set to "true" if NBM cannot be installed (even for the first
time) without restarting the IDE.

nbplatform.active - optional name of a NB platform to build and run against. See
discussion above for details of how this is used.

netbeans.dest.dir - absolute pathname of NB platform (or IDE or whatever) that
you are building your module against, and into which your module will be built.
Available in project.properties (and in all properties files for netbeans.org
modules).

netbeans.home - location of "platform*" cluster of the NetBeans IDE installation
you are running. *Only defined* when you run an Ant script *inside* the IDE.

nbjdk.active [since 5.0u1] - name of a Java platform (JDK) to use when building
and running. Will try to load (e.g. from ${userdir}/build.properties, where Java
Platform Manager stores its information) the properties

    nbjdk.home=${platforms.${nbjdk.active}.home}
      - JDK (not JRE!) home directory
    nbjdk.bootclasspath=${platforms.${nbjdk.active}.bootclasspath}
      - JRE JARs, e.g. rt.jar (default: ${nbjdk.home}/jre/lib/rt.jar)
    nbjdk.java=${platforms.${nbjdk.active}.java}
      - java executable (default: ${nbjdk.home}/bin/java)
    nbjdk.javac=${platforms.${nbjdk.active}.javac}
      - javac executable (default: ${nbjdk.home}/bin/javac)
    nbjdk.javadoc=${platforms.${nbjdk.active}.javadoc}
      - javadoc executable (default: ${nbjdk.home}/bin/javadoc)

if they are not already defined. Uses <presetdef> to make <java>, <javac>,
<javadoc>, <junit>, and <nbjpdastart> use this JDK. Optional; if unset (or set to
'default'), will use the current VM's Java platform instead. Define in
platform.properties (in a standalone module, or in the suite for a suite component
module, or in nbbuild/user.build.properties for a netbeans.org module). You may
also define just ${nbjdk.home} directly, without using ${nbjdk.active}, if you do
not need to use the Java Platform Manager to set up the JDK definition.

release.dir - "${basedir}/release"; location of a directory full of files to
copy unmodified to the output cluster.

run.app.exe - "bin\nb.exe"; name of Windows launcher to start (inside
${netbeans.dest.dir}) if trying to run the application for interactive testing.
Only relevant if ${app.name} is unset.

run.app.sh - "bin/netbeans"; same but for Unix (and Mac OS X).

run.args.extra - empty; any added arguments to pass to the launcher.

run.jdkhome - location of JDK to run application with for interactive testing.
Defaults to JDK the Ant script was using, or that selected by ${nbjdk.active}.
DEPRECATED - for compatibility only. Use ${nbjdk.active} instead.

spec.version.base - this is a little subtle. If you export an implementation
dependency to other modules, *and/or* depend on one or more other modules using
implementation dependencies, you are advised to use this property *in place of*
writing OpenIDE-Module-Specification-Version explicitly in your manifest. It
should be a dotted number to serve as the base of a specification version; keep
the number of components *fixed* even if you branch the module, so e.g. in a
development version use

    spec.version.base=1.7.0

and if you need to increment this in a release branch use e.g.

    spec.version.base=1.7.1

The harness will automatically append integers to it as follows to create the
actual specification version:

1. Your OpenIDE-Module-Implementation-Version, if specified and an integer.

2. The OpenIDE-Module-Implementation-Version of modules you depend on using
implementation dependencies, if integers; ordered by alphabetizing the
dependencies.

(Example: if you have impl version 3, and you depend on org.netbeans.modules.foo
= 6 and org.netbeans.modules.bar = 7, your actual spec version would be
1.7.0.3.7.6.)

This is very handy for Auto Update: whenever you or anyone else makes a change
to an implementation API, just increment the
OpenIDE-Module-Implementation-Version of the providing module. That module and
any modules depending on its API will get a higher
OpenIDE-Module-Specification-Version automatically, so the whole set of
interdependent modules can be published to users at once on an update center.

src.dir - "src", module source directory. Avoid overriding.

test.unit.cp.extra - any additional classpath you might need to compile your
unit tests. If left empty, you can compile against JUnit; the NB test extensions
in nbjunit.jar; your module; and anything your module compiled against (since
5.0u1, ${module.run.classpath}).

    test.unit.cp.extra=\
        ${netbeans.dest.dir}/ide6/modules/some-module-used-in-tests.jar:
        ${basedir}/lib/custom-junit-helpers.jar

test.unit.run.cp.extra - any additional classpath you might need to *run* your
unit tests with (beyond what they are already compiled with). E.g. to make sure
org.openide.filesystems.FileUtil.toFileObject works reliably:

    test.unit.run.cp.extra=\
        ${netbeans.dest.dir}/platform6/modules/org-netbeans-modules-masterfs.jar

test.unit.lib.cp - path to some basic libraries which can be used in unit tests:
junit.jar, nbjunit.jar, and insanelib.jar. Not needed for netbeans.org modules.
For external modules, may be needed if you do not have the junit and testtools
modules installed in the target platform *or* the developing IDE, and the target
platform is not inside a netbeans.org build tree (in nbbuild/netbeans).

test.unit.src.dir - "test/unit/src"; avoid overriding.

test-unit-sys-prop.<NAME> - will set a system property <NAME> when running your
unit tests.

tools.jar [since 5.0u1] - set to location of tools.jar in active JDK. Useful in
case your module needs to compile against JDK-only classes. Meaningless on Mac
OS X.

To support builds of JNLP based applications (described at 
http://installer.netbeans.org/docs/jnlpInstaller.html) additional may be used 
or redefined in JNLP-related targets:

jnlp.servlet.jar - must point to jnlp-servlet.jar as provided by JDK 1.5 in
  the directory sample/jnlp/servlet/jnlp-servlet.jar if one wants to build 
  a packaged war file of JNLP version of your suite

jnlp.dest.dir - the location where to generate the JNLP files and signed 
  jars. By default it is your ${suite.dir}/build/jnlp

jnlp.master.dir - (category='private') is the location of the directory where
  to generate pieces of master jnlp file that get's then included in its resources
  section

jnlp.signjar.alias -
jnlp.signjar.keystore - 
jnlp.signjar.password - allow you to sign your app with your own private key, if
  unspecified then a default keystore is generated. Nice for trying things for
  the first time, but not for production, then you very likely want to generate
  your key and set these properties
jnlp.signjar.vendor - you can override this to be the default dname for the keystore

jnlp.platform.codebase - can point to a shared repository which can be generated
  by ant -f nbbuild/build.xml build-jnlp Then your war file will contain only 
  modules of your suite and platform modules will be referenced by value of this
  property

jnlp.verify.excludes - the default implementation of "jnlp" task in common.xml
  does verification and compares that all files from module NBM are really
  referenced from the JNLP file. Sometimes not all of them need to be, for
  them you can put their full names (relative to your cluster root) into this
  property and separate them by comma.

[XXX some of the above should be listed in "Suite Properties"]


TARGETS AVAILABLE FOR OVERRIDING IN YOUR build.xml
--------------------------------------------------

Obscure or mostly internal targets are skipped here, but again examine the
actual harness script if in doubt. If you want to keep the original
implementation and just add a before hook, try e.g.

    <target name="-pre-javahelp">
        <!-- your stuff here -->
    </target>
    <target name="javahelp" depends="-pre-javahelp,harness.javahelp"/>

(some original targets are projectized-common.* rather than harness.*). If you
want to add an after hook, try e.g.

    <target name="javahelp" depends="harness.javahelp">
        <!-- your stuff here -->
    </target>

basic-init - define some properties such as file locations; enough to do a clean
at least.

build-init - define more properties needed for compiling and other build tasks.

clean - remove all build products: the "build" directory under your project
directory, and any files left in the build cluster (including
${extra.module.files}).

compile - compile Java sources for the module.

compile-single - compile selected Java sources (F9).

compile-test-single - compile selected unit test classes (F9).

debug - build module and then start target platform in debug mode. Use from
within the IDE (there is a context menu item for it) to debug the app.

debug-fix-nb - loads a hotfix for a module class while debugging. Run -> Apply
Code Changes from the IDE.

debug-fix-test-nb - same, for unit test classes.

debug-test-single-nb - run one single unit test in the debugger (e.g. to see why
it is failing). Available from the IDE's menus.

files-init - define list of files in the NBM fileset. Use ${extra.module.files}
rather than overriding this.

init - all normal initialization.

jar - build the module JAR.

jar-prep - prepare to build the module JAR; define ${buildnumber}.

javadoc - build module Javadoc.

jnlp - generetes the JNLP component file for this module and all necessary
  resources for it into ${jnlp.dest.dir} directory and also a fragment of
  the master JNLP into ${jnlp.master.dir}

javadoc-nb - same, and open it in a web browser (only from the IDE). Available
as Build -> Generate Javadoc.

javahelp - build JavaHelp.

nbm - build the NBM. You might override this to give a complex (multipart)
license text. Copy basic impl from common.xml and edit.

netbeans - build everything needed for the NBM. Do not override; use
netbeans-extra instead.

netbeans-extra - hook target: does nothing unless overridden, but called when
building a module. Override to insert any additional build tasks you need to do:
copying libraries to the cluster, etc.

profile - used from inside the IDE (if the NetBeans profiler is installed) to
profile the entire application.

profile-test-single-nb - run one unit test under the profiler. Available from the
IDE's menus if the NetBeans profiler is installed.

release - copies contents of ${release.dir} to ${cluster}.

reload - reloads the module in the target IDE/app to try out changes interactively.

reload-in-ide - reloads the module in the current IDE to try out changes
interactively. Only available when run from inside NetBeans. Use with care.

run - build module and then run application interactively. Only for external
modules. Either way, available from context menu in Projects tab.

test - run all unit tests for the module. Run -> Test... in the IDE.

test-build - build unit tests for the module.

test-init - define properties used for building and running unit tests.

test-preinit - I'm not sure, actually.

test-single - run a selected unit test only. Available in the IDE's menus.

testuserdir-delete - deletes just the testing user directory (if not currently in use).

verify-class-linkage [since 5.0u1] - checks for possible linkage errors in your module
and its Class-Path extensions.

SUITE PROPERTIES
----------------

Some properties are shared with module projects, such as ${cluster}.

app.name - filename of application launchers to create, suite name to create,
etc.

branding.dir (default "${suite.dir}/branding") - directory containing branding
overrides.

branding.token - optional token defining an application branding.

enabled.clusters - comma-separated list of cluster names in the target platform
(e.g. "platform6") which should be included in the application. Should be stored
in platform.properties, not project.properties. Since 5.0u1.

disabled.clusters - comma-separated list of cluster names in the target platform
(e.g. "ide6") which should be completely excluded from the application.
DEPRECATED since 5.0u1 in favor of ${enabled.clusters} and ignored if that is nonempty.

disabled.modules - comma-separated list of code name bases of modules in the
target platform (e.g. "org.netbeans.modules.autoupdate") which should be
excluded from the application. There is no need to specify modules already
excluded by ${disabled.clusters} (if used) or by modules from clusters not included
in ${enabled.clusters}. Since 5.0u1, should be stored in platform.properties,
not project.properties.

modules - list of contained modules. Path format; entries resolved against the
suite directory as needed.

jnlp.codebase [since 5.0u1] - in case one wants to build a static repository not
packaged in a WAR file, one needs to pass in the full URL for it. By default it
is specified as "$$codebase" and replaced dynamically by the servlet packaged in
the WAR file.


TARGETS AVAILABLE FOR OVERRIDING IN YOUR SUITE build.xml
--------------------------------------------------

-init - set up properties. Most importantly, ${modules.sorted} contains a list
of absolute path names to the base directories of the modules in the suite,
topologically sorted by build order; suitable for use with <subant>, for
example. Some other basic properties like ${netbeans.dest.dir} will also be
defined.

branding - building branding JARs, if applicable. Example: if ${branding.token}
is "foo", then a file such as

    ${branding.dir}/modules/org-netbeans-modules-x.jar/org/netbeans/modules/x/resources/Bundle.properties

will be packed into

    ${cluster}/modules/locale/org-netbeans-modules-x_foo.jar!/org/netbeans/modules/x/resources/Bundle_foo.properties

build - build all suite modules.

build-jnlp - builds the JNLP war file with your application

clean - clean everything.

debug - like run, but run in the JPDA debugger. (Only available from inside the
IDE.)

debug-jnlp - starts debuging of your JNLP application (works only from NetBeans IDE)

nbms [since 5.0u1] - creates NBMs for all modules in the suite, and generates
an XML descriptor listing them suitable for use from Auto Update.

profile - used from inside the NetBeans IDE to profile the entire suite

run - start application for testing.

run-jnlp - executes your JNLP application (currently from local files)

testuserdir-delete - deletes just the testing user directory (if not currently in use).

CONTENTS OF YOUR manifest.mf
----------------------------

This file is just a prototype of the module JAR manifest, as described in the
Modules API. It must contain the attribute OpenIDE-Module and is strongly
encouraged to contain also OpenIDE-Module-Localizing-Bundle; other attributes
are generally optional.

Several attributes in the main section should *not* be written into this file as
they are automatically generated during the build:

    Class-Path
    OpenIDE-Module-Build-Version
    OpenIDE-Module-Friends
    OpenIDE-Module-IDE-Dependencies
    OpenIDE-Module-Implementation-Version (unless you are exporting an impl API)
    OpenIDE-Module-Module-Dependencies
    OpenIDE-Module-Public-Packages
    OpenIDE-Module-Specification-Version (unless you are *not* using spec.version.base)

Do not forget that manifest files must begin with the magic phrase

    Manifest-Version: 1.0

and to be safe should end in *two* newlines.

UPGRADING FROM NETBEANS 4.0/4.1
-------------------------------

Upgrading an NBM project from an older 4.x version of NetBeans is not trivial
but should not pose too much difficulty once you get the hang of it. (A tool may
be provided in the future to do it for you.)

1. Switch to the /2 XML schema for project.xml *and validate the result* to make
sure it is syntactically correct. Delete any <javadoc/> element.

2. Delete the <path> element from project.xml. Add <suite-component/> or
<standalone/> for an external module.

3. For externally located modules in a suite, create a module suite project and
refer to it from suite.properties; for standalone external modules, just create
platform.properties with "nbplatform.active=default". Delete build.xml and open
the project to create a default version (which you can edit as needed to
override some targets); opening the project should also make you a
build-impl.xml and set 'user.properties.file' in suite-private.properties or
platform-private.properties.

4. Some targets that used to be defined in projectized.xml are now imported
indirectly from common.xml, so overrides like

    <target name="compile" depends="projectized.compile">...</target>

must be changed to

    <target name="compile" depends="projectized-common.compile">...</target>

Targets currently moved to common.xml:

    -pre-debug-fix
    arch
    arch-nb
    basic-init
    clean
    compile
    compile-single
    compile-test-single
    debug-fix-nb
    debug-fix-test-nb
    debug-test-single
    debug-test-single-nb
    do-debug-test-single
    files-init
    jar (*)
    jar-prep
    module-auto-deps
    module-xml-autoload
    module-xml-eager
    module-xml-regular
    nbm
    netbeans
    netbeans-extra
    reload
    test
    test-build
    test-init
    test-preinit
    test-single

(*) 'jar-no-module-deps' and 'jar-with-module-deps' were replaced with just
'jar'. If you are overriding this target, be sure to use the new
<jarwithmoduleattributes> task which predefines a number of useful manifest
attributes for you.

5. Clean out unnecessary stuff from manifest.mf: remove all substituted values
(@SOMETHING@), and pay attention to these attributes in particular:

5a. OpenIDE-Module-Specification-Version - still OK, but if you import and/or
export implementation dependencies, you may prefer to define spec.version.base
in project.properties (see above).

5b. OpenIDE-Module-Implementation-Version - still OK, *if* you are exporting an
implementation dependency, but now strongly encouraged to be a literal integer.

5c. OpenIDE-Module-Build-Version - delete; it will be inserted by the build
harness automatically.

5d. Class-Path - delete and use <class-path-extension>s in project.xml instead.

5e. OpenIDE-Module-IDE-Dependencies, OpenIDE-Module-Module-Dependencies,
OpenIDE-Module-Public-Packages - you should not have been using these to begin
with, but if you were, delete them now: the harness generates them for you as
appropriate.

6. Avoid use of cp.extra in project.properties if possible. In most cases it is
no longer necessary: any <class-path-extension>s you define, or which are
defined by a module you declare a compile-time dependency on, will automatically
be inserted into your classpath for you.

Currently there is no clean way to declare inter-module unit test dependencies,
but this may be added in the future. For now, use ${test.unit.cp.extra} and/or
${test.unit.run.cp.extra} (see above).

7. Do not override files-init; it is rarely necessary any more. Instead specify
extra.module.files in project.properties. Or for files you are just copying
unmodified, just put them in the correct folder structure beneath a subdirectory
called "release".

8. Delete any complicated build.xml tricks to handle implementation
dependencies. Just declare the dependency normally in project.xml using
<implementation-version/> (and use ${spec.version.base}, above) and you are
done.

9. Remove any special definitions relating to Rich Unger's "cluster harness",
which is obsoleted by this new system.

10. Consider using <friend-packages> instead of <public-packages> if you want to
export a limited API without using implementation dependencies. *Will not work
in NB 4.1, only 5.0+.*

11. Do not pick an explicit name for your module; accept
modules/${code.name.base.dashes}.jar. It can be autoload or eager just by
setting properties in project.properties, without using modules/autoload or
modules/eager.

12. All properties of the form ${nb.*.dir} were removed and replaced by the
literal directory name. For example, ${nb.modules.dir} is now just "modules". Be
careful - some names were tricky, e.g. ${nb.lib.dir} was "core", and
${nb.bin.dir} and ${nb.lib/ext.dir} were both "lib"!

13. ${netbeans.dest.dir}/${cluster.dir} should be replaced by just ${cluster}.

14. Have fun!


----------------
Hey Emacs!
Local Variables:
fill-column: 80
End:
