Maven
Goals
- Use Maven to compile a Java project.
- Run a program that from
.class
files output by Maven. - Use Maven to package a Java project.
- Run a program from a
JAR
file packaged by Maven. - Generate Javadoc documentation via a Maven plugin.
Concepts
- bound
- classpath
- coordinates (Maven)
- convention over configuration
- declarative
- goal
- imperative
- JAR file
- life cycle
- Maven
- plugin
- Project Object Model (POM)
- project root directory
- semantic versioning
- snapshot version
Preview
Preparation
- Download and install Maven.
- Make sure your
JAVA_HOME
environment variable is set. - Make sure your
M2_HOME
environment variable is set. - Make sure that the Maven
…/bin
subdirectory is in your systemPATH
environment variable.
- Make sure your
Lesson
Apache Maven is a popular tool used to compile, test, package, and deploy (collectively called “to build” or “the build”) Java projects. Rather than seek out javac
to compile your programs, you'll ask Maven to do it. Once you start working with multiple classes (and using third-party libraries, which you'll learn about another day), you'll appreciate handing the build off to Maven rather than invoking javac
on each file in your source code.
Project Object Model (POM)
The Maven build configuration for a project is stored in the Project Object Model (POM), which is described in a pom.xml
file in the root directory of your project. the POM is stored in a simple XML format, the most basic of which looks like this:
Project Coordinates
Your project is identified by coordinates. The coordinates are extremely important. They make up the basis for identifying components or artifacts in Maven, allowing you to easily use your project with other libraries. There are three minimum coordinates your project must have: groupId
, artifactId
, and version
.
Coordinate | Description |
---|---|
groupId | Some identifier for the individual, company, or organization releasing the application or library. Usually this is the same as the Java package or relevant part of the package identifier. |
artifactId | Something to identify the program or library. Should be lowercase letters, with the hyphen character - allowed. |
version | Something to identify the version of your program. Usually a sequence of number separated by dots, such as 2.0.1 . |
Snapshot Versions
Maven provides an option for programs that are still in flux and would otherwise need to generate a new version number several times a day. If your program is under construction and not yet ready for public release, you can add a -SNAPSHOT
to the end of your version
coordinate, such as 2.0.1-SNAPSHOT
. This let's Maven know not to expect the features of this version to be completely fixed, and not to use any older, cached version of the snapshot when performing builds. You can keep this snapshot version until you are ready for the final release—just don't forget to remove the -SNAPSHOT
before you publish your final product!
Project Directory Structure
Maven expects your project to be stored in a certain standard directory layout, starting at the top-level project root directory you initially created. There are several directories Maven recognizes for different functions; for now, these are all you need to know. Note that although the source code hierarchy merely moves two levels down, the root directory of the project stays the same. See Introduction to the Standard Directory Layout for more details.
pom.xml | Maven POM |
---|---|
src/main/java |
Main source code root directory. e.g. |
When it compiles your project, Maven will produce .class
files, which it places in the target/classes/
directory subtree:
target/ |
Output root directory, containing package archives. (See Packaging below.) e.g. |
---|---|
target/classes |
Receives an accumulation of compiled classes and copied/filtered resources. e.g. |
Maven Life Cycle
When Maven goes about its work, it goes through several stages called phases in the life cycle of the build. (Maven prefers the single word “lifecycle”.) There are many phases to the default life cycle; here are the only ones you need to know right now:
validate
initialize
compile
test
package
- …
Building with Maven
The following instructions work both on Linux and on Windows.
Compiling
When you invoke Maven indicating a particular phase, Maven will execute all phases up to and including the indicated phase. For example, the following command will cause Maven first to validate your project, initialize some settings, and only then compile your source files. You can later ask Maven to perform special actions during those or other phases.
Adding clean
to any Maven invocation will cause Maven first to clean the artifacts from any previous build. For example, mvn clean compile
will cause Maven first to erase the .class
files and other files in the target/
directory before compiling.
Running Your Program from Maven
You can also run your program directly from Maven. You will need to specify the main class of your file, just as you would with java
.
Running Your Program from Class Files
Remember from an earlier lesson that you ran your program by invoking java
from the root directory of your project. Because Maven places the .class
files relative to the the target/classes/
directory, not relative your project root directory, you'll first need to change to that directory before you can run your program.
Another option is to use the java
-classpath
or -cp
option to set the Java classpath, which is (naturally) the path to the location for finding class files.
Testing
Maven knows how to run tests as well. Currently you probably don't have any tests to run; if you did you could enter the following command to have Maven test your program. Maven would also compile your program if needed, because the test
phase comes after the compile
phase in the Maven life cycle.
Packaging
Maven also knows how to package your .class
files in an archive for distributing to others. Most projects consist of more than one class, and distributing multiple .class
files separately would be unwieldy. The most common archive format for distributing Java programs is the JAR file, which is essentially a Zip file with a .jar
extension. This is the type of archive Maven produces by default when it packages your project output.
To package your project, issue the following command to Maven.
This time, along with the .class
file(s) placed in the target/classes/
directory, Maven creates a JAR file containing these files and places it in the target/
directory. Thus the project defined by the example POM above will result in the JAR file target/helloworld-1.0.jar
when Maven packages the project.
Running Your Program from a JAR File
Besides running your program from one or more .class
files as you've have been doing up till now, you can also run a program from a JAR file package. In fact this is the way Java applications are usually run, as Java programs are typically distributed via JAR files instead of individual .class
files. You'll soon see that Maven coupled with JAR files allows easy integration of an application JAR, the library JARs it depends on, their JAR dependencies, and so on.
Running a Java program from a JAR file works similar to running a Java program from a set of .class
files, except that you'll indicate the -classpath
to the JAR instead of the .class
file output root directory.
Plugins
All the actions Maven takes, including compiling your program and executing it from within Maven, are controlled by plugins. One action you might want to take is to generate Javadoc documentation as you have been doing manually using the javadoc
tool. There exists an Apache Maven Javadoc Plugin
that will generate Javadoc documentation for you. By specifying the plugin in the POM and invoking it though Maven, it will already know where your classes are located. Plugins are specified in the <build>
section of your POM.
After adding the plugin to the POM, you need to invoke a goal of the plugin. The Maven Javadoc Plugin has several goals. The first one you will want to try is the javadoc
goal. You can invoke it through Maven itself on the command line, specifying the plugin name and then the goal, separated by a colon :
character.
The Maven Javadoc Plugin will generate documentation as if you had used the javadoc
tool manually; you do not need to specify any packages or output directory. By default the plugin will place the documentation in the target/site/apidocs
directory.
Review
Summary
pom.xml | Maven POM |
---|---|
src/main/java | Main source code root directory. |
target/ | Output root directory, containing package archives. |
target/classes | Receives an accumulation of compiled classes and copied/filtered resources. |
Gotchas
- A Maven project must have a file named
pom.xml
located in the root directory of the project. If the POM is named anything else, or located in another directory, Maven will not build the project. - Don't forget to remove the
-SNAPSHOT
before final release of your program! - The output of a Maven build is usually found in the
target/
directory subtree. Your.class
files will not be placed in the same directory as your.java
files! - If you don't set the Java version in your POM, the
maven-compiler-plugin
will default to assuming your.java
files are written in Java 1.5, which can generate some very perplexing errors.
In the Real World
- Most java programs and libraries are distributed via JAR files. You will seldom if ever work directly with
.class
files; most of the time Maven and/or your Integrated Development Environment (IDE) will take care of them for you.
Think About It
- Are you sure this is the final release of your project? If you're not positive, leave the
-SNAPSHOT
at the end of the version until you're sure. Otherwise, you'll have to increment the version number if you make any further changes before release.
Self Evaluation
- What are Maven “coordinates”?
- What is a Maven “snapshot version”?
- How might you view the contents of a JAR file?
- If you enter
mvn compile
on the command line, what other life cycle phases will Maven execute? What aboutmvn package
? What aboutmvn validate
?
Task
Convert the “Hello World” program you wrote in a previous homework to match the conventions expected by Maven. Be able to clean and package your program using Maven; as well as run your program from the resulting JAR file.
Create a compressed archive of your entire project and send it to your teacher.
See Also
- Maven in 5 Minutes (Apache Maven Project)
- Maven Tutorial 01 Part 1- Introduction and Setting up (YouTube - Java Brains)
- How to Install Maven on Windows for Java - mvn (YouTube - Evil Tester)
- Introduction to the Standard Directory Layout (Apache Maven Project)
- Introduction to the Build Lifecycle (Apache Maven Project)
- Using JAR Files: The Basics (Oracle - The Java™ Tutorials)
References
- POM Reference (Apache Maven Project)
- Guide to naming conventions on groupId, artifactId, and version (Apache Maven Project)
- Semantic Versioning 2.0.0
- JAR File Overview (Oracle - Java™ Platform Overview)
- Guide to Configuring Plug-ins (Apache Maven Project)