About this GuideThe Maven User Guide is intended to help developers get acquainted with Maven by providing thorough descriptions and examples. Thanks for choosing Maven! POM ProcessingThis document outlines how the POM is processing during Maven execution. Some simple forms of POM inheritance are shown, and the interpolation mechanism is demonstrated. POM InterpolationThe POM, in its familiar project.xml form, is now processed as a Jelly script. In the majority of cases users won't care that the project.xml is really a Jelly script under the covers but it does allow the use interpolated values if you wish. I would rather not see logic start cropping up in project.xml files but the flexibility is there now that the project.xml file is a stealth Jelly script :-) Below is an example of what you can do:
<?xml version="1.0" encoding="ISO-8859-1"?>
<project>
<pomVersion>3</pomVersion>
<id>maven</id>
<name>Maven</name>
<currentVersion>1.0-b5-dev</currentVersion>
<organization>
<name>Apache Software Foundation</name>
<url>http://jakarta.apache.org/</url>
<logo>/images/jakarta-logo-blue.gif</logo>
</organization>
<inceptionYear>2001</inceptionYear>
<package>org.apache.${pom.id}</package>
<logo>/images/${pom.id}.jpg</logo>
<!-- Notice that shortDescription is defined after the description -->
<description>${pom.shortDescription} that was created in ${pom.inceptionYear}.</description>
<shortDescription>${pom.name} is a Java Project Management Tool</shortDescription>
</project>
POM InheritanceThere is now a simple form of inheritance available for use when using the POM in its familiar project.xml form. Below is an example of what you can do:
<?xml version="1.0" encoding="ISO-8859-1"?>
<project>
<extend>project.xml</extend>
<id>super-extendo</id>
<name>Super Extendo</name>
<build>
<unitTest>
<includes>
<include>**/*Test*.java</include>
</includes>
<excludes>
<exclude>**/TestAll.java</exclude>
<exclude>**/*Abstract*.java</exclude>
</excludes>
</unitTest>
</build>
</project>
Currently the resolution of the parent is fairly dumb and I haven't tested anything beyond a single level of extension. But even this level of extension coupled with interpolation can potentially buy you a lot. My motivation for this was an attempt at simplifying building for the commons. You could define something like this for the master template:
<project>
<pomVersion>3</pomVersion>
<id>commons-master</id>
<name>Commons Master Maven POM</name>
<organization>
<name>Apache Software Foundation</name>
<url>http://www.apache.org</url>
</organization>
<gumpRepositoryId>jakarta</gumpRepositoryId>
<url>http://jakarta.apache.org/commons/${pom.id}.html</url>
<issueTrackingUrl>http://nagoya.apache.org/</issueTrackingUrl>
<siteAddress>jakarta.apache.org</siteAddress>
<siteDirectory>/www/jakarta.apache.org/commons/${pom.id}/</siteDirectory>
<distributionDirectory>/www/jakarta.apache.org/builds/jakarta-commons/${pom.id}/</distributionDirectory>
<repository>
<connection>scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:jakarta-commons/${pom.id}</connection>
<url>http://cvs.apache.org/viewcvs/jakarta-commons/${pom.id}/</url>
</repository>
...
</project>
And for a child you could have something like this:
<project>
<id>commons-betwixt</id>
<name>Betwixt</name>
...
</project>
And what you will get is the child's ${pom.id} value substituted into the parent template. So for projects like the commons where you have many builds that are basically set up the same way you can use a master template and leave very little in the child's project.xml file. This should also make it easier to deal with a single project producing multiple JAR artifacts. I plan to test the inheritance out in the commons now as the project.xml won't interfere with the standard Ant builds. If you're wondering what the DVSL reports will look like using this mechanism then you're on the ball! I have changed the DVSL reporting to work on the POM itself i.e. the DVSL transformation is performed on a Java object. This was necessary in order for reports to come out correctly when interpolation and inheritance are involved. You can't use the child template listed above and expect it to work. We need to use the fully resolved POM. As far as I can tell this is working. The process I'm using is probably not the most efficient but it can be improved and we'll probably break even because the POM is processed only once now (that's the theory anyway, I might missed a few bits) and can be used everywhere, or at least that's what I tried to do in this pass. If you don't use inheritance or interpolation then everything should work as per usual. The maven site itself is looking ok and the last few sites deployed have used what I'm going to commit later tonight. Properties ProcessingThe properties files in Maven are processed in the following order:
Where the last definition wins. So, Maven moves through this sequence
of properties files overridding any previously defined properties with
newer definitions. In this sequence your
In addition, System properties are processed after the above chain of
properties files are processed. So, a property specified on the CLI
using the How do Plug-in Properties Work?
Plug-ins are loaded after the above sequence of properties files
are processed but the
So even though Plug-ins are processed later in the initialization cycle you can override a plug-in's default properties as you can with any other property. For example, the Checkstyle plug-in defines the following default property:
maven.checkstyle.format = sun
Which, as you might guess, tells the Checkstyle plug-in to use
Sun's coding conventions as the default format. But you can override
this value in any of the files in standard properties fileset. So if
in your
maven.checkstyle.format = turbine
Then the Checkstyle plug-in will use Turbine's coding conventions. Behavioural PropertiesThe following is a list of properties that change the way Maven works.
BuildingMaven works using the notion of a central repository. All artifacts required for building are drawn from the central repository. Currently our central repository is housed here at Ibiblio. In a typical Maven project, the JARs required to build a are pulled from the central repository. Maven will only retrieve dependencies which are not satisfied. If you are using Maven to build several projects it is likely that those projects share a few dependencies: Maven will let you share one JAR file between any number of projects that require that JAR to build. No multiple copies of the same JAR on your system! Storing JARs in CVSIt is not recommended that you store your JARs in CVS. Maven tries to promote the notion of a user local repository where JARs, or any project artifacts, can be stored and used for any number of builds. Many projects have dependencies such as XML parsers and standard utilities that are often replicated in typical Ant builds. With Maven these standard utilities can be stored in your local repository and shared by any number of builds. Using ProxiesIf you only have access via a proxy then Maven obeys the following properties.
If you do require a proxy, the most appropriate place to set these
values would be in your
## ----------------------------------------------------------
## ${user.home}/build.properties
## ----------------------------------------------------------
.
.
maven.proxy.host = my.proxyserver.com
maven.proxy.port = 8080
maven.proxy.username = username
maven.proxy.password = password
.
.
Naming ConventionsThis document outlines the naming conventions used in the Maven project object model (POM). This document is an attempt to try and unify the many various ways projects name the artifacts that they publish for general consumption by the Java developer community. Rules and GuidelinesProjectsA project must have a unique identifier that is comprised of lowercase letters [a-z] where hyphens can be used. The unique id must also start with a lowercase letter [a-z]:
<project>
<id>foo</id>
...
</project>
All references from one project to another are to be made in terms of the unique project id. At the moment the only place in the POM where this is relevant is the declaration of project dependencies which is discussed below. A project should have a human readable name that can be used in documentation.
<project>
<id>foo</id>
<name>The Grand Master Foo</name>
...
</project>
All artifacts published by a project should be based on the project's unique identifier. DepenendenciesAn example of an ideal, the hopefully typical, dependency declaration looks like the following:
<project>
<id>bar</id>
<name>Baradelic Groove Machine</name>
...
<dependencies>
<dependency>
<id>foo</id>
<version>1.0</version>
</dependency>
</dependencies>
</project>
So, the project As user's have noticed, this ideal situation doesn't work in all cases for all projects. There are several situations that have to be accounted for which require modifications of the ideal dependency declaration:
In most cases, any of these limitations can be overcome using the optional <jar> element or the JAR can be renamed. To date many of the Jakarta products have been renamed in the repository as it is likely in the near future that most Jakarta projects will choose to use Maven to build. But there isn't a firm policy about what to do in all cases which needs to be resolved. Projects with multiple JAR artifactsThe dependency mechanism has been changed slightly in order to accommodate projects that produce/export multiple artifacts. This mechanism is a bit fugly but the Maven developers agreed we could use the format to be described below and later expand it to be more explicit and remain backward compatible. So here is what the entries look like for the ant 1.4.1 primary JAR and the optional JAR plus a bonus hypothetical:
<dependencies>
<!-- A -->
<dependency>
<id>ant</id>
<version>1.4.1</version>
</dependency>
<!-- B -->
<dependency>
<id>ant+optional</id>
<version>1.4.1</version>
</dependency>
<!-- C -->
<dependency>
<id>ant:my-poor-name</id>
<version>1.4.1</version>
</dependency>
</dependencies>
So A), B) and C) are actually pointers to single artifacts in a project. So a single dependency is a reference to a single artifact in a project. Everything right now defaults to JARs, but a dependency might be a JavaDoc index that is to be merged with other JavaDoc indexes to form a global index. Or a pointer to whatever, say a set of resources to pack up into a distribution. We tried to leave it open while preserving the most used case where the artifact is a JAR required for building something. Now for the fugly notation :-)
A)
project id = ant
artifact name = ant-1.4.1.jar
If no "+" or "+" are present then it is assumed the artifact name is the same as the project id.
B)
project id = ant
artifact name = ant-optional-1.4.1.jar
If a "+" is found then the artifact name is a concatenation of the lhs and rhs of the "+" where the "+" is replaced with a "-". If there are multiple JAR artifacts then hopefully they will be named consistently like foo-hubba-1.0.jar and foo-bubba-1.0.jar but of course we can count on this which brings us to C).
C)
project id = ant
artifact name = my-poor-name.jar
This is hypothetical because ant does name their JARs in a consistent way but if a project exports a JAR artifact that has no relation to the project id then the ":" indicates to use the name on the rhs as is. We need the project id in all cases because the new remote repository format stores all of a project's artifacts in a single directory which is named by the project id. So we have to account for artifacts where the base name is the project id, where the project id is used in the base name and where the artifact's base name has nothing to do with the project id. Remote Repository LayoutThis document outlines the layout of Maven's remote repositories. Currently, the primary repository is house at here at Ibiblio, but you may create an use your own remote repositories provided they adhere to the structure outlined in this document. Every separate project has its own directory in the repository where artifacts for that project can be stored. Each project has a unique project id and directory where a project stores its artifacts is named after the project id. Within a project's directory various types of artifacts may be stored. Currently, the two most common types are JARs and distributions. Below is a little snapshot of what the remote repository looks like:
repository
|
|-- ant
| |-- distributions
| `-- jars
| |-- ant-1.4.1.jar
| `-- ant-optional-1.4.1.jar
+-- jsse
|-- distributions
`-- jars
|-- jsse.jar
|-- jcert.jar
`-- jnet.jar
Local Repository LayoutThere is a very minimally implemented set of interfaces that allow the structuring of the local repository in an arbitrary fashion. This has barely been fleshed and I am only using one class in the package directly at the moment. I still think the local and remote repositories should be structured the same, but in an attempt to make users happy I started a set of interfaces that will allow someone to layout their local side anyway they like and still interface with the remote repos in a consistent way. Though currently it is still required to have your local repository structured in the same way as the remote repository. I'm hoping that more user feedback will drive the completion of the interfaces or allow them to be dropped all together. |