Another Apache project, Maven came well after Ant had come to dominate the Java open source landscape.
Initially seen as a competitor or replacement for Ant
Maven addresses both
Grew out of an observation that many supposedly cooperative, related Apache projects had inconsistent and incompatible ant build structures.
Stated goals are
Making the build process easy
Providing a uniform build system
Providing quality project information
Providing guidelines for best practices development
Allowing transparent migration to new features
Perhaps the easiest way to illustrate maven is to follow the steps in Maven in 5 Minutes
Start with the command
mvn archetype:generate -DgroupId=edu.odu.cs \
-DartifactId=myProject \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
\string~/.m2
directory.cd into the new directory and explore
Building with the Sample Source
Run
mvn package
Explore the target directory to see what has been placed there
For even more fun, try
mvn site
The Maven build file is pom.xml
. The POM for our simple project is
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.odu.cs</groupId> ➀
<artifactId>codeAnnotation</artifactId> ➀
<packaging>jar</packaging> ➁
<version>1.0-SNAPSHOT</version>
<name>codeAnnotation</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
What you didn’t see in the pom.xml
were the targets/tasks that would be used.
ant
, Maven is based on task dependencies.Archetypes can be supplied by
Creating Archetypes
Creating new archetypes is
Maven is usually extended by adding plugins
This project adds a stage before compilation to generate some of the source code that then needs to be compiled.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.odu.cs</groupId>
<artifactId>codeAnnotation</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>codeAnnotation</name>
<!-- site generation:
mvn test
mvn jxr:jxr surefire-report:report
mvn site
-->
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>forge350</id>
<name>ODU CS Forge350 Repository</name>
<url>http://forge350.cs.odu.edu/archiva/repositories/internal</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>forge350Scp</id>
<name>ODU CS Forge350 Repository (scp)</name>
<url>scp://forge350.cs.odu.edu/var/lib/gforge/chroot/home/groups/mavenrepo1/htdocs/repo</url>
</repository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>de.jflex</groupId>
<artifactId>maven-jflex-plugin</artifactId> ➀
<version>1.4.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal> ➁
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
</properties>
</project>
The highlighted portions represent (most) of the changes required.
➀ Here we announce our intention to use a plugin that adds a jflex
step to a java build.
➁ Here we declare that jflex
will be invoked during the generate
build step.
Using plugins is not always simple:
How do we know where to put our jflex
input files?
How do we know that the proper time to use it is during the generate
task?
One of the more popular ways to “escape” when Maven is getting in the way of a simple step is the antrun
plugin
For example, Maven’s built-in process for deciding what goes into a .jar file is to include the compiled classes and anything provided in src/main/resources
But what if I want to include some data files that were constructed during the build process?
Easiest to handle both via a couple of embedded ant tasks
Picking up with the example we used earlier.
Examine the pom.xml file and look for the dependencies
section.
You should see something like
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
This indicates that our project requires the junit package.
Change the version number to
<dependencies>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependencies>
[4.10,]
to get versions 4.10 or greaterTry mvn package
again.
Maven does a transitive search over the dependencies for a project
Maven then downloads the required libraries automatically
~/.m2
)Version ranges can be specified as [low,high]
[
and ]
are inclusive. Use (
and )
for exclusiveExamples
[4.0,4.10]
inclusive range[4.10,)
4.10 or anything more recent[4.10]
4.10 and nothing else4.10
with no brackets means “any version, but prefer 4.10”By default, Maven searches the ibiblio repository, which can be human-searched here.
Try searching for junit
<dependencies>
section to request this version.How does Maven know whether junit itself depends on other libraries?
Near the top of the junit 4.10 page, click to “View” the POM file:
Near the bottom, you will see
<dependencies>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>compile</scope>
</dependencies>
This is the same kind of info that we put into our own pom.xml file
The combination of
was a tremendous advance.
Probably the major factor in attracting Java developers to start working with Maven.
(Oscar Wilde)
Ivy
is an Ant plugin that adds this to Ant