Earlier in the User's Guide, you've seen how to configure a project.xml
to build various different
types of projects.
In addition to customising the build through the project model, additional properties can be set, and scripting can be used to define custom goals, or enhance the workflow during the build.
There are two sets of properties: a small set of standard properties that are fundamental to the operation of Maven, and can be changed to customise for your particular environment or change the basic structure Maven uses for a project.
This properties reference above also explains the order in which properties files are loaded, and the reasons to use each.
The majority of properties in Maven are the plugin properties. These can be used to customise any aspect of the build process.
For example, if you are looking to change the way java sources are compiled, you can see the reference for the
Java plugin properties. This allows you to set
properties such as the -target
setting, and whether to see deprecations. These can be added to
project.properties
for all builders of your project:
maven.compile.target=1.1 maven.compile.deprecation=on
While several of the most helpful properties are explained in the guides on this site, there is a full list of plugins available on the Plugins Reference mini-site. From there, you can navigate to the plugin you are interested in (which matches the first part of the goal name you are calling and wanting to configure), and on to its list of available properties.
Note that while properties are essential to configuring Maven and it's plugins, they can also be a source of bad practices. See the Best Practices guide for more information.
Note that due to a 'feature' in the jexl expression evaluator, property names (not values!) must not contain dashes (which are interpreted as subtraction operators by jexl).
It is often much easier to parameterise values in the project descriptor (or in the properties files) with other properties or fields from the project descriptor than to redefine them each time. This is particularly powerful when used with inheritence, as seen in the next section.
For example, you might set the URL based on the artifact ID:
<project> <artifactId>my-project</artifactId> ... <url>http://www.mycompany.com/mainproject/subprojects/${pom.artifactId}</url> </project>
For more information on how to specify expressions to use for interpolating these values, see the Jexl section of the Scripting Reference.
When working with multiple projects that share some information, it would be quite tedious to have to enter the same information into each project, or to maintain it afterwards.
For this reason, it is possible to extend a common project file:
<project> <extend>../project.xml</extend> ... </project>
All elements are inherited and merged in, with later definitions overriding any defined earlier. Projects can be inherited to any level, but each can only extend one parent.
If there are any properties to be substituted into the parent POM or properties, the value will be evaluated
after inheritence has been completed. For instance, if in the parent POM with artifact ID
my-parent
there was a description set like so:
<description>This is ${pom.artifactId}</description>
In the child project, if description were inherited and the artifact ID were my-child
then
the description would be This is my-child
.
In addition to the project.xml
definition, properties files and maven.xml
files
associated with the parent POM are inherited. Like the project descriptor properties and goals defined are
added to those defined in the subprojects, with the subproject properties and goals overriding those from
the parent if specified. preGoal
and postGoal
definitions that are inherited are
accumulated though - all specified hooks will be executed.
Note: lists in the POM will overwrite lists defined in parent projects, with the exception of dependencies where the lists are accumulated.
If the provided plugins do not give all the flexibility needed to do the required tasks, you can add scripting to your project to go the last steps.
There are two ways to add additional goals and hooks to your project - through maven.xml
, and by
writing your own plugin. It is generally recommended to write your own plugin for any significant scripting
effort as it will make it reusable across projects, separated, and allows you to use Java code as well as basic
Jelly script.
The maven.xml
file is tied to the project.xml
file in the same directory, in the
same way as project.properties
is. This means that it is loaded and its goals processed whenever
your project is, and also means that it is inherited from any projects you extend.
The format of maven.xml
is typically like this:
<project default="jar:jar" xmlns:j="jelly:core"> ... </project>
The project
element is the root element, and can specify a default goal name for the project.
The namespace definitions are used by Jelly to import tag libraries.
Within this file, you can define new goals, or attach hooks to existing ones, write logic using Jelly tag libraries, and use existing Ant tasks to add build behaviour.
For more information on scripting in general, please see the Scripting reference. For particular information on building plugins, see Developing Plugins in this User's Guide.
As with properties, there are also some best practices to adhere to with regards to scripting Maven to ensure the build is maintainable.