Handling of basic build steps in Java
* javac
* usage of build-claspath, build-jar-repository to prepare for build
* ...

=== add_maven_depmap macro

Maven identifies JAR files by a set of strings: groupId, artifactId and version
(mostly). To let XMvn know what groupId:artifactId corresponds to which
POM or JAR file, we may use the `%add_maven_depmap` macro. However, if package
is build in standard way (i.e.: `%mvn_build` and `%mvn_install`), then calling
`%add_maven_depmap` is neither needed nor recommended.  This macro is usually
useful only for packages that use other build tool than Maven (e.g.: ant,
gradle).

For the macro to work properly, all JAR files must be copied into `%{_javadir}`
and all POM files must be copied into `%{_mavenpomdir}`.

In simplest form (a POM without a JAR file), `%add_maven_depmap` looks like
this:

.Parent POM
[source,spec]
--------
%add_maven_depmap %{name}.pom
--------

This will read the POM file in question and provide a mapping between the
groupId and artifactId inside the POM file and the POM file placed into
`%{_mavenpomdir}`.

For a POM that maps directly to a JAR file, the following is the correct form:

.Standard invocation
[source,spec]
--------
%add_maven_depmap %{name}.pom %{name}.jar
--------

In addition to creating the POM mapping, this will also ensure that the correct
JAR is associated with the groupId and artifactId from the POM.

Even if there is no POM file from some reason, it is still possilbe to generate
mapping between Maven artifact and corresponding JAR file:

[source,spec]
--------
%add_maven_depmap groupId:artifactId[:extension[:classifier]]:version %{name}.jar
--------

.Providing additional artifact mappings
[source,spec]
--------
%add_maven_depmap %{name}.pom %{name}.jar -a "org.apache.commons:commons-lang"
--------
This form also adds additional mappings for given POM/JAR file. For example, if
the POM file indicates that it contains groupId commons-lang, artifactId
commons-lang, this form ensures that we also add a mapping between groupId
org.apache.commons and the installed POM/JAR files. This is necessary in cases
where the groupId or artifactId may have changed, and other packages might
require different IDs than those reflected in the installed POM.

.Multiple subpackages
[source,spec]
--------
%add_maven_depmap %{name}.pom %{name}.jar -f "XXX"
--------
This form stores metadata information in file with suffix "XXX".  This
is useful for packages with multiple subpackages where each has its own
JAR files.

.Multiple artifacts in a subdirectory
[source,spec]
--------
%add_maven_depmap %{name}-sub.pom %{name}/sub.jar
--------

This form should be used when a package consists of multiple JAR files that are
installed into a subdirectory of `%{_javadir}`. Note that in this case, the POM
file name includes the optional subdirectory field.


=== Generating Application Shell Scripts
As mentioned in section about xref:XFor_Packagers[Java packaging basics], all
Java applications need wrapper shell scripts to setup the environment before
running JVM and associated Java code.


The jpackage-utils package contains a convenience `%jpackage_script` macro that
can be used to create scripts that work for the majority of packages.  See its
definition and documentation in `/etc/rpm/macros.jpackage`.  One thing to pay
attention to is the 6th argument to it - whether to prefer a JRE over a full SDK
when looking up a JVM to invoke - most packages that don't require the full Java
SDK will want to set that to `true` to avoid unexpected results when looking up
a JVM when some of the installed JRE's don't have the corresponding SDK (*-devel
package) installed.

[source,spec]
--------
%install
...
%jpackage_script msv.textui.Driver "" "" msv-msv:msv-xsdlib:relaxngDatatype:isorelax msv true
...
--------

The previous example installs the "msv" script (5th argument) with main class
being msv.textui.Driver (1st argument). No optional flags (2nd argument) or
options (3rd argument) are used. This script will add several libraries to
classpath before executing main class (4th argument, JAR files separated with
":"). `build-classpath` is run on every part of 4th argument to create full
classpaths.

=== Replacing JARs with symlinks using xmvn-subst

Sometimes it may be needed to replace all JAR files in current directory with
symlinks to the system JARs located in `%{_javadir}`. This task can be achieved
using tool called `xmvn-subst`.

[source,shell]
--------
$ ls -l
-rw-r--r--. 1 msrb msrb  40817 Oct 22 09:16 cli.jar
-rw-r--r--. 1 msrb msrb 289983 Oct 22 09:17 junit4.jar
-rw-r--r--. 1 msrb msrb 474276 Oct 22 09:14 log4j.jar
$ xmvn-subst .
[INFO] Linked ./cli.jar to /usr/share/java/commons-cli.jar
[INFO] Linked ./log4j.jar to /usr/share/java/log4j.jar
[INFO] Linked ./junit4.jar to /usr/share/java/junit.jar
$ ls -la
lrwxrwxrwx. 1 msrb msrb   22 Oct 22 10:08 cli.jar -> /usr/share/java/commons-cli.jar
lrwxrwxrwx. 1 msrb msrb   22 Oct 22 10:08 junit4.jar -> /usr/share/java/junit.jar
lrwxrwxrwx. 1 msrb msrb   22 Oct 22 10:08 log4j.jar -> /usr/share/java/log4j.jar
--------

The example above shows how easy the symlinking can be. However, there are some
limitations. Original JAR files need to carry metadata which tell xmvn-subst
for what artifact given file should be substituted. Otherwise `xmvn-subst` won't
be able to identify the Maven artifact from JAR file.

[TIP]
======
See `xmvn-subst -h` for all available options.
======
