Using GNU make for Java

This article will document the development of a reusable template based makefile for developing java projects.

The target makefile will require GNU Make and a GNU or similar shell because that's all I need. It isn't terribly difficult to expand this to be more portable by leveraging GNU Makes portability for the task.

The primary goal of any build tool is to be to run `make' or equivalent and once it has completed be guaranteed to have a complete an accurate build in less time than it would take to start from scratch. `make clean' or equivalent should only be required when debugging the build system itself. The build tool should be usable, that is someone can write and understand the configuration file. Any errors which cause the build to fail should be clear and easy to decipher in the output (as far as the given compiler allows it to be).

Whilst this is not always easy to achieve these goals, it should always be possible and when it works it saves time and thus money as well as developer frustration.

One of the most common Java build tools `ant' typically fails at these goals either through by design or omission.

Note that all makefile snippets have been reformatted for HTML and will not work in make directly. This is a shortcoming of HTML. Spaces in filenames and paths are not supported either. Just don't do this.

(GNU) make features

GNU Make introduces some features which allow it to be extended beyond shell scripting for extensibility. Apart from some useful filename manipulation functions it include meta-programming features which can be used to create compact extensions which are easy to use.

Some of the more important functions and features of make and/or GNU make used in the following sections are introduced here.

$(if test,output)

This substitutes the output text if the test passes.

This is used to build dynamic command lines which add the required switches when a variable is non-empty. For example when constructing a jar file the sequence `-C directory files...' is used and if can be used to omit the parameters if the file list is empty.

$(subst from,to,input)

The subst command substitutes sub-string patterns within a string with another piece of text.

This is used to remove or add components, such as stripping `.java' from filenames.

$(patsubst pattern,replacement,text)

This performs a sub-string pattern based replacement operation on elements of a list. In make all variables are lists where items are delineated by whitespace.

This is used to transform a list of names to output variants and to add or strip directory path components.

$(filter patterns, list)

Returns a new list with only those words matching one of the patterns included.

This is used to search for common prefixes or suffixes amongst a list of filenames.

$(strip input)

This strips leading and trailing spaces and collapses all internal whitespace to a single space. This is to clean up configured values and to make writing the makefiles easier.

$(shell command arguments)

Executes a shell command. This is the same as the back-tick operator but arguably more readable.

$(foreach var,list,text)

Binds var to each word in list and applies it to text.

This is used to iterate over lists as is typically the case.

parallel builds

Using `-j n' will allow 'n' make jobs to be executed concurrently. This is an automatic feature available when using GNU Make provided the makefile is written correctly.

GNU Make Meta Programming

In addition several important functions are used to meta-programme make. This is using templates and macros to create new makefile `source code' on the fly.

$(eval text)

Evaluates the text as a function and then treats it as makefile source-code inserted at that point.

define blah= ... end

Defines a macro / template. Arguments can be passed and referrenced using $1, $2, etc.

$(call var,param,...)

Invoke a macro with the given arguments.

Basic make templates for java

This chapter will define the templates used for each component of a java build. It will first define some commonly used mechanisms and then define each target in turn.

Due to makefile escape syntax some of this can be quite unreadable but none of them are very long. i.e. `$' must be escaped by `$$'.

Makefile Structure

The user of the makefile will define where the source code and resources reside, and then include `java.make' which will expand to all the steps required to achieve those goals.

All resources are define using a syntax similar to Automake.

# Lists all programs to be compiled, these are then referenced by prefix
java_PROGRAMS=proga progb ...

# define programme `proga' sources
proga_JAVA_SOURCES=...

# define programme `progb' sources
progb_JAVA_SOURCES=...

And so on.

In all the following cases `$1' refers to the first macro argument which will be the name of the target (`proga', etc).

Common Tasks

Here are some common tasks which crop up throughout the following chapters. definition.

finding files

This just uses the shell command to invoke find.

  $1_FILES= $$(if $$($1_DIRS),$$(shell find $$(SEARCH_DIRS) -name '*.java'))

This will find all files ending in 'java' from the given search root. If $1_DIRS is not defined then it does nothing.

creating optional arguments

This uses the $(if ) command to add additional tokens, or add nothing at all.

  ... \
  $$(if $$($1_CLASSPATH),-cp $$($1_CLASSPATH)) \
  ...

If the variable is not defined or empty, then this does nothing, otherwise it adds the necessary switches to the command.

building paths

This uses the $(subst) command to replace spaces with a path separator token. It also exposes a rather nasty quirk of (GNU) Make in how to define a single-space token. Spaces are used by GNU Make to separate individual word tokens in all lists so this tasks is quite common.

# global
E:=
S:=$(E) $(E)

# use
$1_CLASSPATH:=$$(subst $$(S),:,$$(strip $$($1_JAVA_LIBS)))

S is defined to be a single space. The above is the recommended way to define such a symbol.

The usage first strips the variable of extraneous spaces and then substitues any remaining with the given string - in this case ':'. For extra portability the ':' could also be a variable.

removing path prefixes

This uses $(foreach), $(filter), and $(patsubst) to iterate, select, and redefine strings to remove (or add) path prefix components. Make only understands file names so all files are defined relative to the Makefile location. For one example, jar files on the other hand require that the class files reflect the package name and this mechanism can be used to rewrite the names appropriately.

jar ... \
  $$(foreach dir,$$($1_JAR_RESOURCE_DIRS),$$(patsubst $$(dir)/%,-C $$(dir) %,\
    $$(filter $$(dir)/%,$$($1_JAR_RESOURCES) $$($1_JAR_GENERATED))))

Given a list of possible prefixes this will replace any filename with a package-relative path name preceeded by a change-directory (-C dir) argument to jar.

Shared Definitions

First, some project-global variables are defined. These combine all user-supplied definitions into useful common variables.

# Java source code for compiling and packaging
$1_JAVA_GENERATED += $$(if $$($1_JAVA_GENERATED_DIRS),$$(shell find $$($1_JAVA_GENERATED_DIRS) -name '*.java'))
$1_JAVA_SOURCES += $$(if $$($1_JAVA_SOURCES_DIRS),$$(shell find $$($1_JAVA_SOURCES_DIRS) -name '*.java'))
$1_JAVA_DIRS += $$($1_JAVA_SOURCES_DIRS) $$($1_JAVA_GENERATED_DIRS)

# Resources for the jar file
$1_JAR_GENERATED += $$(if $$($1_JAR_GENERATED_DIRS),$$(shell find $$($1_JAR_GENERATED_DIRS) -type f))
$1_JAR_RESOURCES += $$(if $$($1_JAR_RESOURCES_DIRS),$$(shell find $$($1_JAR_RESOURCES_DIRS) -type f))
$1_JAR_DIRS += $$($1_JAR_RESOURCES_DIRS) $$($1_JAR_GENERATED_DIRS)

$1_CLASSPATH:=$$(subst $$(S),:,$$(strip $$($(1)_JAVA_LIBS)))

# Test variables
$1_TEST_JAVA_GENERATED += $$(if $$($1_TEST_JAVA_GENERATED_DIRS),$$(shell find $$($1_TEST_JAVA_GENERATED_DIRS) -name '*.java'))
$1_TEST_JAVA_SOURCES += $$(if $$($1_TEST_JAVA_SOURCES_DIRS),$$(shell find $$($1_TEST_JAVA_SOURCES_DIRS) -name '*.java'))
$1_TEST_JAVA_DIRS += $$($1_TEST_JAVA_SOURCES_DIRS) $$($1_TEST_JAVA_GENERATED_DIRS)

$1_TEST_CLASSPATH:=$$(subst $$(S),:,$$(strip $$($1_JAVA_LIBS) $$($1_TEST_JAVA_LIBS) $(BUILD)/$(1) $(junit4)))

# Some common names for ``readability''
$1_NAME:=$(1)$$($1_VERSION)
$1_JAR:=$(BIN)/$$($1_NAME).jar
$1_DOC:=$(BIN)/$$($1_NAME)-doc.jar
$1_SRC:=$(BIN)/$$($1_NAME)-src.jar
$1_BIN:=$(BIN)/$$($1_NAME)-bin.tar.gz

DIST_EXTRA_MAKE += $$($(1)_DIST) $$($(1)_JAVA_SOURCES) $$($(1)_JAR_RESOURCES) $$($(1)_JAR_LIBS) $$($(1)_JAVA_LIBS) $$($1_TEST_JAVA_SOURCES)

While voluminous they are straighforward enough.

Compiling Classes

This chapter defines a template used to build normal source code into class files.

$(BUILD)/$(1).built: $$($1_JAVA_SOURCES) $$($1_JAVA_GENERATED) $$($1_JAVA_LIBS) $$($1_JAVA_FILES)
        -rm -rf $(BUILD)/$(1)
        mkdir -p $(BUILD)/$(1)
        javac $$(if $$($1_CLASSPATH),-cp $$($1_CLASSPATH)) \
                $$($1_JAVA_FLAGS) \
                -d $(BUILD)/$(1) \
                $$($1_JAVA_SOURCES) $$($1_JAVA_GENERATED)
        touch $(BUILD)/$(1).built

Yep, that's it. Bit of a let-down after all that build-up and preparation but you'll be seeing a lot more of this if you make it to the end (pun intended). Most of the shell command use one might expect from a makefile is replaced by the GNU Make built-in functions.

In this specific case unfortunately there is an impedence mismatch here between java and make. make expects a single object/target file to be created for each source/input file. java on the other hand may create any number of generated .class files for a given .java source file. This means that without additional parsing - which may be more expensive than the compilation itself - there is no way to determine an accurate list of dependencies and targets to allow for incremental compilation.

This makefile side-steps the issue by simply recompiling everything and using a tag to track success or failure. This only applies to the given module and incremental compilation is still possible at a higher level. It does at least only invoke javac once for all source files so is much faster than the naive (and utterly broken) approach of specifying one class per one java dependencies as you would with c object and source.

Incremental compilation in the jdk is on the future roadmap and when that becomes available this can be revisited. All other tools are too error prone to be considered useful at this time.

Features

In addition to compiling the user-defined list of source files (or source root directories) this target supports make-time generated source files via the prog_JAVA_GENERATED and prog_JAVA_GENERATED_DIRS variables. Build rules for these can be defined in the caller makefile in the normal way.

prog_JAVA_FILES is an addition mechanism used to indicate the build is stale. These files are not included automatically but may be additional arguments via prog_JAVA_FLAGS. For example to use annotation processors.

Building jars

Creating a basic jar file is more or less equivalent to running tar or zip except the stored paths must reflect the package names and not necesssarily the file names.

$$($1_JAR): $(BUILD)/$(1).built $$($1_JAR_RESOURCES) $$($1_MANIFEST) $$($1_JAR_FILES) $$($1_JAR_LIBS)
        mkdir -p $(BIN)
        $$(if $$($1_MANIFEST),cp $$($1_MANIFEST) $(BUILD)/$(1).manifest,echo -n "" > $(BUILD)/$(1).manifest)
        $$(if $$($1_JAR_LIBS),echo "Class-Path: $$($(1)_JAR_LIBS)" >> $(BUILD)/$(1).manifest)
        jar cfm $$@ $(BUILD)/$(1).manifest \
                $$($1_JAR_FLAGS) \
                -C $(BUILD)/$(1) . \
                $$(foreach dir,$$($1_JAR_RESOURCE_DIRS),$$(patsubst $$(dir)/%,-C $$(dir) %,\
                        $$(filter $$(dir)/%,$$($1_JAR_RESOURCES) $$($1_JAR_GENERATED)))) \
                 || (rm $$@ ; exit 1)
JAR_LIST += $$($1_JAR)

This target has to do a little more actually.

First it must generate a manifest file. This may be a combination of user-supplied manifest part and an autogenerated part. For convenience the makefile automatically creates the class-path manifest element.

Then it must include all compiled classes and resources. The compiled classes are already in the correct layout as generated by the javac command in the last step. The resources on the other hand need to be mapped from their source-tree location to their in-jar location. For efficiency and accuracy the makefile rule does not need to first stage the jar but reads the resources directly from original locations and uses the $(foreach ) block to achieve this.

Because the jar file is an explicit build target it is tracked in the JAR_LIST variable.

Features

As with the compilation step this also supports compile-time generated resource inclusion. It works the same way.

It also supports prog_JAR_FILES as a mechanism to force recompilation.

A detail not readily apparent is that this handles some poor behaviour by the jar command. If any file is missing or if it encounters any other error it leaves the incomplete and unusable jar file intact. This will errornously allow make to continue on a subsequent invocation as the target will have been updated as far as it is concerned. To account for this the jar file is forcibly removed if the jar command returns an error code.

Java Docs

Running javadoc in a portable way is somewhat tricky as it has many arguments some of which have changed over time. This is just one set of arguments which works for me, but most could be moved to the user level Makefile via prog_JAVADOC_FLAGs.

$$($(1)_DOC): $$($(1)_JAVA) $$($(1)_JAVA_SOURCES) $$($(1)_JAVA_GENERATED) $$($(1)_JAVADOC_FILES)
        -rm -rf $(BUILD)/$(1)-doc
        mkdir -p $(BUILD)/$(1)-doc $(BIN)
        javadoc -locale en_AU -charset UTF-8 \
                -quiet -use \
                $$($1_JAVADOC_FLAGS) \
                -d $(BUILD)/$(1)-doc $$($(1)_JAVA) $$($(1)_JAVA_SOURCES) $$($(1)_JAVA_GENERATED)
        jar cf $$@ -C $(BUILD)/$(1)-doc . || (rm $$@ ; exit 1)
DOC_LIST += $$($(1)_DOC)

Features

Not much to be said, this generates the javadoc and jars it up. It handles the broken-jar case properly.

It includes generated source code and auxilliary make dependencies.

TODO

This is hardcoded to my locale, because well, it seemed like a good idea at the time. Multiple locale support would require some adjustments.

Java Sources

Given this is a Free Software build system, sources are one of the core features. It provides a `sources' target which creates an ide-compatible source jar and includes all generates sources.

$$($(1)_SRC): $$($(1)_JAVA_SOURCES) $$($(1)_JAVA_GENERATED) $$($(1)_JAVA_RESOURCES) $$($(1)_SOURCES_FILES)
        mkdir -p $(BIN)
        jar cf $$@ \
                $$(foreach dir,$$($(1)_JAVA_DIRS),$$(patsubst $$(dir)/%,-C $$(dir) %,\
                        $$(filter $$(dir)/%,$$($1_JAVA_SOURCES) $$($1_JAVA_GENERATED)))) \
                $$(foreach dir,$$($(1)_JAR_RESOURCE_DIRS),$$(patsubst $$(dir)/%,-C $$(dir) %,\
                        $$(filter $$(dir)/%,$$($1_JAR_RESOURCES) $$($1_JAR_GENERATED)))) \
         || (rm $$@ ; exit 1)
SRC_LIST += $$($(1)_SRC)

Features

This just reads all the source files directly in-place, no staging is required.

Generated sources are automatically included.

TODO

Perhaps it needs to support additional jar arguments and auxiliary files such as COPYING.

JUnit Tests

No build system is complete without testing. Some basic rules are included for building and running JUnit4 tests.

First, some global definitions. The first is not meant to be portable but can be overriden by the callee makefile.

junit4 ?= /usr/local/netbeans-8.0/platform/modules/ext/junit-4.10.jar
junit4_runner ?= org.junit.runner.JUnitCore

And the templates.

$(BUILD)/$(1)-test.built: $(BUILD)/$(1).built $$($(1)_TEST_JAVA_SOURCES) $$($(1)_TEST_JAVA_GENERATED) $$($(1)_TEST_JAVA_LIBS) $$($(1)_TEST_JAVA_FILES)
        -rm -rf $(BUILD)/$(1)-test
        mkdir -p $(BUILD)/$(1)-test
        javac $$(if $$($(1)_TEST_CLASSPATH),-cp $$($(1)_TEST_CLASSPATH)) \
                $$($(1)_TEST_JAVA_FLAGS) \
                -d $(BUILD)/$(1)-test \
                $$($(1)_TEST_JAVA_SOURCES) $$($(1)_TEST_JAVA_GENERATED)
        touch $(BUILD)/$(1)-test.built

$(BUILD)/$(1)-test.run: $(BUILD)/$(1)-test.built
        java -cp $$($(1)_TEST_CLASSPATH):$(BUILD)/$(1)-test $(junit4_runner) \
          $$(foreach dir,$$($1_TEST_JAVA_DIRS),\
            $$(subst /,., \
              $$(patsubst $$(dir)/%Test.java,%Test, \
                $$(filter $$(dir)/%Test.java,$$($1_TEST_JAVA_SOURCES)))))

$(BUILD)/$(1)-testit.run: $(BUILD)/$(1)-test.built
        java -cp $$($(1)_TEST_CLASSPATH):$(BUILD)/$(1)-test $(junit4_runner) \
          $$(foreach dir,$$($1_TEST_JAVA_DIRS),\
            $$(subst /,., \
              $$(patsubst $$(dir)/%IT.java,%IT, \
                $$(filter $$(dir)/%IT.java,$$($1_TEST_JAVA_SOURCES)))))

TEST_LIST += $(BUILD)/$(1)-test.run
TESTIT_LIST += $(BUILD)/$(1)-testit.run

This uses $(foreach), $(subst), $(patsubst), and $(filter) to convert file names into class names to be passed to the junit runner.

Features

Specifiying directories or individual files is supported. The application classes and libraries are automatically added.

Tests are defined by source code files ending with 'Test.java' or 'IT.java'. Multiple test classes within a single source file are not supported.

TODO

Neither test class nor application class resources are included yet. For accuracy and repeatability they will need to be staged and copied (linked?) to a common area and added to the runtime class path.

At the moment all tests are run with `make test' or `make check', but as can be seen above the integration tests already have separate rules for them so separate targets could be made.

Source Distribution

`make dist' is one of the core features of automake, and this is also mirrored here.

The requirement is to include all components required to build and document the source but not include any generated files. Since all source must be defined for compilation that is automatically included. Extra resources can be defined by prog_DIST and EXTRA_DIST variables.

DIST_EXTRA_MAKE += java.make
 
$(BUILD)/dist-files: $(DIST_EXTRA) $(DIST_EXTRA_MAKE)
        mkdir -p $(BUILD)
        echo $(DIST_EXTRA) $(DIST_EXTRA_MAKE) | sed 's/ /\n/g' | sort -u > $@

$(BIN)/$(DIST_NAME)$(DIST_VERSION).tar.gz: $(BUILD)/dist-files
        mkdir -p $(BIN)
        tar -c '--transform=s@^@$(DIST_NAME)$(DIST_VERSION)/@' -f $@ -z -T $<

dist: $(BIN)/$(DIST_NAME)$(DIST_VERSION).tar.gz

Note that these are not part of the per-programme template.

Features

All files are read directly from their source locations, and GNU tar is used to remap these names to one reflecting the package version.

To avoid duplicate names a sorting and de-duplication step is included to build the list of files.

Full Package

And if that wasn't enough, it also supports a binary+source+docs+extra libraries distribution package.

$$($1_BIN): $$($1_JAR) $$($1_DOC) $$($1_SRC) $$($1_PACKAGE_EXTRA)
        mkdir -p $(BIN)
        tar -c '--transform=s@^@$$($1_NAME)/@' -f $$@ -z \
                $$($1_JAR_LIBS) \
                $$($1_PACKAGE_EXTRA) \
                -C $(BIN) $$($1_NAME).jar \
                 $$($1_NAME)-doc.jar \
                 $$($1_NAME)-src.jar \
         || (rm $$@ ; exit 1)
PACKAGE_LIST += $$($1_BIN)

I'm not sure how useful this is for Free Software projects.

Template expansion & targets

These are the last few rules which tie everything together.

# Dump all the java rules
ifdef DUMP
$(foreach prog,$(java_PROGRAMS),$(info $(call JAVA_template,$(prog))))
endif

# Create all the java rules
$(foreach prog,$(java_PROGRAMS),$(eval $(call JAVA_template,$(prog))))

jar: $(JAR_LIST)
sources: $(SRC_LIST)
javadoc: $(DOC_LIST)
package: $(PACKAGE_LIST)
check test: $(TEST_LIST) $(TESTIT_LIST)

all: jar sources javadoc

clean:
	rm -rf $(BIN) $(BUILD)

.PHONY: clean all dist jar sources javadoc
.DEFAULT_GOAL=jar

Features

Defining DUMP on the command line to make will cause the makefile to display the meta-generated content it is going to process. This is accomplished via the $(info) command. This is vital as the error reporting for templating errors is woeful.

Otherwise, all the usual targets are provided and the default is `jar'.

Example - dez

This is the complete makefile used for the dez package.

java_PROGRAMS = dez

dez_VERSION=-1
dez_JAVA_SOURCES_DIRS=src
dez_TEST_JAVA_SOURCES_DIRS=test

DIST_NAME=dez
DIST_VERSION=-1.3
DIST_EXTRA=COPYING.AGPL3 README Makefile

include java.make

This includes unit tests, versioning, licensing and readme files, with jar, javadoc, sources and dist targets.

And this is an example build from a clean slate followed by another make command. It has been reformatted for readability.

$ make
rm -rf build/dez
mkdir -p build/dez
javac -d build/dez src/au/notzed/dez/ByteDeltaEncoder.java
 src/au/notzed/dez/ByteMatcher.java
 src/au/notzed/dez/ByteMatcherHash.java src/au/notzed/dez/DEZ.java
 src/au/notzed/dez/DEZDecoder.java src/au/notzed/dez/DEZEncoder.java
 src/au/notzed/dez/DEZFormat.java src/au/notzed/dez/DEZPrinter.java
 src/au/notzed/dez/PrintEncoder.java src/au/notzed/util/CyclicHash.java
 src/au/notzed/util/Stats.java
touch build/dez.built
mkdir -p bin
echo -n "" > build/dez.manifest
jar cfm bin/dez-1.jar build/dez.manifest  -C build/dez .
  || (rm bin/dez-1.jar ; exit 1)
$ make
make: Nothing to be done for `jar'.

Whilst it may seem a trivial thing seeing the actual commands being executed is very useful if something fucks up. Note how few steps are taken as well.

And an example of make dist and what gets put into the tar file.

$ make dist
mkdir -p build
echo COPYING.AGPL3 README Makefile java.make
 src/au/notzed/dez/ByteDeltaEncoder.java
 src/au/notzed/dez/ByteMatcher.java
 src/au/notzed/dez/ByteMatcherHash.java src/au/notzed/dez/DEZ.java
 src/au/notzed/dez/DEZDecoder.java src/au/notzed/dez/DEZEncoder.java
 src/au/notzed/dez/DEZFormat.java src/au/notzed/dez/DEZPrinter.java
 src/au/notzed/dez/PrintEncoder.java src/au/notzed/util/CyclicHash.java
 src/au/notzed/util/Stats.java
 test/au/notzed/dez/ByteMatcherHashTest.java
 test/au/notzed/dez/DEZEncoderTest.java test/au/notzed/dez/DEZIT.java
  | sed 's/ /\n/g' | sort -u > build/dist-files
mkdir -p bin
tar -c '--transform=s@^@dez-1.3/@' -f bin/dez-1.3.tar.gz -z -T build/dist-files
$
$ tar tvf bin/dez-1.3.tar.gz 
-rw-r--r-- notzed/users  34520 2016-06-03 11:13 dez-1.3/COPYING.AGPL3
-rw-r--r-- notzed/users    325 2016-06-03 11:27 dez-1.3/Makefile
-rw-r--r-- notzed/users   2611 2016-06-03 11:13 dez-1.3/README
-rw-r--r-- notzed/users  12299 2016-06-03 14:53 dez-1.3/java.make
-rw-r--r-- notzed/users   2342 2016-06-03 11:13 dez-1.3/src/au/notzed/dez/ByteDeltaEncoder.java
-rw-r--r-- notzed/users   2792 2016-06-03 11:13 dez-1.3/src/au/notzed/dez/ByteMatcher.java
-rw-r--r-- notzed/users   8490 2016-06-03 11:13 dez-1.3/src/au/notzed/dez/ByteMatcherHash.java
-rw-r--r-- notzed/users   2815 2016-06-03 11:13 dez-1.3/src/au/notzed/dez/DEZ.java
-rw-r--r-- notzed/users   5252 2016-06-03 12:59 dez-1.3/src/au/notzed/dez/DEZDecoder.java
-rw-r--r-- notzed/users   7622 2016-06-03 11:13 dez-1.3/src/au/notzed/dez/DEZEncoder.java
-rw-r--r-- notzed/users   6140 2016-06-03 11:13 dez-1.3/src/au/notzed/dez/DEZFormat.java
-rw-r--r-- notzed/users   5631 2016-06-03 11:13 dez-1.3/src/au/notzed/dez/DEZPrinter.java
-rw-r--r-- notzed/users   1433 2016-06-03 11:13 dez-1.3/src/au/notzed/dez/PrintEncoder.java
-rw-r--r-- notzed/users   2156 2016-06-03 11:13 dez-1.3/src/au/notzed/util/CyclicHash.java
-rw-r--r-- notzed/users   1567 2016-06-03 11:13 dez-1.3/src/au/notzed/util/Stats.java
-rw-r--r-- notzed/users   7705 2016-06-03 12:14 dez-1.3/test/au/notzed/dez/ByteMatcherHashTest.java
-rw-r--r-- notzed/users   8060 2016-06-03 11:13 dez-1.3/test/au/notzed/dez/DEZEncoderTest.java
-rw-r--r-- notzed/users   3528 2016-06-03 11:13 dez-1.3/test/au/notzed/dez/DEZIT.java

Because it just references existing files and rewrites their names inside the tar file it runs very fast.

ant vs make

Here's some comparisons with Java developer's number one (or two? three?) choice for build tools. And this is being somewhat flattering ant since this is a simple pure java library.

Make output is more concise and meaninful

See above for the make output. This is the pointless spew ant creates.
Buildfile: /home/notzed/NetBeansProjects/dez/build.xml

-pre-init:

-init-private:

-init-user:

-init-project:

-init-macrodef-property:

-do-init:

-post-init:

-init-check:

-init-ap-cmdline-properties:

-init-macrodef-javac-with-processors:

-init-macrodef-javac-without-processors:

-init-macrodef-javac:

-init-macrodef-test-impl:

-init-macrodef-junit-init:

-init-macrodef-junit-single:

-init-test-properties:

-init-macrodef-junit-batch:

-init-macrodef-junit:

-init-macrodef-junit-impl:
Trying to override old definition of task http://www.netbeans.org/ns/j2se-project/3:test-impl

-init-macrodef-testng:

-init-macrodef-testng-impl:

-init-macrodef-test:

-init-macrodef-junit-debug:

-init-macrodef-junit-debug-batch:

-init-macrodef-junit-debug-impl:

-init-macrodef-test-debug-junit:

-init-macrodef-testng-debug:

-init-macrodef-testng-debug-impl:

-init-macrodef-test-debug-testng:

-init-macrodef-test-debug:

-init-debug-args:

-init-macrodef-nbjpda:

-init-macrodef-debug:

-init-macrodef-java:

-init-presetdef-jar:

-init-ap-cmdline-supported:

-init-ap-cmdline:

init:

-deps-jar-init:

deps-jar:
    [mkdir] Created dir: /home/notzed/NetBeansProjects/dez/build

-warn-already-built-jar:
[propertyfile] Updating property file: /home/notzed/NetBeansProjects/dez/build/built-jar.properties

-check-automatic-build:

-clean-after-automatic-build:

-verify-automatic-build:

-pre-pre-compile:
    [mkdir] Created dir: /home/notzed/NetBeansProjects/dez/build/classes

-pre-compile:

-copy-persistence-xml:

-compile-depend:

-do-compile:
    [mkdir] Created dir: /home/notzed/NetBeansProjects/dez/build/empty
    [mkdir] Created dir: /home/notzed/NetBeansProjects/dez/build/generated-sources/ap-source-output
    [javac] Compiling 11 source files to /home/notzed/NetBeansProjects/dez/build/classes

-post-compile:

compile:

-pre-jar:

-pre-pre-jar:
    [mkdir] Created dir: /home/notzed/NetBeansProjects/dez/dist

-do-jar-create-manifest:

-do-jar-copy-manifest:

-do-jar-set-mainclass:

-do-jar-set-profile:

-do-jar-set-splashscreen:

-do-jar-jar:
[j2seproject1:jar] Building jar: /home/notzed/NetBeansProjects/dez/dist/dez.jar
     [echo] To run this application from the command line without Ant, try:
     [echo] /usr/local/java/jdk1.8.0_92/jre/bin/java -cp /home/notzed/NetBeansProjects/dez/dist/dez.jar au.notzed.dez1.Tester

-init-macrodef-copylibs:

-do-jar-copylibs:

-do-jar-delete-manifest:

-do-jar-without-libraries:

-do-jar-with-libraries:

-post-jar:

-do-jar:

jar:

BUILD SUCCESSFUL
Total time: 2 seconds

When manage to actually find out what it did, you don't know what the fuck that was anyway.

Make is faster

DEZ is too small a project to accurately gauge build time, but it's still twice as fast using make. These are both after their respective clean target was run.

$ time ant jar
  
real    0m2.638s
user    0m4.079s
sys     0m0.353s

$ time make jar

real    0m1.148s
user    0m2.611s
sys     0m0.178s

The user makefile is simpler and easier to read

See earlier for the dez makefile.

I only have the IDE-generated ant file to compare, and it doesn't actually do anything. But the comments tell enough of the story to make it worth including. Note that it doesn't provide a dist target either so is less functional.

<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="dez" default="default" basedir=".">
    <description>Builds, tests, and runs the project dez.</description>
    <import file="nbproject/build-impl.xml"/>
    <!--

    There exist several targets which are by default empty and which can be 
    used for execution of your tasks. These targets are usually executed 
    before and after some main targets. They are: 

      -pre-init:                 called before initialization of project properties
      -post-init:                called after initialization of project properties
      -pre-compile:              called before javac compilation
      -post-compile:             called after javac compilation
      -pre-compile-single:       called before javac compilation of single file
      -post-compile-single:      called after javac compilation of single file
      -pre-compile-test:         called before javac compilation of JUnit tests
      -post-compile-test:        called after javac compilation of JUnit tests
      -pre-compile-test-single:  called before javac compilation of single JUnit test
      -post-compile-test-single: called after javac compilation of single JUunit test
      -pre-jar:                  called before JAR building
      -post-jar:                 called after JAR building
      -post-clean:               called after cleaning build products

    (Targets beginning with '-' are not intended to be called on their own.)

    Example of inserting an obfuscator after compilation could look like this:

        <target name="-post-compile">
            <obfuscate>
                <fileset dir="${build.classes.dir}"/>
            </obfuscate>
        </target>

    For list of available properties check the imported 
    nbproject/build-impl.xml file. 


    Another way to customize the build is by overriding existing main targets.
    The targets of interest are: 

      -init-macrodef-javac:     defines macro for javac compilation
      -init-macrodef-junit:     defines macro for junit execution
      -init-macrodef-debug:     defines macro for class debugging
      -init-macrodef-java:      defines macro for class execution
      -do-jar:                  JAR building
      run:                      execution of project 
      -javadoc-build:           Javadoc generation
      test-report:              JUnit report generation

    An example of overriding the target for project execution could look like this:

        <target name="run" depends="dez-impl.jar">
            <exec dir="bin" executable="launcher.exe">
                <arg file="${dist.jar}"/>
            </exec>
        </target>

    Notice that the overridden target depends on the jar target and not only on 
    the compile target as the regular run target does. Again, for a list of available 
    properties which you can use, check the target you are overriding in the
    nbproject/build-impl.xml file. 

    -->
</project>

The glue to make GNU compile java is simpler than the glue to make ant compile java

Again i'm going to include the IDE code here. Both because nobody is ever stupid enough to try to do it themselves and because someone still had to write this shit.

Remember, this is a tool specifically written to compile java source codes. Make knows nothing about java so all its knowledge is imparted here in its entirety.

First, the make glue. i.e. the templates. I've included it in full together with license. It's still pretty big in total but about half is documentation.

# ######################################################################
# Generic java makefile template

# Copyright (C) 2015,2016 Michael Zucchi

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

###
# Global variables

# java_PROGRAMS = list of programs to build (applications or libraries)

# DIST_NAME sets the base name (excluding extensions) of the full
#       source archive generated by 'make dist'.

# DIST_VERSION sets the distribution version suffix.

# DIST_EXTRA is a list of extra files required to complete the source
#       distribution.  These are files outside of any _JAVA,
#       _RESOURCE, _LIBSFILE, or _OVERVIEW.

# DIST_EXTRA_MAKE extra dist files created by the makefiles.

###
# Per-target variables.

# Program Sepcification
# =====================

# In the following 'prog' is one of the names in JAVA_PROGRAMS or JAVA_LIBS

# prog_VERSION is an optional string appended to the name for all files
#       generated.  Any hyphens should be included. e.g. -1.0

# Source Specification
# ====================
# Source can be specified by listing every file or by specifying a
# package root directory.  Both may also be used together.
#
# If listing individual files using prog_JAVA_SOURCES then
# prog_JAVA_DIRS must list all the path prefixes which indicate the
# package roots.

# For example, if your source is in src/java/au/notzed/A.java, then
# prog_JAVA_DIRS must include "src/java" as that is not part of
# the package name.

# Any directories specified using prog_JAVA_SOURCES_DIRS are included
# in prog_JAVA_DIRS automatically.

# prog_JAVA_SOURCES lists all files to include in `prog'.  The names
#       must be relative to the location of the Makefile.

# prog_JAVA_SOURCES_DIRS lists root directories for automatic file
#       search.  All files found ending in `.java' are added to the
#       sources file list.

# prog_JAVA_GENERATED lists all source files generated by the
#       makefile.

# prog_JAVA_GENERATED_DIRS lists all root directories of generated
#       directories for automatic file search.  All files found ending
#       with `.java' are added to the sources file list.

# prog_JAVA_DIRS lists all outside-of-package prefixes which appear in
#       any of the names of the source files.  Names may not begin
#       with '-' and MUST NOT include any training '/'.

# prog_JAVA_LIBS is a list of jar files to add to the classpath during
#       the build.

# JUnit Tests
# ===========

# An initial stab at testing with JUnit4 is included in this Makefile.
# All `*Test.java' and `*IT.java' tests are executed via the `check'
# and `test' make targets.

# Global Variables
# ----------------
# junit4 Defines the system or source local location of the junit 4
#       jar file

# junit4_runner defines the name of the runner class to use.
#       `org.junit.runner.JUnitCore' is the default.

# Test Specification
# ------------------

# The tests to run are defined at the source level.  That is, each
# test must be included in a source file which ends with `Test.java'
# or `IT.java'.

# prog_TEST_JAVA_SOURCES
# prog_TEST_JAVA_SOURCES_DIRS
# prog_TEST_JAVA_GENERATED
# prog_TEST_JAVA_GENERATED_DIRS
# prog_TEST_JAVA_DIRS
# prog_TEST_JAVA_LIBS
#
#       All operate the same way as the `prog_JAVA' variables above.
#       The programme classes and prog_JAVA_LIBS are automatically
#       included at both build and run time.
#

# JAR Packaging
# =============

# Specfication of jar inputs works in a similar manner to that of the
# sources.  Individual files, directories, generated files and
# generated directories can all be specified.

# prog_JAR_RESOURCES lists individual resource files to package in
#       the jar file.

# prog_JAR_RESOURCES_DIRS lists root directories which are searched
#       for files to add to the jar.  All files (find -type f) are
#       included.  This is not currently filtered and may include
#       source code control meta-files.

# prog_JAR_GENERATED lists individual generated resource files.

# prog_JAR_GENERATED_DIRS lists root directories whicha re searched
#      for files to add to the jar.  All files (find -type f) are
#      included.

# prog_JAR_DIRS lists all Makefile relative prefixes which must be
#      stripped from any resource name.  If specified, the
#      prog_JAR_RESOURCES_DIRS and prog_JAR_GENERATED_DIRS are
#      automatically included.

# javadoc
# =======

# Extra definitions for the javadoc target.

# prog_JAVADOC_FLAGS extra flags to javadoc

# prog_JAVADOC_FILES lists dependencies for the `javadoc' target.
#       They are used to specify files that javadoc will use
#       implicitly. These files are not passed to javadoc nor used
#       used elsewhere.

# sources
# =======

# Extra definitions for the IDE-compatible source jar target.  It
# automatically includes all specified and generated source code.

# prog_SOURCES_FILES lists extra dependencies for the `sources'
#       target.  These are not included in the source archive.

# This creates a variable S which equates to a single space (make can be arcane)
E:=
S:=$(E) $(E)

# 'system' defaults
BUILD ?= build
BIN ?= bin

junit4 ?= /usr/local/netbeans-8.0/platform/modules/ext/junit-4.10.jar
junit4_runner ?= org.junit.runner.JUnitCore

# ######################
# The magic happens here.
define JAVA_template =

# Java source code for compiling and packaging
$1_JAVA_GENERATED += $$(if $$($1_JAVA_GENERATED_DIRS),$$(shell find $$($1_JAVA_GENERATED_DIRS) -name '*.java'))
$1_JAVA_SOURCES += $$(if $$($1_JAVA_SOURCES_DIRS),$$(shell find $$($1_JAVA_SOURCES_DIRS) -name '*.java'))
$1_JAVA_DIRS += $$($1_JAVA_SOURCES_DIRS) $$($1_JAVA_GENERATED_DIRS)

# Resources for the jar file
$1_JAR_GENERATED += $$(if $$($1_JAR_GENERATED_DIRS),$$(shell find $$($1_JAR_GENERATED_DIRS) -type f))
$1_JAR_RESOURCES += $$(if $$($1_JAR_RESOURCES_DIRS),$$(shell find $$($1_JAR_RESOURCES_DIRS) -type f))
$1_JAR_DIRS += $$($1_JAR_RESOURCES_DIRS) $$($1_JAR_GENERATED_DIRS)

$1_CLASSPATH:=$$(subst $$(S),:,$$(strip $$($(1)_JAVA_LIBS)))

# Test variables
$1_TEST_JAVA_GENERATED += $$(if $$($1_TEST_JAVA_GENERATED_DIRS),$$(shell find $$($1_TEST_JAVA_GENERATED_DIRS) -name '*.java'))
$1_TEST_JAVA_SOURCES += $$(if $$($1_TEST_JAVA_SOURCES_DIRS),$$(shell find $$($1_TEST_JAVA_SOURCES_DIRS) -name '*.java'))
$1_TEST_JAVA_DIRS += $$($1_TEST_JAVA_SOURCES_DIRS) $$($1_TEST_JAVA_GENERATED_DIRS)

$1_TEST_CLASSPATH:=$$(subst $$(S),:,$$(strip $$($1_JAVA_LIBS) $$($1_TEST_JAVA_LIBS) $(BUILD)/$(1) $(junit4)))

# Some common names for ``readability''
$1_NAME:=$(1)$$($1_VERSION)
$1_JAR:=$(BIN)/$$($1_NAME).jar
$1_DOC:=$(BIN)/$$($1_NAME)-doc.jar
$1_SRC:=$(BIN)/$$($1_NAME)-src.jar
$1_BIN:=$(BIN)/$$($1_NAME)-bin.tar.gz

DIST_EXTRA_MAKE += $$($(1)_DIST) $$($(1)_JAVA_SOURCES) $$($(1)_JAR_RESOURCES) $$($(1)_JAR_LIBS) $$($(1)_JAVA_LIBS) $$($1_TEST_JAVA_SOURCES)

# ######################################################################
# Build application classes

$(BUILD)/$(1).built: $$($1_JAVA_SOURCES) $$($1_JAVA_GENERATED) $$($1_JAVA_LIBS) $$($1_JAVA_FILES)
        -rm -rf $(BUILD)/$(1)
        mkdir -p $(BUILD)/$(1)
        javac $$(if $$($1_CLASSPATH),-cp $$($1_CLASSPATH)) \
                $$($1_JAVA_FLAGS) \
                -d $(BUILD)/$(1) \
                $$($1_JAVA_SOURCES) $$($1_JAVA_GENERATED)
        touch $(BUILD)/$(1).built

# ######################################################################
# Create jar from compiled classes + resources

$$($1_JAR): $(BUILD)/$(1).built $$($1_JAR_RESOURCES) $$($1_MANIFEST) $$($1_JAR_FILES) $$($1_JAR_LIBS)
        mkdir -p $(BIN)
        $$(if $$($1_MANIFEST),cp $$($1_MANIFEST) $(BUILD)/$(1).manifest,echo -n "" > $(BUILD)/$(1).manifest)
        $$(if $$($1_JAR_LIBS),echo "Class-Path: $$($(1)_JAR_LIBS)" >> $(BUILD)/$(1).manifest)
        jar cfm $$@ $(BUILD)/$(1).manifest \
                $$($1_JAR_FLAGS) \
                -C $(BUILD)/$(1) . \
                $$(foreach dir,$$($1_JAR_RESOURCE_DIRS),$$(patsubst $$(dir)/%,-C $$(dir) %,\
                        $$(filter $$(dir)/%,$$($1_JAR_RESOURCES) $$($1_JAR_GENERATED)))) \
                 || (rm $$@ ; exit 1)
JAR_LIST += $$($1_JAR)

# ######################################################################
# Build test classes

$(BUILD)/$(1)-test.built: $(BUILD)/$(1).built $$($(1)_TEST_JAVA_SOURCES) $$($(1)_TEST_JAVA_GENERATED) $$($(1)_TEST_JAVA_LIBS) $$($(1)_TEST_JAVA_FILES)
        -rm -rf $(BUILD)/$(1)-test
        mkdir -p $(BUILD)/$(1)-test
        javac $$(if $$($(1)_TEST_CLASSPATH),-cp $$($(1)_TEST_CLASSPATH)) \
                $$($(1)_TEST_JAVA_FLAGS) \
                -d $(BUILD)/$(1)-test \
                $$($(1)_TEST_JAVA_SOURCES) $$($(1)_TEST_JAVA_GENERATED)
        touch $(BUILD)/$(1)-test.built

# ######################################################################
# Run tests

$(BUILD)/$(1)-test.run: $(BUILD)/$(1)-test.built
        java -cp $$($(1)_TEST_CLASSPATH):$(BUILD)/$(1)-test $(junit4_runner) \
          $$(foreach dir,$$($1_TEST_JAVA_DIRS),\
            $$(subst /,., \
              $$(patsubst $$(dir)/%Test.java,%Test, \
                $$(filter $$(dir)/%Test.java,$$($1_TEST_JAVA_SOURCES)))))

$(BUILD)/$(1)-testit.run: $(BUILD)/$(1)-test.built
        java -cp $$($(1)_TEST_CLASSPATH):$(BUILD)/$(1)-test $(junit4_runner) \
          $$(foreach dir,$$($1_TEST_JAVA_DIRS),\
            $$(subst /,., \
              $$(patsubst $$(dir)/%IT.java,%IT, \
                $$(filter $$(dir)/%IT.java,$$($1_TEST_JAVA_SOURCES)))))

TEST_LIST += $(BUILD)/$(1)-test.run
TESTIT_LIST += $(BUILD)/$(1)-testit.run

# ######################################################################
# Build javadocs

$$($(1)_DOC): $$($(1)_JAVA) $$($(1)_JAVA_SOURCES) $$($(1)_JAVA_GENERATED) $$($(1)_JAVADOC_FILES)
        -rm -rf $(BUILD)/$(1)-doc
        mkdir -p $(BUILD)/$(1)-doc $(BIN)
        javadoc -locale en_AU -charset UTF-8 \
                -quiet -use \
                $$($1_JAVADOC_FLAGS) \
                -d $(BUILD)/$(1)-doc $$($(1)_JAVA) $$($(1)_JAVA_SOURCES) $$($(1)_JAVA_GENERATED)
        jar cf $$@ -C $(BUILD)/$(1)-doc . || (rm $$@ ; exit 1)
DOC_LIST += $$($(1)_DOC)

# ######################################################################
# Build sources

$$($(1)_SRC): $$($(1)_JAVA_SOURCES) $$($(1)_JAVA_GENERATED) $$($(1)_JAVA_RESOURCES) $$($(1)_SOURCES_FILES)
        mkdir -p $(BIN)
        jar cf $$@ \
                $$(foreach dir,$$($(1)_JAVA_DIRS),$$(patsubst $$(dir)/%,-C $$(dir) %,\
                        $$(filter $$(dir)/%,$$($1_JAVA_SOURCES) $$($1_JAVA_GENERATED)))) \
                $$(foreach dir,$$($(1)_JAR_RESOURCE_DIRS),$$(patsubst $$(dir)/%,-C $$(dir) %,\
                        $$(filter $$(dir)/%,$$($1_JAR_RESOURCES) $$($1_JAR_GENERATED)))) \
         || (rm $$@ ; exit 1)
SRC_LIST += $$($(1)_SRC)

# ######################################################################
# Create complete binary distribution package

# Package is basically the jar plus any libs
# It doesn't always make sense
$$($(1)_BIN): $$($1_JAR) $$($1_DOC) $$($1_SRC) $$($1_PACKAGE_EXTRA)
        mkdir -p $(BIN)
        tar -c '--transform=s@^@$$($(1)_NAME)/@' -f $$@ -z \
                $$($1_JAR_LIBS) \
                $$($1_PACKAGE_EXTRA) \
                -C $(BIN) $$($1_NAME).jar \
                 $$($1_NAME)-doc.jar \
                 $$($1_NAME)-src.jar \
         || (rm $$@ ; exit 1)
PACKAGE_LIST += $$($1_BIN)
endef

DIST_EXTRA_MAKE += java.make

# Dump all the java rules
ifdef DUMP
$(foreach prog,$(java_PROGRAMS),$(info $(call JAVA_template,$(prog))))
endif

# Create all the java rules
$(foreach prog,$(java_PROGRAMS),$(eval $(call JAVA_template,$(prog))))

# source distribution
$(BUILD)/dist-files: $(DIST_EXTRA) $(DIST_EXTRA_MAKE)
        mkdir -p $(BUILD)
        echo $(DIST_EXTRA) $(DIST_EXTRA_MAKE) | sed 's/ /\n/g' | sort -u > $@

# To support possible duplicates in dist-all, unique-ify them first
$(BIN)/$(DIST_NAME)$(DIST_VERSION).tar.gz: $(BUILD)/dist-files
        mkdir -p $(BIN)
        tar -c '--transform=s@^@$(DIST_NAME)$(DIST_VERSION)/@' -f $@ -z -T $<

# helper targets
dist: $(BIN)/$(DIST_NAME)$(DIST_VERSION).tar.gz
jar: $(JAR_LIST)
sources: $(SRC_LIST)
javadoc: $(DOC_LIST)
package: $(PACKAGE_LIST)
check test: $(TEST_LIST) $(TESTIT_LIST)

all: jar sources javadoc

clean:
        rm -rf $(BIN) $(BUILD)

.PHONY: clean all dist jar sources javadoc

.DEFAULT_GOAL=jar

And here it comes ... nbproject/build-impl.xml, which is not the only file, but it's enough to demonstrate the point.

<?xml version="1.0" encoding="UTF-8"?>
<!--
*** GENERATED FROM project.xml - DO NOT EDIT  ***
***         EDIT ../build.xml INSTEAD         ***

For the purpose of easier reading the script
is divided into following sections:

  - initialization
  - compilation
  - jar
  - execution
  - debugging
  - javadoc
  - test compilation
  - test execution
  - test debugging
  - applet
  - cleanup

        -->
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="dez-impl">
    <fail message="Please build using Ant 1.8.0 or higher.">
        <condition>
            <not>
                <antversion atleast="1.8.0"/>
            </not>
        </condition>
    </fail>
    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
    <!-- 
                ======================
                INITIALIZATION SECTION 
                ======================
            -->
    <target name="-pre-init">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="-pre-init" name="-init-private">
        <property file="nbproject/private/config.properties"/>
        <property file="nbproject/private/configs/${config}.properties"/>
        <property file="nbproject/private/private.properties"/>
    </target>
    <target depends="-pre-init,-init-private" name="-init-user">
        <property file="${user.properties.file}"/>
        <!-- The two properties below are usually overridden -->
        <!-- by the active platform. Just a fallback. -->
        <property name="default.javac.source" value="1.4"/>
        <property name="default.javac.target" value="1.4"/>
    </target>
    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
        <property file="nbproject/configs/${config}.properties"/>
        <property file="nbproject/project.properties"/>
    </target>
    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
        <property name="platform.java" value="${java.home}/bin/java"/>
        <available file="${manifest.file}" property="manifest.available"/>
        <condition property="splashscreen.available">
            <and>
                <not>
                    <equals arg1="${application.splash}" arg2="" trim="true"/>
                </not>
                <available file="${application.splash}"/>
            </and>
        </condition>
        <condition property="main.class.available">
            <and>
                <isset property="main.class"/>
                <not>
                    <equals arg1="${main.class}" arg2="" trim="true"/>
                </not>
            </and>
        </condition>
        <condition property="profile.available">
            <and>
                <isset property="javac.profile"/>
                <length length="0" string="${javac.profile}" when="greater"/>
                <matches pattern="1\.[89](\..*)?" string="${javac.source}"/>
            </and>
        </condition>
        <condition property="do.archive">
            <or>
                <not>
                    <istrue value="${jar.archive.disabled}"/>
                </not>
                <istrue value="${not.archive.disabled}"/>
            </or>
        </condition>
        <condition property="do.mkdist">
            <and>
                <isset property="do.archive"/>
                <isset property="libs.CopyLibs.classpath"/>
                <not>
                    <istrue value="${mkdist.disabled}"/>
                </not>
            </and>
        </condition>
        <condition property="do.archive+manifest.available">
            <and>
                <isset property="manifest.available"/>
                <istrue value="${do.archive}"/>
            </and>
        </condition>
        <condition property="do.archive+main.class.available">
            <and>
                <isset property="main.class.available"/>
                <istrue value="${do.archive}"/>
            </and>
        </condition>
        <condition property="do.archive+splashscreen.available">
            <and>
                <isset property="splashscreen.available"/>
                <istrue value="${do.archive}"/>
            </and>
        </condition>
        <condition property="do.archive+profile.available">
            <and>
                <isset property="profile.available"/>
                <istrue value="${do.archive}"/>
            </and>
        </condition>
        <condition property="have.tests">
            <or>
                <available file="${test.src.dir}"/>
            </or>
        </condition>
        <condition property="have.sources">
            <or>
                <available file="${src.dir}"/>
            </or>
        </condition>
        <condition property="netbeans.home+have.tests">
            <and>
                <isset property="netbeans.home"/>
                <isset property="have.tests"/>
            </and>
        </condition>
        <condition property="no.javadoc.preview">
            <and>
                <isset property="javadoc.preview"/>
                <isfalse value="${javadoc.preview}"/>
            </and>
        </condition>
        <property name="run.jvmargs" value=""/>
        <property name="run.jvmargs.ide" value=""/>
        <property name="javac.compilerargs" value=""/>
        <property name="work.dir" value="${basedir}"/>
        <condition property="no.deps">
            <and>
                <istrue value="${no.dependencies}"/>
            </and>
        </condition>
        <property name="javac.debug" value="true"/>
        <property name="javadoc.preview" value="true"/>
        <property name="application.args" value=""/>
        <property name="source.encoding" value="${file.encoding}"/>
        <property name="runtime.encoding" value="${source.encoding}"/>
        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
            <and>
                <isset property="javadoc.encoding"/>
                <not>
                    <equals arg1="${javadoc.encoding}" arg2=""/>
                </not>
            </and>
        </condition>
        <property name="javadoc.encoding.used" value="${source.encoding}"/>
        <property name="includes" value="**"/>
        <property name="excludes" value=""/>
        <property name="do.depend" value="false"/>
        <condition property="do.depend.true">
            <istrue value="${do.depend}"/>
        </condition>
        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
            <and>
                <isset property="endorsed.classpath"/>
                <not>
                    <equals arg1="${endorsed.classpath}" arg2="" trim="true"/>
                </not>
            </and>
        </condition>
        <condition else="" property="javac.profile.cmd.line.arg" value="-profile ${javac.profile}">
            <isset property="profile.available"/>
        </condition>
        <condition else="false" property="jdkBug6558476">
            <and>
                <matches pattern="1\.[56]" string="${java.specification.version}"/>
                <not>
                    <os family="unix"/>
                </not>
            </and>
        </condition>
        <property name="javac.fork" value="${jdkBug6558476}"/>
        <property name="jar.index" value="false"/>
        <property name="jar.index.metainf" value="${jar.index}"/>
        <property name="copylibs.rebase" value="true"/>
        <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
        <condition property="junit.available">
            <or>
                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
            </or>
        </condition>
        <condition property="testng.available">
            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
        </condition>
        <condition property="junit+testng.available">
            <and>
                <istrue value="${junit.available}"/>
                <istrue value="${testng.available}"/>
            </and>
        </condition>
        <condition else="testng" property="testng.mode" value="mixed">
            <istrue value="${junit+testng.available}"/>
        </condition>
        <condition else="" property="testng.debug.mode" value="-mixed">
            <istrue value="${junit+testng.available}"/>
        </condition>
    </target>
    <target name="-post-init">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
        <fail unless="src.dir">Must set src.dir</fail>
        <fail unless="test.src.dir">Must set test.src.dir</fail>
        <fail unless="build.dir">Must set build.dir</fail>
        <fail unless="dist.dir">Must set dist.dir</fail>
        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
        <fail unless="dist.jar">Must set dist.jar</fail>
    </target>
    <target name="-init-macrodef-property">
        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
            <attribute name="name"/>
            <attribute name="value"/>
            <sequential>
                <property name="@{name}" value="${@{value}}"/>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${src.dir}" name="srcdir"/>
            <attribute default="${build.classes.dir}" name="destdir"/>
            <attribute default="${javac.classpath}" name="classpath"/>
            <attribute default="${javac.processorpath}" name="processorpath"/>
            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="${javac.debug}" name="debug"/>
            <attribute default="${empty.dir}" name="sourcepath"/>
            <attribute default="${empty.dir}" name="gensrcdir"/>
            <element name="customize" optional="true"/>
            <sequential>
                <property location="${build.dir}/empty" name="empty.dir"/>
                <mkdir dir="${empty.dir}"/>
                <mkdir dir="@{apgeneratedsrcdir}"/>
                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
                    <src>
                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
                            <include name="*"/>
                        </dirset>
                    </src>
                    <classpath>
                        <path path="@{classpath}"/>
                    </classpath>
                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
                    <compilerarg line="${javac.compilerargs}"/>
                    <compilerarg value="-processorpath"/>
                    <compilerarg path="@{processorpath}:${empty.dir}"/>
                    <compilerarg line="${ap.processors.internal}"/>
                    <compilerarg line="${annotation.processing.processor.options}"/>
                    <compilerarg value="-s"/>
                    <compilerarg path="@{apgeneratedsrcdir}"/>
                    <compilerarg line="${ap.proc.none.internal}"/>
                    <customize/>
                </javac>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${src.dir}" name="srcdir"/>
            <attribute default="${build.classes.dir}" name="destdir"/>
            <attribute default="${javac.classpath}" name="classpath"/>
            <attribute default="${javac.processorpath}" name="processorpath"/>
            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="${javac.debug}" name="debug"/>
            <attribute default="${empty.dir}" name="sourcepath"/>
            <attribute default="${empty.dir}" name="gensrcdir"/>
            <element name="customize" optional="true"/>
            <sequential>
                <property location="${build.dir}/empty" name="empty.dir"/>
                <mkdir dir="${empty.dir}"/>
                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
                    <src>
                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
                            <include name="*"/>
                        </dirset>
                    </src>
                    <classpath>
                        <path path="@{classpath}"/>
                    </classpath>
                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
                    <compilerarg line="${javac.compilerargs}"/>
                    <customize/>
                </javac>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${src.dir}" name="srcdir"/>
            <attribute default="${build.classes.dir}" name="destdir"/>
            <attribute default="${javac.classpath}" name="classpath"/>
            <sequential>
                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
                    <classpath>
                        <path path="@{classpath}"/>
                    </classpath>
                </depend>
            </sequential>
        </macrodef>
        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${build.classes.dir}" name="destdir"/>
            <sequential>
                <fail unless="javac.includes">Must set javac.includes</fail>
                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
                    <path>
                        <filelist dir="@{destdir}" files="${javac.includes}"/>
                    </path>
                    <globmapper from="*.java" to="*.class"/>
                </pathconvert>
                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
                <delete>
                    <files includesfile="${javac.includesfile.binary}"/>
                </delete>
                <delete>
                    <fileset file="${javac.includesfile.binary}"/>
                </delete>
            </sequential>
        </macrodef>
    </target>
    <target if="${junit.available}" name="-init-macrodef-junit-init">
        <condition else="false" property="nb.junit.batch" value="true">
            <and>
                <istrue value="${junit.available}"/>
                <not>
                    <isset property="test.method"/>
                </not>
            </and>
        </condition>
        <condition else="false" property="nb.junit.single" value="true">
            <and>
                <istrue value="${junit.available}"/>
                <isset property="test.method"/>
            </and>
        </condition>
    </target>
    <target name="-init-test-properties">
        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>
        <property name="test.binarytestincludes" value=""/>
        <property name="test.binaryexcludes" value=""/>
    </target>
    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <element name="customize" optional="true"/>
            <sequential>
                <property name="junit.forkmode" value="perTest"/>
                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
                    <syspropertyset>
                        <propertyref prefix="test-sys-prop."/>
                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
                    </syspropertyset>
                    <formatter type="brief" usefile="false"/>
                    <formatter type="xml"/>
                    <jvmarg value="-ea"/>
                    <customize/>
                </junit>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <element name="customize" optional="true"/>
            <sequential>
                <property name="junit.forkmode" value="perTest"/>
                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
                    <batchtest todir="${build.test.results.dir}">
                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
                            <filename name="@{testincludes}"/>
                        </fileset>
                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
                            <filename name="${test.binarytestincludes}"/>
                        </fileset>
                    </batchtest>
                    <syspropertyset>
                        <propertyref prefix="test-sys-prop."/>
                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
                    </syspropertyset>
                    <formatter type="brief" usefile="false"/>
                    <formatter type="xml"/>
                    <jvmarg value="-ea"/>
                    <customize/>
                </junit>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
    <target if="${testng.available}" name="-init-macrodef-testng">
        <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <element name="customize" optional="true"/>
            <sequential>
                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
                    <isset property="test.method"/>
                </condition>
                <union id="test.set">
                    <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
                        <filename name="@{testincludes}"/>
                    </fileset>
                </union>
                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
                <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="dez" testname="TestNG tests" workingDir="${work.dir}">
                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
                    <propertyset>
                        <propertyref prefix="test-sys-prop."/>
                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
                    </propertyset>
                    <customize/>
                </testng>
            </sequential>
        </macrodef>
    </target>
    <target name="-init-macrodef-test-impl">
        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <element implicit="true" name="customize" optional="true"/>
            <sequential>
                <echo>No tests executed.</echo>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <element implicit="true" name="customize" optional="true"/>
            <sequential>
                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
                    <customize/>
                </j2seproject3:junit>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <element implicit="true" name="customize" optional="true"/>
            <sequential>
                <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
                    <customize/>
                </j2seproject3:testng>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
        <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <sequential>
                <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
                    <customize>
                        <classpath>
                            <path path="${run.test.classpath}"/>
                        </classpath>
                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
                        <jvmarg line="${run.jvmargs}"/>
                        <jvmarg line="${run.jvmargs.ide}"/>
                    </customize>
                </j2seproject3:test-impl>
            </sequential>
        </macrodef>
    </target>
    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <element name="customize" optional="true"/>
            <sequential>
                <property name="junit.forkmode" value="perTest"/>
                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
                    <syspropertyset>
                        <propertyref prefix="test-sys-prop."/>
                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
                    </syspropertyset>
                    <formatter type="brief" usefile="false"/>
                    <formatter type="xml"/>
                    <jvmarg value="-ea"/>
                    <jvmarg line="${debug-args-line}"/>
                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
                    <customize/>
                </junit>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <element name="customize" optional="true"/>
            <sequential>
                <property name="junit.forkmode" value="perTest"/>
                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
                    <batchtest todir="${build.test.results.dir}">
                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
                            <filename name="@{testincludes}"/>
                        </fileset>
                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
                            <filename name="${test.binarytestincludes}"/>
                        </fileset>
                    </batchtest>
                    <syspropertyset>
                        <propertyref prefix="test-sys-prop."/>
                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
                    </syspropertyset>
                    <formatter type="brief" usefile="false"/>
                    <formatter type="xml"/>
                    <jvmarg value="-ea"/>
                    <jvmarg line="${debug-args-line}"/>
                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
                    <customize/>
                </junit>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <element implicit="true" name="customize" optional="true"/>
            <sequential>
                <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
                    <customize/>
                </j2seproject3:junit-debug>
            </sequential>
        </macrodef>
    </target>
    <target if="${testng.available}" name="-init-macrodef-testng-debug">
        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${main.class}" name="testClass"/>
            <attribute default="" name="testMethod"/>
            <element name="customize2" optional="true"/>
            <sequential>
                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
                    <isset property="test.method"/>
                </condition>
                <condition else="-suitename dez -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
                    <matches pattern=".*\.xml" string="@{testClass}"/>
                </condition>
                <delete dir="${build.test.results.dir}" quiet="true"/>
                <mkdir dir="${build.test.results.dir}"/>
                <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">
                    <customize>
                        <customize2/>
                        <jvmarg value="-ea"/>
                        <arg line="${testng.debug.mode}"/>
                        <arg line="-d ${build.test.results.dir}"/>
                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
                        <arg line="${testng.cmd.args}"/>
                    </customize>
                </j2seproject3:debug>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${main.class}" name="testClass"/>
            <attribute default="" name="testMethod"/>
            <element implicit="true" name="customize2" optional="true"/>
            <sequential>
                <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
                    <customize2/>
                </j2seproject3:testng-debug>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <attribute default="${main.class}" name="testClass"/>
            <attribute default="" name="testMethod"/>
            <sequential>
                <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
                    <customize>
                        <classpath>
                            <path path="${run.test.classpath}"/>
                        </classpath>
                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
                        <jvmarg line="${run.jvmargs}"/>
                        <jvmarg line="${run.jvmargs.ide}"/>
                    </customize>
                </j2seproject3:test-debug-impl>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${includes}" name="includes"/>
            <attribute default="${excludes}" name="excludes"/>
            <attribute default="**" name="testincludes"/>
            <attribute default="" name="testmethods"/>
            <attribute default="${main.class}" name="testClass"/>
            <attribute default="" name="testMethod"/>
            <sequential>
                <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
                    <customize2>
                        <syspropertyset>
                            <propertyref prefix="test-sys-prop."/>
                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
                        </syspropertyset>
                    </customize2>
                </j2seproject3:testng-debug-impl>
            </sequential>
        </macrodef>
    </target>
    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
    <!--
                pre NB7.2 profiling section; consider it deprecated
            -->
    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">
        <macrodef name="resolve">
            <attribute name="name"/>
            <attribute name="value"/>
            <sequential>
                <property name="@{name}" value="${env.@{value}}"/>
            </sequential>
        </macrodef>
        <macrodef name="profile">
            <attribute default="${main.class}" name="classname"/>
            <element name="customize" optional="true"/>
            <sequential>
                <property environment="env"/>
                <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
                <java classname="@{classname}" dir="${profiler.info.dir}" fork="true" jvm="${profiler.info.jvm}">
                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
                    <jvmarg value="${profiler.info.jvmargs.agent}"/>
                    <jvmarg line="${profiler.info.jvmargs}"/>
                    <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
                    <arg line="${application.args}"/>
                    <classpath>
                        <path path="${run.classpath}"/>
                    </classpath>
                    <syspropertyset>
                        <propertyref prefix="run-sys-prop."/>
                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
                    </syspropertyset>
                    <customize/>
                </java>
            </sequential>
        </macrodef>
    </target>
    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">
        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
    </target>
    <!--
                end of pre NB7.2 profiling section
            -->
    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
            <attribute default="${main.class}" name="name"/>
            <attribute default="${debug.classpath}" name="classpath"/>
            <attribute default="" name="stopclassname"/>
            <sequential>
                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
                    <classpath>
                        <path path="@{classpath}"/>
                    </classpath>
                </nbjpdastart>
            </sequential>
        </macrodef>
        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
            <attribute default="${build.classes.dir}" name="dir"/>
            <sequential>
                <nbjpdareload>
                    <fileset dir="@{dir}" includes="${fix.classes}">
                        <include name="${fix.includes}*.class"/>
                    </fileset>
                </nbjpdareload>
            </sequential>
        </macrodef>
    </target>
    <target name="-init-debug-args">
        <property name="version-output" value="java version &quot;${ant.java.version}"/>
        <condition property="have-jdk-older-than-1.4">
            <or>
                <contains string="${version-output}" substring="java version &quot;1.0"/>
                <contains string="${version-output}" substring="java version &quot;1.1"/>
                <contains string="${version-output}" substring="java version &quot;1.2"/>
                <contains string="${version-output}" substring="java version &quot;1.3"/>
            </or>
        </condition>
        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
            <istrue value="${have-jdk-older-than-1.4}"/>
        </condition>
        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
            <os family="windows"/>
        </condition>
        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
            <isset property="debug.transport"/>
        </condition>
    </target>
    <target depends="-init-debug-args" name="-init-macrodef-debug">
        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${main.class}" name="classname"/>
            <attribute default="${debug.classpath}" name="classpath"/>
            <element name="customize" optional="true"/>
            <sequential>
                <java classname="@{classname}" dir="${work.dir}" fork="true">
                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
                    <jvmarg line="${debug-args-line}"/>
                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
                    <jvmarg line="${run.jvmargs}"/>
                    <jvmarg line="${run.jvmargs.ide}"/>
                    <classpath>
                        <path path="@{classpath}"/>
                    </classpath>
                    <syspropertyset>
                        <propertyref prefix="run-sys-prop."/>
                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
                    </syspropertyset>
                    <customize/>
                </java>
            </sequential>
        </macrodef>
    </target>
    <target name="-init-macrodef-java">
        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
            <attribute default="${main.class}" name="classname"/>
            <attribute default="${run.classpath}" name="classpath"/>
            <attribute default="jvm" name="jvm"/>
            <element name="customize" optional="true"/>
            <sequential>
                <java classname="@{classname}" dir="${work.dir}" fork="true">
                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
                    <jvmarg line="${run.jvmargs}"/>
                    <jvmarg line="${run.jvmargs.ide}"/>
                    <classpath>
                        <path path="@{classpath}"/>
                    </classpath>
                    <syspropertyset>
                        <propertyref prefix="run-sys-prop."/>
                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
                    </syspropertyset>
                    <customize/>
                </java>
            </sequential>
        </macrodef>
    </target>
    <target name="-init-macrodef-copylibs">
        <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
            <attribute default="${manifest.file}" name="manifest"/>
            <element name="customize" optional="true"/>
            <sequential>
                <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
                <pathconvert property="run.classpath.without.build.classes.dir">
                    <path path="${run.classpath}"/>
                    <map from="${build.classes.dir.resolved}" to=""/>
                </pathconvert>
                <pathconvert pathsep=" " property="jar.classpath">
                    <path path="${run.classpath.without.build.classes.dir}"/>
                    <chainedmapper>
                        <flattenmapper/>
                        <filtermapper>
                            <replacestring from=" " to="%20"/>
                        </filtermapper>
                        <globmapper from="*" to="lib/*"/>
                    </chainedmapper>
                </pathconvert>
                <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
                <copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
                    <fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
                    <manifest>
                        <attribute name="Class-Path" value="${jar.classpath}"/>
                        <customize/>
                    </manifest>
                </copylibs>
            </sequential>
        </macrodef>
    </target>
    <target name="-init-presetdef-jar">
        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
            <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">
                <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
            </jar>
        </presetdef>
    </target>
    <target name="-init-ap-cmdline-properties">
        <property name="annotation.processing.enabled" value="true"/>
        <property name="annotation.processing.processors.list" value=""/>
        <property name="annotation.processing.processor.options" value=""/>
        <property name="annotation.processing.run.all.processors" value="true"/>
        <property name="javac.processorpath" value="${javac.classpath}"/>
        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
        <condition property="ap.supported.internal" value="true">
            <not>
                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
            </not>
        </condition>
    </target>
    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
            <isfalse value="${annotation.processing.run.all.processors}"/>
        </condition>
        <condition else="" property="ap.proc.none.internal" value="-proc:none">
            <isfalse value="${annotation.processing.enabled}"/>
        </condition>
    </target>
    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
        <property name="ap.cmd.line.internal" value=""/>
    </target>
    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
    <!--
                ===================
                COMPILATION SECTION
                ===================
            -->
    <target name="-deps-jar-init" unless="built-jar.properties">
        <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
        <delete file="${built-jar.properties}" quiet="true"/>
    </target>
    <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
        <echo level="warn" message="Cycle detected: dez was already built"/>
    </target>
    <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
        <mkdir dir="${build.dir}"/>
        <touch file="${built-jar.properties}" verbose="false"/>
        <property file="${built-jar.properties}" prefix="already.built.jar."/>
        <antcall target="-warn-already-built-jar"/>
        <propertyfile file="${built-jar.properties}">
            <entry key="${basedir}" value=""/>
        </propertyfile>
    </target>
    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
    <target depends="init" name="-check-automatic-build">
        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
    </target>
    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
        <antcall target="clean"/>
    </target>
    <target depends="init,deps-jar" name="-pre-pre-compile">
        <mkdir dir="${build.classes.dir}"/>
    </target>
    <target name="-pre-compile">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target if="do.depend.true" name="-compile-depend">
        <pathconvert property="build.generated.subdirs">
            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
                <include name="*"/>
            </dirset>
        </pathconvert>
        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
    </target>
    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
        <copy todir="${build.classes.dir}">
            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
        </copy>
    </target>
    <target if="has.persistence.xml" name="-copy-persistence-xml">
        <mkdir dir="${build.classes.dir}/META-INF"/>
        <copy todir="${build.classes.dir}/META-INF">
            <fileset dir="${meta.inf.dir}" includes="persistence.xml orm.xml"/>
        </copy>
    </target>
    <target name="-post-compile">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
    <target name="-pre-compile-single">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
        <j2seproject3:force-recompile/>
        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
    </target>
    <target name="-post-compile-single">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
    <!--
                ====================
                JAR BUILDING SECTION
                ====================
            -->
    <target depends="init" name="-pre-pre-jar">
        <dirname file="${dist.jar}" property="dist.jar.dir"/>
        <mkdir dir="${dist.jar.dir}"/>
    </target>
    <target name="-pre-jar">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available">
        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
        <touch file="${tmp.manifest.file}" verbose="false"/>
    </target>
    <target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest">
        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
        <copy file="${manifest.file}" tofile="${tmp.manifest.file}"/>
    </target>
    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass">
        <manifest file="${tmp.manifest.file}" mode="update">
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </target>
    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile">
        <manifest file="${tmp.manifest.file}" mode="update">
            <attribute name="Profile" value="${javac.profile}"/>
        </manifest>
    </target>
    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-set-splashscreen">
        <basename file="${application.splash}" property="splashscreen.basename"/>
        <mkdir dir="${build.classes.dir}/META-INF"/>
        <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
        <manifest file="${tmp.manifest.file}" mode="update">
            <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
        </manifest>
    </target>
    <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs">
        <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
        <echo level="info">To run this application from the command line without Ant, try:</echo>
        <property location="${dist.jar}" name="dist.jar.resolved"/>
        <echo level="info">java -jar "${dist.jar.resolved}"</echo>
    </target>
    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
        <j2seproject1:jar manifest="${tmp.manifest.file}"/>
        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
        <property location="${dist.jar}" name="dist.jar.resolved"/>
        <pathconvert property="run.classpath.with.dist.jar">
            <path path="${run.classpath}"/>
            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
        </pathconvert>
        <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java} -cp ${run.classpath.with.dist.jar} ${main.class}">
            <isset property="main.class.available"/>
        </condition>
        <condition else="debug" property="jar.usage.level" value="info">
            <isset property="main.class.available"/>
        </condition>
        <echo level="${jar.usage.level}" message="${jar.usage.message}"/>
    </target>
    <target depends="-do-jar-copylibs" if="do.archive" name="-do-jar-delete-manifest">
        <delete>
            <fileset file="${tmp.manifest.file}"/>
        </delete>
    </target>
    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-jar,-do-jar-delete-manifest" name="-do-jar-without-libraries"/>
    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-copylibs,-do-jar-delete-manifest" name="-do-jar-with-libraries"/>
    <target name="-post-jar">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="init,compile,-pre-jar,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>
    <target depends="init,compile,-pre-jar,-do-jar,-post-jar" description="Build JAR." name="jar"/>
    <!--
                =================
                EXECUTION SECTION
                =================
            -->
    <target depends="init,compile" description="Run a main class." name="run">
        <j2seproject1:java>
            <customize>
                <arg line="${application.args}"/>
            </customize>
        </j2seproject1:java>
    </target>
    <target name="-do-not-recompile">
        <property name="javac.includes.binary" value=""/>
    </target>
    <target depends="init,compile-single" name="run-single">
        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
        <j2seproject1:java classname="${run.class}"/>
    </target>
    <target depends="init,compile-test-single" name="run-test-with-main">
        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
    </target>
    <!--
                =================
                DEBUGGING SECTION
                =================
            -->
    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
        <j2seproject1:nbjpdastart name="${debug.class}"/>
    </target>
    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
    </target>
    <target depends="init,compile" name="-debug-start-debuggee">
        <j2seproject3:debug>
            <customize>
                <arg line="${application.args}"/>
            </customize>
        </j2seproject3:debug>
    </target>
    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
    </target>
    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
        <j2seproject3:debug classname="${debug.class}"/>
    </target>
    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
    </target>
    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
    <target depends="init" name="-pre-debug-fix">
        <fail unless="fix.includes">Must set fix.includes</fail>
        <property name="javac.includes" value="${fix.includes}.java"/>
    </target>
    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
        <j2seproject1:nbjpdareload/>
    </target>
    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
    <!--
                =================
                PROFILING SECTION
                =================
            -->
    <!--
                pre NB7.2 profiler integration
            -->
    <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
        <nbprofiledirect>
            <classpath>
                <path path="${run.classpath}"/>
            </classpath>
        </nbprofiledirect>
        <profile/>
    </target>
    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">
        <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
        <nbprofiledirect>
            <classpath>
                <path path="${run.classpath}"/>
            </classpath>
        </nbprofiledirect>
        <profile classname="${profile.class}"/>
    </target>
    <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">
        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
        <nbprofiledirect>
            <classpath>
                <path path="${run.classpath}"/>
            </classpath>
        </nbprofiledirect>
        <profile classname="sun.applet.AppletViewer">
            <customize>
                <arg value="${applet.url}"/>
            </customize>
        </profile>
    </target>
    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
        <nbprofiledirect>
            <classpath>
                <path path="${run.test.classpath}"/>
            </classpath>
        </nbprofiledirect>
        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
            <jvmarg value="${profiler.info.jvmargs.agent}"/>
            <jvmarg line="${profiler.info.jvmargs}"/>
            <test name="${profile.class}"/>
            <classpath>
                <path path="${run.test.classpath}"/>
            </classpath>
            <syspropertyset>
                <propertyref prefix="test-sys-prop."/>
                <mapper from="test-sys-prop.*" to="*" type="glob"/>
            </syspropertyset>
            <formatter type="brief" usefile="false"/>
            <formatter type="xml"/>
        </junit>
    </target>
    <!--
                end of pre NB72 profiling section
            -->
    <target if="netbeans.home" name="-profile-check">
        <condition property="profiler.configured">
            <or>
                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
            </or>
        </condition>
    </target>
    <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
        <startprofiler/>
        <antcall target="run"/>
    </target>
    <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">
        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
        <startprofiler/>
        <antcall target="run-single"/>
    </target>
    <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>
    <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">
        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
        <startprofiler/>
        <antcall target="test-single"/>
    </target>
    <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">
        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
        <startprofiler/>
        <antcal target="run-test-with-main"/>
    </target>
    <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">
        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
        <startprofiler/>
        <antcall target="run-applet"/>
    </target>
    <!--
                ===============
                JAVADOC SECTION
                ===============
            -->
    <target depends="init" if="have.sources" name="-javadoc-build">
        <mkdir dir="${dist.javadoc.dir}"/>
        <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">
            <and>
                <isset property="endorsed.classpath.cmd.line.arg"/>
                <not>
                    <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>
                </not>
            </and>
        </condition>
        <condition else="" property="bug5101868workaround" value="*.java">
            <matches pattern="1\.[56](\..*)?" string="${java.version}"/>
        </condition>
        <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
            <classpath>
                <path path="${javac.classpath}"/>
            </classpath>
            <fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
                <filename name="**/*.java"/>
            </fileset>
            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
                <include name="**/*.java"/>
                <exclude name="*.java"/>
            </fileset>
            <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
        </javadoc>
        <copy todir="${dist.javadoc.dir}">
            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
                <filename name="**/doc-files/**"/>
            </fileset>
            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
                <include name="**/doc-files/**"/>
            </fileset>
        </copy>
    </target>
    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
    </target>
    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
    <!--
                =========================
                TEST COMPILATION SECTION
                =========================
            -->
    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
        <mkdir dir="${build.test.classes.dir}"/>
    </target>
    <target name="-pre-compile-test">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target if="do.depend.true" name="-compile-test-depend">
        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
    </target>
    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir="${test.src.dir}"/>
        <copy todir="${build.test.classes.dir}">
            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
        </copy>
    </target>
    <target name="-post-compile-test">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
    <target name="-pre-compile-test-single">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
        <copy todir="${build.test.classes.dir}">
            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
        </copy>
    </target>
    <target name="-post-compile-test-single">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
    <!--
                =======================
                TEST EXECUTION SECTION
                =======================
            -->
    <target depends="init" if="have.tests" name="-pre-test-run">
        <mkdir dir="${build.test.results.dir}"/>
    </target>
    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
        <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>
    </target>
    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
    </target>
    <target depends="init" if="have.tests" name="test-report"/>
    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
    <target depends="init" if="have.tests" name="-pre-test-run-single">
        <mkdir dir="${build.test.results.dir}"/>
    </target>
    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
        <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
    </target>
    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
    </target>
    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
        <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
    </target>
    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
    </target>
    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
    <!--
                =======================
                TEST DEBUGGING SECTION
                =======================
            -->
    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
    </target>
    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
    </target>
    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
    </target>
    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
    </target>
    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
    <!--
                =========================
                APPLET EXECUTION SECTION
                =========================
            -->
    <target depends="init,compile-single" name="run-applet">
        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
        <j2seproject1:java classname="sun.applet.AppletViewer">
            <customize>
                <arg value="${applet.url}"/>
            </customize>
        </j2seproject1:java>
    </target>
    <!--
                =========================
                APPLET DEBUGGING  SECTION
                =========================
            -->
    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
        <j2seproject3:debug classname="sun.applet.AppletViewer">
            <customize>
                <arg value="${applet.url}"/>
            </customize>
        </j2seproject3:debug>
    </target>
    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
    <!--
                ===============
                CLEANUP SECTION
                ===============
            -->
    <target name="-deps-clean-init" unless="built-clean.properties">
        <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
        <delete file="${built-clean.properties}" quiet="true"/>
    </target>
    <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
        <echo level="warn" message="Cycle detected: dez was already built"/>
    </target>
    <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
        <mkdir dir="${build.dir}"/>
        <touch file="${built-clean.properties}" verbose="false"/>
        <property file="${built-clean.properties}" prefix="already.built.clean."/>
        <antcall target="-warn-already-built-clean"/>
        <propertyfile file="${built-clean.properties}">
            <entry key="${basedir}" value=""/>
        </propertyfile>
    </target>
    <target depends="init" name="-do-clean">
        <delete dir="${build.dir}"/>
        <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
    </target>
    <target name="-post-clean">
        <!-- Empty placeholder for easier customization. -->
        <!-- You can override this target in the ../build.xml file. -->
    </target>
    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
    <target name="-check-call-dep">
        <property file="${call.built.properties}" prefix="already.built."/>
        <condition property="should.call.dep">
            <and>
                <not>
                    <isset property="already.built.${call.subproject}"/>
                </not>
                <available file="${call.script}"/>
            </and>
        </condition>
    </target>
    <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
        <ant antfile="${call.script}" inheritall="false" target="${call.target}">
            <propertyset>
                <propertyref prefix="transfer."/>
                <mapper from="transfer.*" to="*" type="glob"/>
            </propertyset>
        </ant>
    </target>
</project>  

Links

Contact

notzed on various mail servers, primarily gmail.com.


Copyright (C) 2016 Michael Zucchi, All Rights Reserved.

All makefile snippets on this page are GNU GPL Version 3 or later.