Wednesday, October 16, 2024

Maven in 5 Minutes

 

Prerequisites

You must understand how to install software on your computer. If you do not know how to do this, please ask someone at your office, school, etc. or pay someone to explain this to you. The Maven mailing lists are not the best place to ask for this advice.

Installation

Maven is a Java tool, so you must have Java installed in order to proceed.

First, download Maven and follow the installation instructions. After that, type the following in a terminal or in a command prompt:

mvn --version

It should print out your installed version of Maven, for example:

Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: D:\apache-maven-3.6.3\apache-maven\bin\..
Java version: 1.8.0_232, vendor: AdoptOpenJDK, runtime: C:\Program Files\AdoptOpenJDK\jdk-8.0.232.09-hotspot\jre
Default locale: en_US, platform encoding: Cp1250
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

Depending upon your network setup, you may require extra configuration. Check out the Guide to Configuring Maven if necessary.

If you are using Windows, you should look at Windows Prerequisites to ensure that you are prepared to use Maven on Windows.

Creating a Project

You need somewhere for your project to reside. Create a directory somewhere and start a shell in that directory. On your command line, execute the following Maven goal:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false

If you have just installed Maven, it may take a while on the first run. This is because Maven is downloading the most recent artifacts (plugin jars and other files) into your local repository. You may also need to execute the command a couple of times before it succeeds. This is because the remote server may time out before your downloads are complete. Don't worry, there are ways to fix that.

You will notice that the generate goal created a directory with the same name given as the artifactId. Change into that directory.

cd my-app

Under this directory you will notice the following standard project structure.

my-app
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- com
    |           `-- mycompany
    |               `-- app
    |                   `-- App.java
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- app
                        `-- AppTest.java

The src/main/java directory contains the project source code, the src/test/java directory contains the test source, and the pom.xml file is the project's Project Object Model, or POM.

The POM

The pom.xml file is the core of a project's configuration in Maven. It is a single configuration file that contains the majority of information required to build a project in just the way you want. The POM is huge and can be daunting in its complexity, but it is not necessary to understand all of the intricacies just yet to use it effectively. This project's POM should look like this:

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4.  
  5. <groupId>com.mycompany.app</groupId>
  6. <artifactId>my-app</artifactId>
  7. <version>1.0-SNAPSHOT</version>
  8.  
  9. <name>my-app</name>
  10. <!-- FIXME change it to the project's website -->
  11. <url>http://www.example.com</url>
  12.  
  13. <properties>
  14. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  15. <maven.compiler.release>17</maven.compiler.release>
  16. </properties>
  17.  
  18. <dependencyManagement>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.junit</groupId>
  22. <artifactId>junit-bom</artifactId>
  23. <version>5.11.0</version>
  24. <type>pom</type>
  25. <scope>import</scope>
  26. </dependency>
  27. </dependencies>
  28. </dependencyManagement>
  29.  
  30. <dependencies>
  31. <dependency>
  32. <groupId>org.junit.jupiter</groupId>
  33. <artifactId>junit-jupiter-api</artifactId>
  34. <scope>test</scope>
  35. </dependency>
  36. <!-- Optionally: parameterized tests support -->
  37. <dependency>
  38. <groupId>org.junit.jupiter</groupId>
  39. <artifactId>junit-jupiter-params</artifactId>
  40. <scope>test</scope>
  41. </dependency>
  42. </dependencies>
  43.  
  44. <build>
  45. <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
  46. ... lots of helpful plugins
  47. </pluginManagement>
  48. </build>
  49. </project>

What did I just do?

You executed the Maven goal archetype:generate, and passed in various parameters to that goal. The prefix archetype is the plugin that provides the goal. If you are familiar with Ant, you may conceive of this as similar to a task. This archetype:generate goal created a simple project based upon a maven-archetype-quickstart archetype. Suffice it to say for now that a plugin is a collection of goals with a general common purpose. For example the jboss-maven-plugin, whose purpose is "deal with various jboss items".

Build the Project

mvn package

The command line will print out various actions, and end with the following:

 ...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.953 s
[INFO] Finished at: 2019-11-24T13:05:10+01:00
[INFO] ------------------------------------------------------------------------

Unlike the first command executed (archetype:generate), the second is simply a single word - package. Rather than a goal, this is a phase. A phase is a step in the build lifecycle, which is an ordered sequence of phases. When a phase is given, Maven executes every phase in the sequence up to and including the one defined. For example, if you execute the compile phase, the phases that actually get executed are:

  1. validate
  2. generate-sources
  3. process-sources
  4. generate-resources
  5. process-resources
  6. compile

You may test the newly compiled and packaged JAR with the following command:

java -cp target/my-app-1.0-SNAPSHOT.jar com.mycompany.app.App

Which will print the quintessential:

Hello World!

Java 9 or later

By default your version of Maven might use an old version of the maven-compiler-plugin that is not compatible with Java 9 or later versions. To target Java 9 or later, you should at least use version 3.6.0 of the maven-compiler-plugin and set the maven.compiler.release property to the Java release you are targetting (e.g. 9, 10, 11, 12, etc.).

In the following example, we have configured our Maven project to use version 3.8.1 of maven-compiler-plugin and target Java 11:

  1. <properties>
  2. <maven.compiler.release>11</maven.compiler.release>
  3. </properties>
  4.  
  5. <build>
  6. <pluginManagement>
  7. <plugins>
  8. <plugin>
  9. <groupId>org.apache.maven.plugins</groupId>
  10. <artifactId>maven-compiler-plugin</artifactId>
  11. <version>3.8.1</version>
  12. </plugin>
  13. </plugins>
  14. </pluginManagement>
  15. </build>

To learn more about javac's --release option, see JEP 247.

Running Maven Tools

Maven Phases

Although hardly a comprehensive list, these are the most common default lifecycle phases executed.

  • validate: validate the project is correct and all necessary information is available
  • compile: compile the source code of the project
  • test: test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
  • package: take the compiled code and package it in its distributable format, such as a JAR.
  • integration-test: process and deploy the package if necessary into an environment where integration tests can be run
  • verify: run any checks to verify the package is valid and meets quality criteria
  • install: install the package into the local repository, for use as a dependency in other projects locally
  • deploy: done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

There are two other Maven lifecycles of note beyond the default list above. They are

  • clean: cleans up artifacts created by prior builds
  • site: generates site documentation for this project

Phases are actually mapped to underlying goals. The specific goals executed per phase is dependant upon the packaging type of the project. For example, package executes jar:jar if the project type is a JAR, and war:war if the project type is - you guessed it - a WAR.

An interesting thing to note is that phases and goals may be executed in sequence.

mvn clean dependency:copy-dependencies package

This command will clean the project, copy dependencies, and package the project (executing all phases up to package, of course).

Generating the Site

mvn site

This phase generates a site based upon information on the project's pom. You can look at the documentation generated under target/site.

Conclusion

We hope this quick overview has piqued your interest in the versatility of Maven. Note that this is a very truncated quick-start guide. Now you are ready for more comprehensive details concerning the actions you have just performed. Check out the Maven Getting Started Guide.

Introduction to Archetypes

 

What is Archetype?

In short, Archetype is a Maven project templating toolkit. An archetype is defined as an original pattern or model from which all other things of the same kind are made. The name fits as we are trying to provide a system that provides a consistent means of generating Maven projects. Archetype will help authors create Maven project templates for users, and provides users with the means to generate parameterized versions of those project templates.

Using archetypes provides a great way to enable developers work quickly in a way consistent with best practices employed by your project or organization. Within the Maven project, we use archetypes to try and get our users up and running as quickly as possible by providing a sample project that demonstrates many of the features of Maven, while introducing new users to the best practices employed by Maven. In a matter of seconds, a new user can have a working Maven project to use as a jumping board for investigating more of the features in Maven. We have also tried to make the Archetype mechanism additive, and by that we mean allowing portions of a project to be captured in an archetype so that pieces or aspects of a project can be added to existing projects. A good example of this is the Maven site archetype. If, for example, you have used the quick start archetype to generate a working project, you can then quickly create a site for that project by using the site archetype within that existing project. You can do anything like this with archetypes.

You may want to standardize J2EE development within your organization, so you may want to provide archetypes for EJBs, or WARs, or for your web services. Once these archetypes are created and deployed in your organization's repository, they are available for use by all developers within your organization.

Using an Archetype

To create a new project based on an Archetype, you need to call mvn archetype:generate goal, like the following:

mvn archetype:generate

Please refer to Archetype Plugin page.

Provided Archetypes

Maven provides several Archetype artifacts:

Archetype ArtifactIdsDescription
maven-archetype-archetypeAn archetype to generate a sample archetype project.
maven-archetype-j2ee-simpleAn archetype to generate a simplifed sample J2EE application.
maven-archetype-mojoAn archetype to generate a sample a sample Maven plugin.
maven-archetype-pluginAn archetype to generate a sample Maven plugin.
maven-archetype-plugin-siteAn archetype to generate a sample Maven plugin site.
maven-archetype-portletAn archetype to generate a sample JSR-268 Portlet.
maven-archetype-quickstartAn archetype to generate a sample Maven project.
maven-archetype-simpleAn archetype to generate a simple Maven project.
maven-archetype-siteAn archetype to generate a sample Maven site which demonstrates some of the supported document types like APT, XDoc, and FML and demonstrates how to i18n your site.
maven-archetype-site-simpleAn archetype to generate a sample Maven site.
maven-archetype-webappAn archetype to generate a sample Maven Webapp project.

For more information on these archetypes, please refer to the Maven Archetype Bundles page.

What makes up an Archetype?

Archetypes are packaged up in a JAR and they consist of the archetype metadata which describes the contents of archetype, and a set of Velocity templates which make up the prototype project. If you would like to know how to make your own archetypes, please refer to our Guide to creating archetypes.

Introduction to the Standard Directory Layout

 Having a common directory layout allows users familiar with one Maven project to immediately feel at home in another Maven project. The advantages are analogous to adopting a site-wide look-and-feel.

The next section documents the directory layout expected by Maven and the directory layout created by Maven. Try to conform to this structure as much as possible. However, if you can't, these settings can be overridden via the project descriptor.

src/main/javaApplication/Library sources
src/main/resourcesApplication/Library resources
src/main/filtersResource filter files
src/main/webappWeb application sources
src/test/javaTest sources
src/test/resourcesTest resources
src/test/filtersTest resource filter files
src/itIntegration Tests (primarily for plugins)
src/assemblyAssembly descriptors
src/siteSite
LICENSE.txtProject's license
NOTICE.txtNotices and attributions required by libraries that the project depends on
README.txtProject's readme

At the top level, files descriptive of the project: a pom.xml file. In addition, there are textual documents meant for the user to be able to read immediately on receiving the source: README.txtLICENSE.txt, etc.

There are just two subdirectories of this structure: src and target. The only other directories that would be expected here are metadata like CVS.git or .svn, and any subprojects in a multiproject build (each of which would be laid out as above).

The target directory is used to house all output of the build.

The src directory contains all of the source material for building the project, its site and so on. It contains a subdirectory for each type: main for the main build artifact, test for the unit test code and resources, site and so on.

Within artifact producing source directories (ie. main and test), there is one directory for the language java (under which the normal package hierarchy exists), and one for resources (the structure which is copied to the target classpath given the default resource definition).

If there are other contributing sources to the artifact build, they would be under other subdirectories. For example src/main/antlr would contain Antlr grammar definition files.Having a common directory layout allows users familiar with one Maven project to immediately feel at home in another Maven project. The advantages are analogous to adopting a site-wide look-and-feel.

The next section documents the directory layout expected by Maven and the directory layout created by Maven. Try to conform to this structure as much as possible. However, if you can't, these settings can be overridden via the project descriptor.

src/main/javaApplication/Library sources
src/main/resourcesApplication/Library resources
src/main/filtersResource filter files
src/main/webappWeb application sources
src/test/javaTest sources
src/test/resourcesTest resources
src/test/filtersTest resource filter files
src/itIntegration Tests (primarily for plugins)
src/assemblyAssembly descriptors
src/siteSite
LICENSE.txtProject's license
NOTICE.txtNotices and attributions required by libraries that the project depends on
README.txtProject's readme

At the top level, files descriptive of the project: a pom.xml file. In addition, there are textual documents meant for the user to be able to read immediately on receiving the source: README.txtLICENSE.txt, etc.

There are just two subdirectories of this structure: src and target. The only other directories that would be expected here are metadata like CVS.git or .svn, and any subprojects in a multiproject build (each of which would be laid out as above).

The target directory is used to house all output of the build.

The src directory contains all of the source material for building the project, its site and so on. It contains a subdirectory for each type: main for the main build artifact, test for the unit test code and resources, site and so on.

Within artifact producing source directories (ie. main and test), there is one directory for the language java (under which the normal package hierarchy exists), and one for resources (the structure which is copied to the target classpath given the default resource definition).

If there are other contributing sources to the artifact build, they would be under other subdirectories. For example src/main/antlr would contain Antlr grammar definition files.

Download & Install Maven

Downloading Apache Maven 3.9.9

Apache Maven 3.9.9 is the latest release: it is the recommended version for all users.

System Requirements

Java Development Kit (JDK)Maven 3.9+ requires JDK 8 or above to execute. It still allows you to build against 1.3 and other JDK versions by using toolchains.
MemoryNo minimum requirement
DiskApproximately 10MB is required for the Maven installation itself. In addition to that, disk space will be used for your local Maven repository. The size of your local repository will vary depending on usage but expect at least 500MB.
Operating SystemNo minimum requirement. Start up scripts are included as shell scripts (tested on many Unix flavors) and Windows batch files.

Files

Maven is distributed in several formats for your convenience. Simply pick a ready-made binary distribution archive and follow the installation instructions. Use a source archive if you intend to build Maven yourself.

In order to guard against corrupted downloads/installations, it is highly recommended to verify the signature of the release bundles against the public KEYS used by the Apache Maven developers.

LinkChecksumsSignature
Binary tar.gz archiveapache-maven-3.9.9-bin.tar.gzapache-maven-3.9.9-bin.tar.gz.sha512apache-maven-3.9.9-bin.tar.gz.asc
Binary zip archiveapache-maven-3.9.9-bin.zipapache-maven-3.9.9-bin.zip.sha512apache-maven-3.9.9-bin.zip.asc
Source tar.gz archiveapache-maven-3.9.9-src.tar.gzapache-maven-3.9.9-src.tar.gz.sha512apache-maven-3.9.9-src.tar.gz.asc
Source zip archiveapache-maven-3.9.9-src.zipapache-maven-3.9.9-src.zip.sha512apache-maven-3.9.9-src.zip.asc


Installing Apache Maven

The installation of Apache Maven is a simple process of extracting the archive and adding the bin directory with the mvn command to the PATH.

Detailed steps are:

  • Have a JDK installation on your system. Either set the JAVA_HOME environment variable pointing to your JDK installation or have the java executable on your PATH.

  • Extract distribution archive in any directory

unzip apache-maven-3.9.9-bin.zip

or

tar xzvf apache-maven-3.9.9-bin.tar.gz

Alternatively use your preferred archive extraction tool.

  • Add the bin directory of the created directory apache-maven-3.9.9 to the PATH environment variable

  • Confirm with mvn -v in a new shell. The result should look similar to

Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: /opt/apache-maven-3.9.9
Java version: 1.8.0_45, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.8.5", arch: "x86_64", family: "mac"