blob: f49e171dffec9df2ab011b9b2ed45e39c30b43da [file] [log] [blame]
---
Advanced Module-Set Topics
---
John Casey
---
2006-12-01
---
~~ Licensed to the Apache Software Foundation (ASF) under one
~~ or more contributor license agreements. See the NOTICE file
~~ distributed with this work for additional information
~~ regarding copyright ownership. The ASF licenses this file
~~ to you under the Apache License, Version 2.0 (the
~~ "License"); you may not use this file except in compliance
~~ with the License. You may obtain a copy of the License at
~~
~~ http://www.apache.org/licenses/LICENSE-2.0
~~
~~ Unless required by applicable law or agreed to in writing,
~~ software distributed under the License is distributed on an
~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~~ KIND, either express or implied. See the License for the
~~ specific language governing permissions and limitations
~~ under the License.
~~ NOTE: For help with the syntax of this file, see:
~~ http://maven.apache.org/doxia/references/apt-format.html
Advanced Module-Set Topics
* Quick Note
Some of the topics in this document refer to more general topics or
improvements in the assembly descriptor as a whole. For more information, see
the {{{./advanced-descriptor-topics.html}Advanced Assembly-Descriptor Topics}}
page.
* Including and Excluding Modules using a ModuleSet
As you are no doubt aware, Maven introduces advanced handling of
multimodule builds. These are builds which contain multiple, often
interrelated projects. In these builds, project hierarchy is established
through use of the <<<modules>>> section of the POM, where parent POMs specify
their children in a <<<modules>>> section. Other relationships, like
interdependency, also exist within multimodule builds; however, these are
beyond the scope of this document.
When constructing an assembly from any parent-level project in a multimodule
build, it's possible to process this parent-POM's descendent modules, and
include them in some form within the resulting assembly artifact. By default,
the entire module hierarchy below the current project is available for
inclusion or exclusion. Also, include/exclude patterns for modules are matched
using the artifact-matching rules explained in the <<Advanced
Assembly-Descriptor Topics>> document.
The following examples describe how to select certain modules in the project
hierarchy using basic artifact includes/excludes. It does <<not>> describe
what to do with the selected modules; to learn about the actions available for
selected modules, see {{{Including_Module_Sources}including module sources}}
and {{{Including_Module_Binaries}including module binaries}}
below. For other, more advanced module-handling options, read on!
** Example: Select one from a set of child projects
Given the following project structure, and all appropriate module references
in the parent POM:
---
+ parent (groupId: org.test, artifactId: parent)
|
+ child1 (groupId: org.test, artifactId: child1)
|
+ child2 (groupId: org.test, artifactId: child2)
---
We can select <<just>> the child1 module using the following <<<moduleSet>>>:
---
<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
[...]
<moduleSets>
[...]
<moduleSet>
<includes>
<include>org.test:child1</include>
</includes>
</moduleSet>
</moduleSets>
[...]
</assembly>
---
<NOTE: It's important to remember that, if the child1 project itself had
children, those children would not be included just because the child1 project
was included. Each module is matched separately.>
~~ [jdcasey] TODO: Amend this once we've handled the case where you want to process
~~ the entire inheritance/dependency trail. We'll need a flag to say "Include
~~ my ancestry when matching for includes/excludes", and have that apply
~~ appropriately to the transitive dependency trail in a dependencySet, or a
~~ module hierarchy in a moduleSet.
* Quick Note on <<<outputFileNameMapping>>> within ModuleSets
When used from within a <<<moduleSet>>>, all <<<outputFileNameMapping>>>
configurations with expressions like <<<$\{artifactId\}>>> <extract information
from the artifact in question.>
** Example: Setting <<<outputFileNameMapping>>> from <<<moduleSet/binaries>>>
Given a module with the following:
---
Group Id: org.test
Artifact Id: project
Version: 1.0.1
Type: jar
---
The following <<<outputFileNameMapping>>>:
---
${module.groupId}-${module.artifactId}-${module.version}.${module.extension}
---
Will result in a file called <<<org.test-project-1.0.jar>>> being created
within the assembly.
<NOTE: The expression> <<<$\{module.extension\}>>> <is mapped to the file extension
supplied by the ArtifactHandler for the type> <<<jar>>>. <It's important to
remember that the file extension> <<need not be .jar>><.>
* {Including Module Sources}
Once you've selected certain modules to be included in the assembly, you have
to determine what you want included from each module. This usually depends on
the purpose of the assembly. For instance, if you're building a binary
assembly, for use in a runtime context, you probably want to include module
binaries only (see the {{Including_Module_Binaries}} section below). However,
if your assembly is meant to include project sources, either as a reference or
to allow users to build your project (or for some other reason altogether),
then you're probably interested in the <<<sources>>> section of the
<<<moduleSet>>>.
Processing module sources is a fileSet-based activity. That is, sources are
included or excluded based on file-matching patterns, or explicit
<<<fileSet>>> subsections. <<For backward compatibility only>>, the
<<<\<sources/\>>>> section itself supports <<<includes>>> and <<<excludes>>>
that can help determine which files from a module's directory should be
processed. Starting in version 2.2 of the assembly plugin, the
<<<\<sources/\>>>> section supports a <<<\<fileSets/\>>>> subsection, which is
the preferred way of selecting module-source files for processing.
** Example: including the <<<src>>> directory from each selected module
In this example, we'll explore how to include the <<<src>>> directory <<only>>
for each module selected by the moduleSet. This is useful to provide a source
reference for your project to users.
---
<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
[...]
<moduleSets>
[...]
<moduleSet>
[...]
<sources>
<fileSets>
<fileSet>
<directory>src</directory>
</fileSet>
</fileSets>
</sources>
</moduleSet>
</moduleSets>
</assembly>
---
** Example: Including a buildable project directory for each selected module
In this example, we'll explore how to include an entire buildable project
directory, for each selected module, within your assembly. This is useful to
give your users the chance to tinker with your project, then build it on their
own.
---
<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
[...]
<moduleSets>
[...]
<moduleSet>
[...]
<sources>
<fileSets>
<fileSet>
<excludes>
<exclude>target/**</exclude>
</excludes>
</fileSet>
</fileSets>
</sources>
</moduleSet>
</moduleSets>
</assembly>
---
<NOTE: We exclude the target directory, since this is assumed to be temporary
storage for files produced during the course of a Maven build. Permanent
project files are not meant to reside here...>
** Consolidating All Module Sources into a Single Directory Structure
Normally, each module processed by the assembly plugin is placed within its
own directory structure inside the assembly root directory. For module
sources, the default name of this module-specific directory is the module's
<<<artifactId>>>.
However, in some cases you may want to consolidate module sources into the
same directory structure, based in the assembly root directory. To do this,
simply set the <<<includeModuleDirectory>>> flag to <<<false>>>.
*** Example: Copy all module sources into a single <<<src>>> directory
When providing a source reference to users, you may want to produce a single,
consolidated source directory containing all of the source files from your
multimodule hierarchy.
---
<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
[...]
<moduleSets>
[...]
<moduleSet>
[...]
<sources>
<includeModuleDirectory>false</includeModuleDirectory>
<fileSets>
<fileSet>
<outputDirectory>src</outputDirectory>
<includes>
<include>src/**</include>
</includes>
</fileSet>
</fileSets>
</sources>
</moduleSet>
</moduleSets>
</assembly>
---
** Excluding Modules of Modules from Direct Assembly Processing
When dealing with project sources in a complex multimodule build consisting of
several layers of module groupings, it's sometimes desirable to process only
the top layer of modules, and provide <<<fileSet>>> specifications to handle
sub-modules. This can make it much easier to preserve the project-directory
structure, since it doesn't force all modules - regardless of their location
within the project hierarchy - through a flat module-processing mechanism.
Processing only the first level of modules is the default configuration for
the <<<sources>>> section of a <<<moduleSet>>>.
To explicitly process modules of modules - sub-modules, that is - simply use
the <<<excludeSubModuleDirectories>>> flag, set to <<<false>>>.
*** Example: Providing a shallow source-directory structure for reference
Consider the case where you want to preserve the context of all source files
within your project hierarchy, according to the project in which they belong.
At the same time, you want to avoid confusing users with a complex nesting of
projects within projects, and present a simple list of projects to browse.
If your project hierarchy looks like this:
---
+ application
|
+ src
|
+ project1
| |
| + src
| |
| + project1-child1
| | |
| | + src
| |
| + project1-child2
| | |
| | + src
|
+ project2
|
+ src
|
+ project2-child1
|
+ src
---
You may want it to look like this in the resulting assembly:
---
+ application
| |
| + src
|
+ project1
| |
| + src
|
+ project1-child1
| |
| + src
|
+ project1-child2
| |
| + src
|
+ project2
| |
| + src
|
+ project2-child1
|
+ src
---
To accomplish this restructuring, simply use the
<<<excludeSubModuleDirectories>>> flag, as follows:
---
<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
[...]
<moduleSets>
[...]
<moduleSet>
[...]
<sources>
<excludeSubModuleDirectories>false</excludeSubModuleDirectories>
<fileSets>
<fileSet>
<includes>
<include>src/**</include>
</includes>
</fileSet>
</fileSets>
</sources>
</moduleSet>
</moduleSets>
</assembly>
---
* {Including Module Binaries}
<<WARNING!>> Using the <<<binaries>>> section of a <<<moduleSet>>> definition
involves some tricky considerations that are a result of the way Maven
sorts and executes project builds within a multimodule context. Please
read {{{./faq.html#module-binaries}this FAQ entry}} if you decide to use them.
In cases where your assembly artifact is meant to be used in a runtime
context, you'll most likely want to include the binaries from any modules
processed by the assembly plugin. This can be as simple as adding the module's
jar artifact to your assembly archive; or, it can involve selectively
including the dependencies of that module in addition to the module's own jar.
At any rate, processing module binaries is an artifact-based activity.
Accordingly, selection of the appropriate artifacts for a given module follows
the artifact inclusion rules explained in the <<Advanced Assembly-Descriptor
Topics>> document.
Once you've selected <which> artifacts should be processed for a particular
module, you have several options for <how> to process them. In its simplest
form, the <<<binaries>>> section of a <<<moduleSet>>> has many of the same
characteristics as a <<<dependencySet>>>. That is, you have the option to
specify an <<<outputDirectory>>>, and you can choose whether to unpack the
artifact(s) - the default action will unpack them.
** Processing a Module's Attachment Artifacts
Sometimes it's important to have the option to add artifacts from a module
that are not the main project artifact. Such artifacts might include javadocs,
project sources, or even other assembly artifacts.
*** Example: Including other assemblies within the current assembly
Suppose we have the following project structure:
---
+ application
|
+ app-db
|
+ app-web
|
+ app-site
---
Further, suppose that the assembly plugin is currently executing at the
<<<application>>> level, but that another assembly archive has been created
previously for the <<<app-site>>> project. This other assembly archive is a
zip file containing the project website. We want to include a copy of this
website in the application distribution assembly, which we are creating now.
Finally, suppose that the website-attachment has a classifier of <<<site>>>
taken from the assemblyId.
Since the zipfile containing the website produced by <<<app-site>>> is an
attached artifact in that module, we'll need to extract that artifact instead
of the main project artifact.
---
<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
[...]
<moduleSets>
<moduleSet>
<includes>
<include>*:app-site</include>
</includes>
<binaries>
<attachmentClassifier>site</attachmentClassifier>
<outputDirectory>doc</outputDirectory>
<outputFileNameMapping>website.${module.extension}</outputFileNameMapping>
</binaries>
</moduleSet>
[...]
</moduleSets>
</assembly>
---
** Excluding Module Dependencies
Just like any binary, modules usually have runtime dependencies, without which
they will simply fail to execute. By default, module dependencies are included
when the module itself is included. However, as we saw in the above example,
there are times when this may not be appropriate.
In the above example, the module binary included was an assembly artifact that
contained the website for the application. Other assemblies might embody a
completely self-contained version of the module's binaries, with all
dependency classes unpacked and inlined within the archive.
In short, sometimes we want to turn off automatic dependency inclusion. We can
achieve this by setting the <<<includeDependencies>>> flag to <<<false>>>.
*** Example: Including a <<<jar-with-dependencies>>> module assembly
Suppose we have the following project structure:
---
+ application
|
+ app-db
|
+ app-web
---
Further, suppose that the assembly plugin is currently executing at the
<<<app-web>>> level, but that another assembly archive has been created
previously for the <<<app-db>>> project using the built-in
<<<jar-with-dependencies>>> assembly descriptor. This assembly archive
contains all of the module dependencies, so it's not necessary to include this
module's dependencies in the current assembly.
---
<assembly xmlns="http://maven.apache.org/ASSEMBLY/${mdoVersion}"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/${mdoVersion} http://maven.apache.org/xsd/assembly-${mdoVersion}.xsd">
[...]
<moduleSets>
<moduleSet>
<includes>
<include>*:app-db</include>
</includes>
<binaries>
<attachmentClassifier>jar-with-dependencies</attachmentClassifier>
<outputDirectory>lib</outputDirectory>
<outputFileNameMapping>${module.artifactId}-${module.version}-${module.classifier}.${module.extension}</outputFileNameMapping>
</binaries>
</moduleSet>
[...]
</moduleSets>
</assembly>
---
<NOTE: The> <<<binaries>>> <section still accommodates direct> <<<\<includes/\>>>>
<and> <<<\<excludes/\>>>> <subsections, for specifying which module-dependencies
to include in the assembly. However, these are deprecated, and only provided
for backward compatibility.>