# Managing Builds with Maven

Abstract

Maven combines build management with configuration management (a future topic in this course). It attempts to standardize the build process in a way that improves consistency from project to project and enforces local best practices.

In this lesson, we will look at the capabilities and limitations of Maven and how projects can be structured to use it. We will look at how it works with some of our sample projects.

# 1 Why Maven?

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

• build management (as does Ant)
• and configuration management (which Ant does not)
• Later, we’ll talk about Ivy, which adds configuration mgmt to Ant

Maven as a Build Manager

Maven uses an underlying task dependency model, but the tasks and their dependencies are pre-defined for a collection of archetype projects.

As a consequence, maven offers far less flexibility than ant, but a basic, unaltered maven build may include tasks that less experienced developers would never think to include or might have difficulty adding to a more conventional build manager.

Motivations for Maven

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

Uniform Build System

• Maven supports archetype projects that standardize

• directory structure

• Source code kept in separate directory tree from both intermediate and final build products
• Tests occupy separate subtrees of the source and product trees
• “Life Cycle”

• Really, a presumptuous name on their part for a build process
• A sequence of goals
• Archetypes can be obtained from the Maven project or tailored for an organization.

Providing quality project information

• Aids in building & maintaining project web sites (e.g.)

Providing guidelines for best practices development

• Unit testing

• Encourage familiarity with approved archetypes

# 2 Maven as a Build Manager

mvn archetype:generate -DgroupId=edu.odu.cs \
-DartifactId=codeAnnotation \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false

• Lots of libraries (mainly comprising the latest version of Maven system itself) will be downloaded into your \string~/.m2 directory.
• A directory, codeAnnotation, will be created.
• cd into the new directory and explore

• src directory structure
• pom.xml is the build file for this project

Building with the Sample Source

• Run

mvn package


• Sample source code is compiled
• Sample unit test is run and executed.
• A jar file is created with the sample source code
• Explore the target directory to see what has been placed there

OK, that was fun…

Let’s try this with some real source code.

• Delete the target directory (or run mvn clean)

• Replace the contents of src/main/java and src/test/java by the corresponding contents from my code Annotation project.

• Also, copy src/main/jflex while we’re at it, though we won’t use this right away.
• Try mvn package again.

What Went Wrong?

• A glance at the code with the error messages won’t show anything obvious.

• But I happen to know that Maven defaults to running the Java compiler in Java 5 compatibility mode
• This code uses Java 7 features
• Edit the pom.xml file and, just above the <dependencies> section, add

  <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>

• Then try mvn package again

That was a little better

• The main source code compiled successfully.

• The error was in the compilation of the unit tests

• The first error message says
[ERROR] /home/.../codeAnnotation/src/test/java/edu/odu/cs/codeAnnotation/TestC2HOptions.java:[3,23] package org.junit does not exist

• Looks to be a problem with the JUnit library

• In the original project, I was keeping a copy of junit4.jar in the project directory.

• A clumsy solution

• Which we’ll solve when we take up configuration management.

# 3 Case Studies

## 3.1 Simple Java Build

Well, we pretty much just did that.

1. Use mvn archetype:generate to set up the directories and build file.

2. Replace maven’s “Hello World” code by the real source code.

## 3.2 Java Build with Code Generation

Not All Sourcecode is Hand-Written

This project adds a stage before compilation to generate some of the source code that then needs to be compiled.

pom.xml.listing
<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>
<url>https://secweb.cs.odu.edu/~zeil/cs795SD/s13/Directory/topics.html</url>
<description>
This is a tool used to parse code listings and to
generate syntax-highlighted C++/Java listings in both
HTML and LaTeX.

Markup can be added in the form of special comments that will
be recognized as instructions to highlight blocks of code, to
add callout symbols, or to insert vertical ellipses.
</description>

<!-- site generation:
mvn test
mvn surefire-report:report
mvn site
-->

<repositories>
</repositories>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.jflex</groupId>
<artifactId>jflex</artifactId>
<version>1.4.3</version>
</dependency>
</dependencies>
<build>
<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>
</pluginManagement>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>


TYhe 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.

How do we know where to put our jflex input files?

• We learn that by reading the documentation of the plugin.

How do we know that the proper time to use it is during the generate task?

• We learn that by reading the documentation of the Java project archetype.

## 3.3 C++ Multi-project Build

Not even going to try and go there.

I’ve never had much luck getting maven to work with C++.