Apache Maven or in short just Maven, is popular for its build capabilities. That is why, most people refer to Maven, as a Build Automation tool, or in short - just a Build Tool.
Yet, Maven is not just a build tool; but it is more than that. The project team responsible for the development and maintenance of Maven, describes Maven as a software project management and comprehension tool.
Based on the concept of a Project Object Model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.
Do remember this term, Project Object Model or in short POM, because you will hear and use it all the time when talking about Maven. We will discuss POM in detail in our later videos.
So, as you can see, Maven aims to be, more than, just a Build Automation Tool.
More than a Build Tool
But, you might ask, what do we mean by “More than a Build Tool”?
Well, apart from providing the build capabilities, which comprise of:
Pre-processing - where-in you initialize your build which could mean setting up environment variables, processing some configuration files for the build, copying files if you need, and then
Compile - where you take the actual source code and compile to ensure there are no errors in your code, and then you
Test - the code by running the automation tests (be it unit test or integration test) and once, your code is tested, you
Package - your code where-in, you will be creating a jar file or zip file or a docker image or whatever your packaging need is. And finally, you
Distribute it - So, you would be publishing to your companyβs repository of artifacts or deploy the packaged artifact on a server.
But apart from all of this (the build tooling), Maven can do things like generating reports. These reports could be a Unit Test report, or you have a tool that does some Performance testing of your application. Maven can take the performance test data and generate a report and publish them.
You can also generate a documentation website from Maven. People who are familiar with Javadoc, Maven provides support to generate Javadoc, which is a very common documentation format for Java source code.
What else - you can also use it to communicate within your team. Maven can act as a team member and can send you notification on your Slack or Hangouts or any other messenger.
And it can do a lot - a lot more things.
Dependencies
All applications built today have dependencies.
The below XKCD diagram depicts the nature of modern day applications and their interdependence.
As much as using dependencies allows us to quickly build the applications, dependency management becomes important.
One of the biggest benefits or features that Maven brings with it, is Dependency Management. If you have ever worked with Apache ANT, you will know how much things got better, when you started using Maven.
A typical Java application these days has multiple dependencies. For example, here I have an application which has 2 dependencies. A Web Server that is going to handle requests(Tomcat or Jetty), and I have a database driver that allows me to connect to the database.
Without Maven, I will need to download the jars from the internet, copy them to the library folder, and then add these in the application classpath. Now, when I run the application, after compilation and building, the application works.
Now, thatβs a lot of manual work.
Instead of manually managing these dependencies, I can configure these dependencies in Maven and let Maven do the hard work. Maven will download the jar files from the internet, use them for compiling, testing and then package it along with the final packaged artifact.
You might think, these are just two files and I can manage that. But these days, a typical java application has easily more than 10 dependencies/jar files. If you start managing these dependencies manually, trust me, it is going to be a nightmare.
Managing Dependencies Manually (an example)
In fact, let me give you an example how managing dependency manually can easily go out of control.
So taking the previous example, we have WebServer version 1.0 and DB Driver version 1.0 in the application. The application is running fine and there are no issues.
Consider, there is a critical security bug reported in Web Server 1.0 (and this happens all the time). Developers managing Web Server, fix the security bug and release a new version. This new version is Web Server 2.0. Since we do not want the security bug to affect our application, we will need to update the Web Server dependency from 1.0 to 2.0. So, we will download the latest Web Server 2.0 jar, and add it to the application.
But, when we try to run the application, it fails. Why?
Because, in a hurry to fix the security bug, WebServer 2.0 became incompatible with DB Driver 1.0. Developers of DB Driver, on realizing this, fixes the compatibility issue and releases their version DB Driver version 2.0.
So, what will we have to do now?
Again the same process, update DB Driver to version 2.0. We download the jar file, add it to our application and then now, the application starts to run again.
This is a very simple example with just 2 dependencies. Manual dependency management gets really, really complicated once you start to deal with dependency over 10.
Worse, you update a single dependency, and you see multiple other dependencies becoming incompatible with each other. There is a cascading update of the dependencies required, until all incompatibilities are resolved, to eventually have the application work fine.
We will configure both Web Server and DB Driver dependency in the Maven configuration file. Whenever we update any of the dependencies, all related compatible dependencies are also fetched by Maven.
In our example, when we update Web Server 2.0 in the Maven configuration file, Maven automatically fetches the compatible DB Driver 2.0.
And all this happens magically, under the hood. All you do is update the Maven configuration file, and Maven does the magic for you.
How Maven does its Magic?
But, you might wonder - how does Maven do all this Magic? The answer to that question is - Plugins.
Maven makes use of Plugins. Whatever activity you can think of, there is a plugin for that activity.
In fact, there is even a plugin to create the Maven project structure called archetype. It allows you to create your starting project structure - your folders for source code, folder for test classes, and then create the Maven configuration file, so that you can adjust settings as per your need.
Whatever Maven does, it does it with the help of plugins. These plugins contain the code to perform the activity. Maven just triggers the plugin code as per userβs needs, via the Maven configuration file.
Is Maven multi-platform?
Maven works on all three platforms, Windows, Mac and Linux. All, you need is Java installed on your system to run Maven on your system.
And that is a very brief introduction to Apache Maven.
This article gives you a step by step walkthrough for installing Apache Maven on Linux.
You can watch the entire installation demo in this video.
Introduction
Apache Maven is the most popular build and project management tool for Java projects. Maven is built on top of Java, so if you plan to install Maven on your system, you need to have Java installed on your system.
Installation of Maven on any system consists of following 3 steps.
Download the Apache Maven binary zip from the official website
Extracting the binary zip into a specific folder
Configure the environment variables of the System.
Let me walk you through these steps in detail for a Linux system.
Info
The latest Apache Maven version at the time of writing this is 3.9.9. All screenshots and commands in this article refer to this version. But they are equally applicable to other versions, as well.
1. Downloading the Apache Maven
The first step is to download the Apache Maven from the official website. The downloads page for Apache Maven is this - https://maven.apache.org/download.cgi. On this page, you have two binary options to download - either a zip file or a tar.gz file(marked in blue boxes). Here is the screenshot below.
You can choose either of these. If you are not sure, choose the zip file. Also, download the corresponding checksum file(marked in orange boxes) so that you can validate the zip file download.
You can use your browser to download these, or you can use the wget or curl on the command prompt to download the files.
Here is the command using the wget that download the zip file and the corresponding checksum file.
-> wget -q --show-progress https://dlcdn.apache.org/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.zip
apache-maven-3.9.9-bin.zip 100%[======================================================>] 8.78M 17.8MB/s in 0.5s
-> wget -q --show-progress https://downloads.apache.org/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.zip.sha512
apache-maven-3.9.9-bin.zip.sha5 100%[======================================================>] 128 --.-KB/s in 0s
-> ls -l
-rw-rw-r-- 1 thedevjournal thedevjournal 9202456 Jan 27 15:24 apache-maven-3.9.9-bin.zip
-rw-rw-r-- 1 thedevjournal thedevjournal 128 Jan 27 15:26 apache-maven-3.9.9-bin.zip.sha512
Tip
If you don’t have wget and/or curl installed, you can run sudo apt install wget curl -y. Find more install options here - for wget, and for curl
2. Extracting the Binary archive File
2.1. Verifying the Checksum
Before you extract the zip or tar.gz file, perform a quick checksum validation of the downloaded file to ensure that there were no issues with the download.
The checksum files mentions which kind of hash is used for zip file. Its sha512, and hence we need sha512sum command to calculate the checksum of the zip file. This command is part of coreutils package and if you don’t have install, you can install it with your package manager. Here is a list of installation commands for installing coreutils on your Linux distribution.
-> sha512sum apache-maven-3.9.9-bin.zip
8beac8d11ef208f1e2a8... (removed in favour of brevity) ...82ee8a2ff4c4418ba apache-maven-3.9.9-bin.zip
-> cat apache-maven-3.9.9-bin.zip.sha512
8beac8d11ef208f1e2a8... (removed in favour of brevity) ...82ee8a2ff4c4418ba
A quick glance, you would see that both the checksums are same and that ensures that the download was completed without any errors.
2.2. Installation Directory
Before we extract the binary archive file, we need a directory. It is a good practice to keep all of your installations together, so you can place them in a directory called installed in your home directory(~).
You can create this directory if it does not exist using the mkdir command. Inside this installed directory, we need to create our maven3 directory where we will extract our binary archive file. You can create these directories like this.
-> mkdir -p ~/installed/maven3
Afterwards, we need to move our binary archive file in this maven3 directory, and then we cd into this directory so that we can extract the archive file here.
-> mv apache-maven-3.9.9-bin.zip ~/installed/maven3/
-> cd ~/installed/maven3
2.3. Extracting the Binary file
If you have downloaded the zip file, you will need unzip command to extract the zip file. After extracting the zip file, you won’t need it, so you can delete that.
And if you have downloaded the tar.gz file, you will need tar command.
-> tar -xf apache-maven-3.9.9-bin.tar.gz
-> rm apache-maven-3.9.9-bin.tar.gz -f
Creating a Symbolic Link
You don’t need to create a symbolic link to the newly extracted folder, but it will make your life easier if a symbolic link always pointed to latest Maven installation.
So, if next time, you upgrade the Maven installation from 3.9.9 to 3.9.10, you can just update the symbolic link and everything should continue to work as it is. You won’t have to update any environment variables(discussed in the next section)
Here is how you will create a symbolic link.
-> ln -s apache-maven-3.9.9 latest
Configure the Environment Variables
With the extraction of binary archive file in the installed/maven3 directory, Maven is pretty much installed in your system. The only gotcha is that every-time you need to run the mvn command, you will have to traverse the entire path - ~/installed/maven3/latest/bin/mvn. It will be much better, if we could just run the mvn command from any directory without specifying the entire path to the mvn executable.
A lot of Java tools look for M2_HOME environment variable to locate the Maven installation directory in the system. This environment variable can be configured in any of your .bash_profile, .bashrc, .profile file. This is the entry that you will need to put.
export M2_HOME="~/installed/maven3/latest"
Once, this is configured, we need to configure the PATH variable, that will enable running of the mvn command from any directory. Here is how, it will be configured in your .bashrc or .bash_profile file.
export PATH="$PATH:$M2_HOME/bin"
Once this is configured, you need to re-import the configurations. Simple close the current terminal window and open a new one.
And now if you run mvn -version, you should see the Maven installation details confirming that you have Apache Maven installed successfully.
This article gives you a step by step walkthrough for installing Apache Maven on Mac.
You can watch the entire installation demo in this video.
Introduction
Apache Maven is the most popular build and project management tool for Java projects. Maven is built on top of Java, so if you plan to install Maven on your system, you need to have Java installed on your system.
Installation of Maven on any system consists of following 3 steps.
Download the Apache Maven binary zip from the official website
Extracting the binary zip into a specific folder
Configure the environment variables of the System.
Let me walk you through these steps in detail for a Mac system.
Info
The latest Apache Maven version at the time of writing this is 3.9.9. All screenshots and commands in this article refer to this version. But they are equally applicable to other versions, as well.
1. Downloading the Apache Maven
The first step is to download the Apache Maven from the official website. The downloads page for Apache Maven is this - https://maven.apache.org/download.cgi. On this page, you have two binary options to download - either a zip file or a tar.gz file(marked in blue boxes). Here is the screenshot below.
You can choose either of these. If you are not sure, choose the zip file. Also, download the corresponding checksum file(marked in orange boxes) so that you can validate the zip file download.
You can use your browser to download these, or you can use the wget or curl on the command prompt to download the files.
Here is the command using the wget that download the zip file and the corresponding checksum file.
-> wget -q --show-progress https://dlcdn.apache.org/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.zip
apache-maven-3.9.9-bin.zip 100%[======================================================>] 8.78M 17.8MB/s in 0.5s
-> wget -q --show-progress https://downloads.apache.org/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.zip.sha512
apache-maven-3.9.9-bin.zip.sha5 100%[======================================================>] 128 --.-KB/s in 0s
-> ls -l
-rw-rw-r-- 1 thedevjournal thedevjournal 9202456 Jan 27 15:24 apache-maven-3.9.9-bin.zip
-rw-rw-r-- 1 thedevjournal thedevjournal 128 Jan 27 15:26 apache-maven-3.9.9-bin.zip.sha512
Tip
If you don’t have wget and/or curl installed, you can install these through homebrew via brew install wget and/or brew install curl.
2. Extracting the Binary archive File
2.1. Verifying the Checksum
Before you extract the zip or tar.gz file, perform a quick checksum validation of the downloaded file to ensure that there were no issues with the download.
The checksum files mentions which kind of hash is used for zip file. Its sha512, and hence we need shasum command to calculate the checksum of the zip file.
-> shasum -a 512 apache-maven-3.9.9-bin.zip
8beac8d11ef208f1e2a8... (removed in favour of brevity) ...82ee8a2ff4c4418ba apache-maven-3.9.9-bin.zip
-> cat apache-maven-3.9.9-bin.zip.sha512
8beac8d11ef208f1e2a8... (removed in favour of brevity) ...82ee8a2ff4c4418ba
A quick glance, you would see that both the checksums are same and that ensures that the download was completed without any errors.
2.2. Installation Directory
Before we extract the binary archive file, we need a directory. It is a good practice to keep all of your installations together, so you can place them in a directory called installed in your home directory(~).
You can create this directory if it does not exist using the mkdir command. Inside this installed directory, we need to create our maven3 directory where we will extract our binary archive file. You can create these directories like this.
-> mkdir ~/installed
-> mkdir ~/installed/maven3
Afterwards, we need to move our binary archive file in this maven3 directory, and then we cd into this directory so that we can extract the archive file here.
-> mv apache-maven-3.9.9-bin.zip ~/installed/maven3/
-> cd ~/installed/maven3
2.3. Extracting the Binary file
If you have downloaded the zip file, you will need unzip command to extract the zip file. After extracting the zip file, you won’t need it, so you can delete that.
And if you have downloaded the tar.gz file, you will need tar command.
-> tar -xf apache-maven-3.9.9-bin.tar.gz
-> rm apache-maven-3.9.9-bin.tar.gz
Creating a Symbolic Link
You don’t need to create a symbolic link to the newly extracted folder, but it will make your life easier if a symbolic link always pointed to latest Maven installation.
So, if next time, you upgrade the Maven installation from 3.9.9 to 3.9.10, you can just update the symbolic link and everything should continue to work as it is. You won’t have to update any environment variables(discussed in the next section)
Here is how you will create a symbolic link.
-> ln -s apache-maven-3.9.9 latest
Configure the Environment Variables
With the extraction of binary archive file in the installed/maven3 directory, Maven is pretty much installed in your system. The only gotcha is that every-time you need to run the mvn command, you will have to traverse the entire path - ~/installed/maven3/latest/bin/mvn. It will be much better, if we could just run the mvn command from any directory without specifying the entire path to the mvn executable.
A lot of Java tools look for M2_HOME environment variable to locate the Maven installation directory in the system. This environment variable can be configured in your .zshrc file. This is the entry that you will need to put.
Change devjournal to your username in the above path
Once, this is configured, we need to configure the PATH variable, that will enable running of the mvn command from any directory. Here is how, it will be configured in your .zshrc file.
export PATH="$PATH:$M2_HOME/bin"
Once this is configured, you need to re-import the configurations. Simple close the current terminal window and open a new one.
And now if you run mvn -version, you should see the Maven installation details confirming that you have Apache Maven installed successfully.
This article gives you a step by step walkthrough for installing Apache Maven on Mac.
You can watch the entire installation demo in this video.
Introduction
Apache Maven is the most popular build and project management tool for Java projects. Maven is built on top of Java, so if you plan to install Maven on your system, you need to have Java installed on your system.
Installation of Maven on any system consists of following 3 steps.
Download the Apache Maven binary zip from the official website
Extracting the binary zip into a specific folder
Configure the environment variables of the System.
Let me walk you through these steps in detail for a Mac system.
Info
The latest Apache Maven version at the time of writing this is 3.9.9. All screenshots and commands in this article refer to this version. But they are equally applicable to other versions, as well.
1. Downloading the Apache Maven
The first step is to download the Apache Maven from the official website. The downloads page for Apache Maven is this - https://maven.apache.org/download.cgi. On this page, you have two binary options to download - either a zip file or a tar.gz file(marked in blue boxes). Here is the screenshot below.
You can choose either of these. If you are not sure, choose the zip file. Also, download the corresponding checksum file (marked in orange boxes) so that you can validate the zip file download.
You can use your browser to download these, or you can use the curl on the command prompt to download the files.
Here is the command using the curl that download the zip file and the corresponding checksum file.
Before you extract the zip file, perform a quick checksum validation of the downloaded file to ensure that there were no issues with the download.
The checksum files mentions which kind of hash is used for zip file. Windows provides CertUtil which allows to generate checksum of files using -hashfile operation. Since the Maven checksum file uses SHA-512 format, we also need to generate the hash in the same format.
PS C:\Users\thedevjournal\Downloads> CertUtil -hashfile .\apache-maven-3.9.9-bin.zip SHA512
SHA512 hash of .\apache-maven-3.9.9-bin.zip:
8beac8d11ef208f1e2a8... (removed in favour of brevity) ...82ee8a2ff4c4418ba
CertUtil: -hashfile command completed successfully.
PS C:\Users\thedevjournal\Downloads> cat .\apache-maven-3.9.9-bin.zip.sha512
8beac8d11ef208f1e2a8... (removed in favour of brevity) ...82ee8a2ff4c4418ba
A quick glance, you would see that both the checksums are same and that ensures that the download was completed without any errors.
2.2. Installation Directory
Before we extract the binary archive file, we need a directory. It is a good practice to keep all of your installations together, so you can place them in a directory called installed in your C drive(C:\).
You can create this directory if it does not exist using the mkdir command.
Afterwards, we need to move our binary archive file inside C:\installed directory, and then we cd into this directory so that we can extract the archive file here.
PS C:\Users\thedevjournal\Downloads> mv apache-maven-3.9.9-bin.zip C:\installed
PS C:\Users\thedevjournal\Downloads> cd C:\installed
2.3. Extracting the Binary file
You will use Expand-Archive command to extract the contents of the zip file.
PS C:\installed> Expand-Archive .\apache-maven-3.9.9-bin.zip
PS C:\installed> dir
Directory: C:\installed
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 02-02-202505:35 apache-maven-3.9.9-bin
-a---- 02-02-202505:189202456 apache-maven-3.9.9-bin.zip
PS C:\installed> dir .\apache-maven-3.9.9-bin\
Directory: C:\installed\apache-maven-3.9.9-bin
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 02-02-202505:35 apache-maven-3.9.9
Expand-Archive extracts the file contents inside the apache-maven-3.9.9-bin directory, hence we also need to move the new extracted folder 1 level above. And then, we can delete the zip file and the empty extraction folder.
With the extraction of binary archive file in the installed directory, Maven is pretty much installed in your system. The only gotcha is that every-time you need to run the mvn command, you will have to traverse the entire path - C:\installed\apache-maven-3.9.9\bin\mvn. It will be much better, if we could just run the mvn command from any directory without specifying the entire path to the mvn executable.
A lot of Java tools look for M2_HOME environment variable to locate the Maven installation directory in the system. This environment variable can be configured using [System.Environment]::SetEnvironmentVariable. This is the command:
The 3rd parameter, User indicates that you intend to store this variable across multiple sessions, and only available to the user who is logged in. If you want to set this variable system-wide, use Machine as the parameter.
Once, this is configured, we need to configure the PATH variable, that will enable running of the mvn command from any directory. Here is how, it will be configured:
This article demonstrates the very first build with Apache Maven. In this article, we will use command prompt to create our simple Maven project and then use mvn command to build it.
You can watch the entire demo in this video.
Pre-requisite
You need to have Apache Maven already installed on your system. If you don’t have Maven installed, you can install it by following steps from our previous articles:
In this article, we will create the Maven project from the command prompt using the mvn command. This basic project scaffolding is done using the maven-archetype-plugin. This plugin the one that is used by the IDEs under the hood to create the Project.
The archetype plugin has a numerous template projects to chose from and also from various sources. If you type simple mvn archetype:generate, you will be presented with 3500+ various project templates. You can use the filter option to limit the search and chose, but in most cases, it is preferable to use an IDE.
The Archetype plugin works in interactive and non-interactive mode. In the interactive mode, you need to select the project template from which the project should be created and then you need to provide the maven coordinates.
If you already know the archetype, it is advisable to use the non-interactive mode. This is the approach which we will use in this article.
So, fire up a new Terminal window, and run the following command:
If you are running this for the very first time, then Maven will download the plugin jars from the Maven central, and you will see those in your console. Don’t worry, these will be just downloaded just once and occasionally when there is a new update to the plugin that is being executed.
The command is a long one, so let us dissect it one at a time.
archetype:generate
This is a goal of archetype plugin that is responsible for generating for the project. Maven’s plugin execution follows this convention plugin:goal to execute the various executions goals provided by the plugin. A full list of archetype plugin’s goals are listed here.
Because, we need to create a project from a template, we use the generate goal.
Property arguments to Maven are provided using -D prefix. In our case, we are providing a property interactiveMode which is used by archetype plugin. This tells the archetype plugin that it should not prompt the user for any mandatory value that is not provided. It will instead error out mentioning which value was missing.
In the interactive mode, Maven will use the values that you have provided and if any value is missing, it will ask you to provide them on the prompt.
Since, we are providing all the mandatory values as property arguments, we are disabling the interactive mode by interactiveMode=false.
-DarchetypeGroupId=org.apache.maven.archetypes
This property tells the Archetype plugin to select the groupId of the archetype that need to be used to create the project. There can be multiple organizations or teams that are creating their own archetypes, and they could clash. The archetypeGroupId provides the ability to avoid such collisions.
For example, if you type mvn archetype:generate, and when the plugin is asking you to provide the archetype id or filter option, type maven-archetype-simple. You will see that there are three archetypes that define the same artifact id. Here is the output.
-> mvn archetype:generate
...
...
3523: remote -> za.co.absa.hyperdrive:component-archetype_2.12 (-)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 2216: maven-archetype-simple
Choose archetype:
1: remote -> com.haoxuer.maven.archetype:maven-archetype-simple (a simple maven archetype)
2: remote -> fr.ebruno.maven.archetypes:maven-archetype-simple (An archetype which contains a simple Maven project.)
3: remote -> org.apache.maven.archetypes:maven-archetype-simple (An archetype which contains a simple Maven project.)
As you can see, the first archetype has archetypeGroupId=com.haoxuer.maven.archetype, second one has archetypeGroupId=fr.ebruno.maven.archetypes, and third archetypeGroupId=org.apache.maven.archetypes. To allow archetype plugin to chose precisely which of this needs to be used, you should specify archetypeGroupId.
Info
If you don’t specify archetypeGroupId and there are multiple archetypes, the archetype plugin will use the first one from the list.
-DarchetypeArtifactId=maven-archetype-simple
archetypeArtifactId tells which project template to be used to create the project. In our case, we will be using maven-archetype-simple to create our project from.
-DarchetypeVersion=1.5
Even if you have provided archetypeGroupId and archetypeArtifactId, it is possible that there are multiple versions. If that is the case, you need to specify the version of the artifact id, which should be used to generate the project. In our case, we will be using Version 1.5 of maven-archetype-simple to generate our project.
Info
If you don’t specify archetypeVersion and there are multiple versions, the archetype plugin will use the oldest available version.
-DgroupId=io.thedevjournal.maven.firstbuild, -DartifactId=first-build and -Dversion=1.0
groupId, artifactId and version together combine to indicate your project’s co-ordinate. Maven co-ordinates is the backbone of the Dependency Management. Just like a GPS Co-ordinate allow you to locate a specific place on a Globe, similarly, a project co-ordinate allows Maven to locate the project in the dependency tree of the root project.
packageio.devjournal.maven.firstbuild;import staticorg.junit.jupiter.api.Assertions.assertTrue;importorg.junit.jupiter.api.Test;/**
* Unit test for simple App.
*/publicclass AppTest{/**
* Rigorous Test :-)
*/@TestpublicvoidshouldAnswerWithTrue(){assertTrue(true);}}
pom.xml
The project object model file, pom.xml contains the project, its dependencies and details of how to build the project. A detailed explanation of different sections of the POM is covered in this article, but high-level sections are discussed in individual tabs.
<!-- Project's Co-ordinates as provided in the mvn archetype:generate command --><groupId>io.devjournal.maven</groupId><artifactId>first-maven-build</artifactId><version>1.0</version>
<!-- Name of the Project and URL(you should adjust this as indicated) --><name>first-maven-build</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url>
<properties><!-- Encoding of Files in the Project --><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><!-- Java Compiler Version --><maven.compiler.release>17</maven.compiler.release></properties>
<!-- How to Build the Project --><build><!-- Which Build Plugins to Use --><pluginManagement><plugins><!-- Build Plugin 1 - maven-clean-plugin--><plugin><artifactId>maven-clean-plugin</artifactId><version>3.4.0</version></plugin><!-- Build Plugin 2 - maven-resources-plugin--><plugin><artifactId>maven-resources-plugin</artifactId><version>3.3.1</version></plugin><!-- More plugins here --></plugins></pluginManagement></build>
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="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/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>io.devjournal.maven</groupId><artifactId>first-maven-build</artifactId><version>1.0</version><name>first-maven-build</name><!-- FIXME change it to the project's website --><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.release>17</maven.compiler.release></properties><dependencyManagement><dependencies><dependency><groupId>org.junit</groupId><artifactId>junit-bom</artifactId><version>5.11.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><scope>test</scope></dependency><!-- Optionally: parameterized tests support --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-params</artifactId><scope>test</scope></dependency></dependencies><build><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --><plugin><artifactId>maven-clean-plugin</artifactId><version>3.4.0</version></plugin><!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.3.1</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.13.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>3.3.0</version></plugin><plugin><artifactId>maven-jar-plugin</artifactId><version>3.4.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>3.1.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>3.1.2</version></plugin><!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --><plugin><artifactId>maven-site-plugin</artifactId><version>3.12.1</version></plugin><plugin><artifactId>maven-project-info-reports-plugin</artifactId><version>3.6.1</version></plugin></plugins></pluginManagement></build></project>
Building the Project
It has been too much theory. Let us build this project.
Maven build contains of different lifecycle phases, and depending on your requirements, you specify the goals to execute. A typical Maven build consists of two goals - clean package.
clean tells Maven to delete the files created from previous builds, while package tells Maven to compile, test, and package the project.
Here is the output when you run mvn clean package.
-> mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------< io.devjournal.maven:first-maven-build >----------------
[INFO] Building first-maven-build 1.0
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- clean:3.4.0:clean (default-clean) @ first-maven-build ---
[INFO] Deleting /home/thedevjournal/git/mastering-maven/first-maven-build/target
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ first-maven-build ---
[INFO] skip non existing resourceDirectory /home/thedevjournal/git/mastering-maven/first-maven-build/src/main/resources
[INFO]
[INFO] --- compiler:3.13.0:compile (default-compile) @ first-maven-build ---
[INFO] Recompiling the module because of changed source code.
[INFO] Compiling 1 source file with javac [debug release 17] to target/classes
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ first-maven-build ---
[INFO] skip non existing resourceDirectory /home/thedevjournal/git/mastering-maven/first-maven-build/src/test/resources
[INFO]
[INFO] --- compiler:3.13.0:testCompile (default-testCompile) @ first-maven-build ---
[INFO] Recompiling the module because of changed dependency.
[INFO] Compiling 1 source file with javac [debug release 17] to target/test-classes
[INFO]
[INFO] --- surefire:3.3.0:test (default-test) @ first-maven-build ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running io.devjournal.maven.firstbuild.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.033 s -- in io.devjournal.maven.firstbuild.AppTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO]
[INFO]
[INFO] --- jar:3.4.2:jar (default-jar) @ first-maven-build ---
[INFO] Building jar: /home/thedevjournal/git/mastering-maven/first-maven-build/target/first-maven-build-1.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.511 s
[INFO] Finished at: 2025-02-02T20:10:27+05:30
[INFO] ------------------------------------------------------------------------
Info
If you are running mvn clean package for the very first time, you will see Maven download a lot of plugin jar files, just like the archetype plugin execution earlier. Every time, there is a new plugin that Maven executes, or an existing plugin for which there is a new updated, Maven will download the new jar files for the first time.
And with that, your first Maven build is complete.
Maven uses convention based approach, and hence, it defines a standard directory structure for the project to organize the files.
Familiarity with this structure is important for understanding how the project files are used by Maven to build and assemble the project.
Here is the video explaining these.
But why?
But, why limit ourselves to one project structure?
Because, this discipline allows you to be more productive. It might take a bit of time for you to get used to this structure, but the effort is worth it.
Prior to Maven, projects had very varied directory structure and if you worked on multiple projects, keeping track of files across these projects, would have been really difficult.
Maven made all of this simpler, by having a consistent project structure across projects. So, even if you moved to a different organization or worked on an open source project, you will feel completely at home and navigating the project files would be a walk in the park.
With this consistent project structure, Maven plugins can easily assume the location of certain files that they need for execution. That means you can just include the plugin and they will just work, out of the box. You donβt need to configure anything specific for most cases. It really, really reduces the time to get your builds running.
Letβs now look at a standard directory structure for a Maven Project.
Maven Configuration File - pom.xml
The first and foremost, maven configuration file - pom.xml. This should be located in your projectβs root directory or project’s home directory.
In this directory, you also will have src folder that will contain all the files that, Maven plugins will use.
Below, is the example of the project’s home directory.
-> tree . -L 1.
βββ pom.xml
βββ src
Letβs see how src folder is laid out, to store the files.
Source Code Files in src
For all of your Application code files, they need to be placed inside the main directory of src. Within the main directory, you need to put the files inside the language specific folder.
So, your java files will be stored in src/main/java and your scala or kotlin files will be stored at src/main/scala or src/main/kotlin respectively.
Within each of these directories, you have your regular package structure, that is unique to your application.
For storing the application configuration files, like property configs, yaml configs, xml configs, or any other file that your application needs to use from classpath when its run, you need to store those in resources folder inside main directory.
If you working on a web application, you need to store your html, css, javascript, jsp, etc. They are stored in src/main/webapp. The directory structure inside webapp should confirm to Java Servlet Specification so that these can be packaged correctly and gets deployed correctly on Application servers.
When we talk about files for testing, Maven expects these to be stored in a separate directory - test inside src folder.
And for Test class files for your source classes, the structure is similar to files under src/main. So, if you have application Java class files under src/main/java, then you need to place your test classes for these at src/test/java.
Similarly, for other language class files for scala, kotlin and groovy.
And if you require any test specific configuration files, then you need to store those in resources folder in your src/test folder. Again, similar to what the structure is for src/main.
If you have some integration tests that maven needs to run, Maven expects you to store these in a separate directory inside src. It is src/it, short form for integration test.
The directory structure of integration test folder is exactly similar to that of src/main or src/test. You get language specific folders to store your integration test class files and an additional resources folder to store any configuration files that you might need during the integration tests.
-> tree .
.
βββ pom.xml
βββ src
ββββββ main
ββββββ test
| +-----------------------+
βββ|β it |
| βββ java |
| βββ kotlin |
| βββ scala |
| | |
| βββ resources |
+-----------------------+
Generating a Site
As you know, Maven can generate a project site for your application. To facilitate this, maven expects you to store these files in a separate folder called site inside the src folder.
The site directory contains a site.xml that defines how Maven should build the site. To store the site pages, maven provides different folders for each supported markup language.
-> tree .
.
βββ pom.xml
βββ src
ββββββ main
ββββββ test
ββββββ it
| +----------------------+
βββ|β site |
| βββ apt |
| βββ fml |
| βββ markdown |
| βββ xdoc |
| | |
| βββ site.xml |
+----------------------+
Assembly Files
And finally, assembly directory that tells Maven how to assemble your project. Without specifying any assembly configuration, maven assembles the project based on the default packaging from pom.xml.
But if you want to assemble your project differently, you can define the configuration in the assembly directory, and provide the configuration file to the maven-assembly plugin.
-> tree .
.
βββ pom.xml
βββ src
ββββββ main
ββββββ test
ββββββ it
ββββββ site
| +-------------------------+
βββ|β assembly |
| βββ distribution.xml |
+-------------------------+
And that is pretty much it. Again, adhering to Maven’s standard project structure streamlines project management and enhances productivity. By following these conventions, you can ensure consistency and ease of collaboration across different projects and teams.