
When you search for artifacts using http://repository.sonatype.org, the browser is querying the Nexus repository using a REST API. In this post, I’m going to show you some simple Ruby scripts which you can use to search the Maven repository ...
If you are looking for the easiest way to search for artifacts in the Central Maven Repository, go to http://repository.sonatype.org. Sonatype maintains a publi instance of Nexus that can be used to search for artifacts by GAV (groupId, artifactId...
A common question from Apache Maven users is “How do I search the central repository?” or “How do I find out what groupId or artifactId I should use for a specific dependency?” Use Sonatype’s Nexus installation at htt...
One of the users on the m2eclipse user list has some great feedback about a presentation he did at the Stockholm JUG on the best of breed Maven tooling which includes Nexus and m2eclipse. Apparently people are impressed with the Maven support insi...
Maven 3.0 uses a new standalone component that handles inheritance and interpolation of a model in any format. The model needn’t even be XML based. If you can translate your model into a list of property-value pairs, you can use this framewo...
There’s are lots of people who already know that Mark de Visser is the new CEO of Sonatype, but Zack wrote a nice bit about it today in his InfoWorld blog: http://weblog.infoworld.com/openresource/archives/2008/11/marketing_maven.html I am r...
Throughout this book, you will notice references to properties which
can be used in a POM file. Sibling dependencies in a
multi-project build can be referenced using the
${project.groupId} and
${project.version} properties and any part of the
POM can be referenced by prefixing the variable name
with "project.". Environment variables and Java System properties can be
referenced, as well as values from your
~/.m2/settings.xml file. What you haven't seen yet is
an enumeration of the possible property values and some discussion about
how they can be used to help you create portable builds. This chapter
provides such an enumeration.
If you've been using property references in your
POM, you should also know that Maven has a feature
called Resource Filtering which allows you to replace property references
in any resource files stored under
src/main/resources. By default this feature is
disabled to prevent accidental replacement of property references. This
feature can be used to target builds toward a specific platform and to
externalize important build variables to properties files,
POMs, or profiles. This chapter introduces the resource
filtering feature and provides a brief discussion of how it can be used to
create portable enterprise builds.
You can use Maven properties in a pom.xml file
or in any resource that is being processed by the Maven Resource plugin's
filtering features. A property is always surrounded by
${ and }. For example, to reference
the project.version property, one would write:
${project.version}There some implicit properties available in any Maven project, these implicit properties are:
project.*Maven Project Object Model (POM). You can
use the project.* prefix to reference values in a
Maven POM.
settings.*Maven Settings. You use the settings.*
prefix to reference values from your Maven Settings in
~/.m2/settings.xml.
env.*Environment variables like PATH and
M2_HOME can be referenced using the
env.* prefix.
Any property which can be retrieved from the
System.getProperty() method can be
referenced as a Maven property.
In addition to the implicit properties listed above, a Maven POM, Maven Settings, or a Maven Profile can define a set of arbitrary, user-defined properties. The following sections provide so detail on the various properties available in a Maven project.
When a Maven Project Property is referenced, the property name is
referencing a property of the Maven Project Object Model
(POM). Specifically, you are referencing a property
of the org.apache.maven.model.Model class which
is being exposed as the implicit variable project. When you reference a
property using this implicit variable, you are using simple dot notation
to reference a bean property of the Model object.
For example, when you reference ${project.version},
you are really invoking the getVersion() method
on the instance of Model that is being exposed as
project.
The POM is also represented in the
pom.xml document present in all Maven projects.
Anything in a Maven POM can be referenced with a
property. A complete reference for the POM structure
is available at http://maven.apache.org/ref/2.0.9/maven-model/maven.html.
The following list shows some common property references from the Maven
project.
project.groupId and
project.versionProjects in a large, multi-module build often share the same
groupId and version
identifiers. When you are declaring interdependencies between two
modules which share the same groupId and
version, it is a good idea to use a property
reference for both:
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>sibling-project</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>project.artifactIdA project's artifactId is often used as the name of a
deliverable. For example, in a project with WAR
packaging, you will want to generate a a WAR
file without the version identifiers. To do this, you would
reference the project.artifactId in your
POM file like this:
<build>
<finalName>${project.artifactId}</finalName>
</build>project.name and
project.descriptionThe name and project description can often be useful properties to reference from documentation. Instead of having to worry that all of your site documents maintain the same short descriptions, you can just reference these properties.
project.build.*If you are ever trying to reference output directories in
Maven, you should never use a literal value like
target/classes. Instead you should use
property references to refer to these directories.
project.build.sourceDirectory
project.build.scriptSourceDirectory
project.build.testSourceDirectory
project.build.outputDirectory
project.build.testOutputDirectory
project.build.directory
sourceDirectory,
scriptSourceDirectory, and
testSourceDirectory provide access to the
source directories for the project.
outputDirectory and
testOutputDirectory provide access to the
directories where Maven is going to put bytecode or other build
output. directory refers to the directory which
contains all of these output directories.
There are hundreds of properties to reference in a POM. A complete reference for the POM structure is available at http://maven.apache.org/ref/2.0.9/maven-model/maven.html.
For a full list of properties available on the Maven
Model object, take a look at the JavaDoc for the
maven-model project here http://maven.apache.org/ref/2.0.9/maven-model/apidocs/index.html.
Once you load this JavaDoc, take a look at the
Model class. From this
Model class JavaDoc, you should be able to
navigate to the POM property you wish to reference.
If you needed to reference the output directory of the build, you can
use the Maven Model JavaDoc to see that the output directory is
referenced via
model.getBuild().getOutputDirectory(); this
method call would be translated to the Maven property reference
${project.build.outputDirectory}.
For more information about the Maven Model module, the module which defines the structure of the POM, see the Maven Model project page at http://maven.apache.org/ref/2.0.9/maven-model.
You can also reference any properties in the Maven Local Settings
file which is usually stored in ~/.m2/settings.xml.
This file contains user-specific configuration such as the location of
the local repository and any servers, profiles, and mirrors configured
by a specific user.
A full reference for the Local Settings file and corresponding properties is available here http://maven.apache.org/ref/2.0.9/maven-settings/settings.html.
Environment variables can be referenced with the env.* prefix. Some interesting environment variables are listed in the following list:
env.PATHContains the current PATH in which Maven
is running. The PATH contains a list of
directories used to locate executable scripts and programs.
env.HOME(On *nix systems) this variable points to a user's home directory. Instead of referencing this, you should use the ${user.home}
env.JAVA_HOMEContains the Java installation directory. This can point to either a Java Development Kit (JDK) installation or a Java Runtime Environment (JRE). Instead of using this, you should consider referencing the ${java.home} property.
env.M2_HOMEContains the Maven 2 installation directory.
While they are available, you should always use the Java System
properties if you have the choice. If you need a user's home directory
use ${user.home} instead of
${env.HOME}. If you do this, you'll end up with a
more portable build that is more likely to adhere to the
Write-One-Run-Anywhere (WORA) promise of the Java
platform.
Maven exposes all properties from
java.lang.System. Anything you can retrieve from
System.getProperty() you can reference in a
Maven property. The following table lists available properties:
Table 13.1. Java System Properties
| System Property | Description |
|---|---|
java.version |
Java Runtime Environment version |
java.vendor |
Java Runtime Environment vendor |
| java.vendor.url | Java vendor URL |
java.home |
Java installation directory |
java.vm.specification.version |
Java Virtual Machine specification version |
java.vm.specification.vendor |
Java Virtual Machine specification vendor |
java.vm.specification.name |
Java Virtual Machine specification name |
java.vm.version |
Java Virtual Machine implementation version |
java.vm.vendor |
Java Virtual Machine implementation vendor |
java.vm.name |
Java Virtual Machine implementation name |
java.specification.version |
Java Runtime Environment specification version |
java.specification.vendor |
Java Runtime Environment specification vendor |
java.specification.name |
Java Runtime Environment specification name |
java.class.version |
Java class format version number |
java.class.path |
Java class path |
java.ext.dirs |
Path of extension directory or directories |
os.name |
Operating system name |
os.arch |
Operating system architecture |
os.version |
Operating system version |
file.separator |
File separator ("/" on UNIX, "\" on Windows) |
path.separator |
Path separator (":" on UNIX, ";" on Windows) |
line.separator |
Line separator ("\n" on UNIX and Windows) |
user.name |
User's account name |
user.home |
User's home directory |
user.dir |
User's current working |
In addition to the implicit properties provided by the POM, Maven Settings, environment variables, and the Java System properties, you have the ability to define your own arbitrary properties. Properties can be defined in a POM or in a Profile. The properties set in a POM or in a Maven Profile can be referenced just like any other property available throughout Maven. User-defined properties can be referenced in a POM, or they can be used to filter resources via the Maven Resource plugin. Here's an example of defining some arbitrary properties in a Maven POM.
Example 13.1. User-defined Properties in a POM
<project>
...
<properties>
<arbitrary.property.a>This is some text</arbitrary.property.a>
<hibernate.version>3.3.0.ga</hibernate.version>
</properties>
...
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>${hibernate.version}</version>
</dependency>
</dependencies>
...
</project>The previous example defines two properties:
arbitrary.property.a and
hibernate.version. The
hibernate.version is referenced in a dependency
declaration. Using the period character as a separator in property names
is a standard practice throughout Maven POMs and
Profiles. There is nothing special about using a period as a separator;
to Maven "hibernate.version" is just a key used to retrieve the property
value "3.3.0.ga". The next example shows you how to define a property in
a profile from a Maven POM.
Example 13.2. User-defined Properties in a Profile in a POM
<project>
...
<profiles>
<profile>
<id>some-profile</id>
<properties>
<arbitrary.property>This is some text</arbitrary.property>
</properties>
</profile>
</profiles>
...
</project>The previous example demonstrates the process of defining a user-defined property in a profile from a Maven POM. For more information about user-defined properties and profiles, see Chapter 11, Build Profiles.
You can use Maven to perform variable replacement on project
resources. When resource filtering is activated, Maven will scan resources
for references to Maven property references surrounded by
${ and }. When it finds these
references it will replace them with the appropriate value in much the
same way the properties defined in the previous section can be referenced
from a POM. This feature is especially helpful when you
need to parameterize a build with different configuration values depending
on the target deployment platform.
Often a .properties file or an
XML document in src/main/resources
will contain a reference to an external resource such as a database or a
network location which needs to be configured differently depending on the
target deployment environment. For example, a system which reads data from
a database has an XML document which contains the
JDBC URL along with credentials for
the database. If you need to use a different database in development and a
different database in production. You can either use a technology like
JNDI to externalize the configuration from the application in an
application server, or you can create a build which knows how to replace
variables with different values depending on the target platform.
Using Maven resource filtering you can reference Maven properties
and then use Maven profiles to define different configuration values for
different target deployment environments. To illustrate this feature,
assume that you have a project which uses a the Spring Framework to
configure a BasicDataSource from the Commons DBCP project. Your
project may contain a file in src/main/resources
named applicationContact.xml which contains the
XML listed in Example 13.3, “Referencing Maven Properties from a Resource”.
Example 13.3. Referencing Maven Properties from a Resource
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="someDao" class="com.example.SomeDao"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> </beans>
Your program would read this file at runtime, and your build is
going to replace the references to properties like
jdbc.url and jdbc.username with the
values you defined in your pom.xml. Resource filtering is disabled by
default to prevent any unintentional resource filtering. To turn on
resource filter, you need to use the resources child element of the build
element in a POM. Example 13.4, “Defining Variables and Activating Resource Filtering”
shows a POM which defines the variables referenced in
Example 13.3, “Referencing Maven Properties from a Resource” and which activates resource filtering
for every resource under src/main/resources.
Example 13.4. Defining Variables and Activating Resource Filtering
<project>
...
<properties>
<jdbc.driverClassName>
com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.url>jdbc:mysql://localhost:3306/development_db</jdbc.url>
<jdbc.username>dev_user</jdbc.username>
<jdbc.password>s3cr3tw0rd</jdbc.password>
</properties>
...
<build>
<resources>
<resource>src/main/resources</resource>
<filtering>true</filtering>
</resources>
</build>
...
<profiles>
<profile>
<id>production</id>
<properties>
<jdbc.driverClassName>oracle.jdbc.driver.OracleDriver</jdbc.driverClassName>
<jdbc.url>jdbc:oracle:thin:@proddb01:1521:PROD</jdbc.url>
<jdbc.username>prod_user</jdbc.username>
<jdbc.password>s00p3rs3cr3t</jdbc.password>
</properties>
</profile>
</profiles>
</project>The four variables are defined in the properties
element, and resource filtering is activated for resources under
src/main/resources. Resource filtering is deactivated
by default, and to activate it you must explicitly set
filtering to true for the resources
stored in your project. Filtering is deactivated by default to prevent
accidental, unintentional filtering during your build. If you build a
project with the resource from Example 13.3, “Referencing Maven Properties from a Resource” and the
POM from Example 13.4, “Defining Variables and Activating Resource Filtering” and if you list the contents of
the resource in target/classes, you should see that it contains the
filtered resource:
$ mvn install ... $ cat target/classes/applicationContext.xml ... <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/development_db"/> <property name="username" value="dev_user"/> <property name="password" value="s3cr3tw0rd"/> </bean> ...
The POM in Example 13.4, “Defining Variables and Activating Resource Filtering” also
defines a production profile under the
profiles/profile element which overrides the default
properties with values that would be appropriate for a production
environment. In this particular POM, the default values
for the database connection are for a local MySQL database installed on a
developer's machine. When the project is built with the production profile
activated, Maven will configure the system to connect to a production
Oracle database using a different driver class, URL, username, and
password. If you build a project with the resource from Example 13.3, “Referencing Maven Properties from a Resource” and the POM from Example 13.4, “Defining Variables and Activating Resource Filtering” with the production profile
activated and if you list the contents of the resource in target/classes,
you should see that it contains the filtered resource with production
values:
$ mvn -Pproduction install ... $ cat target/classes/applicationContext.xml ... <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@proddb01:1521:PROD"/> <property name="username" value="prod_user"/> <property name="password" value="s00p3rs3cr3t"/> </bean> ...

