Maven Complete Tutorial for Beginners
If you are a Java Developer, your day to day activities while working on Java Projects includes writing code, compiling code, testing, packaging code in the form of an artifact like JAR, WAR or EAR and then deploying this artifact to an Application Server.
Apache Maven automates all the tasks which are mentioned above by minimizing the manual overhead.
In this tutorial, we will understand What is Apache Maven? and will cover all the concepts required for you to start using Maven in your Java Projects
If you are a visual learner like me, check out the below video tutorial:
Table of Contents
What is Apache Maven ?
Apache Maven is a Project Management Tool used to manage projects which are developed using JVM languages like Java, Scala, Groovy etc.
The major tasks of a Project Management Tool include:
- Building the Source Code
- Testing Source Code
- Packaging the Source Code into an Artifact (ZIP, JAR, WAR or EAR)
- Handles Versioning and Releases of the Artifacts
- Generating JavaDocs from the Source Code
- Managing Project Dependencies
Maven is also called as a Build Tool or a Dependency Management Tool
Installing Maven
You can download Maven from the website here. At the time of writing this tutorial, the latest version of Maven is 3.6.3.
Under the Files section, you can download Maven by clicking on the link which looks something like apache-maven-3.6.3-bin.zip
Once you have downloaded and unzipped the folder, make sure to add the M2_HOME environment variable and to set the value of this variable to location of the unzipped folder.
After that make sure to set another environment variable called M2 which contains the value M2_HOME/bin
After that, make sure to update the Path variable also with the M2 environment variable.
Once you completed the above steps, open a new terminal window and type mvn –version and you should see the output like below:
Configure Maven Installation in IDE
The next step is to configure the maven installation inside your favorite IDE, in this tutorial we are going to use IntelliJ IDEA as the primary IDE.
You can download the community edition of this IDE here
Once you have installed the IDE, on the Welcome Window click on the Configure button and select Settings and inside the Settings Window search for Maven and under the Maven home directory choose the Maven directory.
Click on Apply and then OK
You configured Maven successfully in your IDE. Now it’s time to create our first Maven Project.
Create your First Maven Project
In IntelliJ, click on New Project and in the window, select Maven to the left side and click on Next.
Then enter your project name and if you expand the section Artifact Coordinates.
You will see the fields GroupId, ArtifactId and Version.
- A GroupId is like a identifier for your project which usually follows the Java Package naming convention, so in our example IntelliJ has by default added the value org.example but you can add any value you like.
- An ArtifactId is the name of the project you are creating
- A Version is a unique number which identifies the version of our project.
Once you click on Finish, IntelliJ should open the project and the folder structure of the project will look something like the picture you see below.
Exploring Maven Folder Structure
Let’s have a look at the Folder Structure of the Maven Project we just created.
The src folder is the root for our application source code and tests. Then we have the following subfolders:
- The folder src/main/java contains the java source code, all the production code for our application resides here
- In the src/main/resources we will store all the files we are going to use in our project (example: Property Files, any files where we need to read in our application like XML, CSV etc.). If you are developing a web-application we will usually place all the static resources inside this folder.
- In the src/test/java folder we will store all the test classes in our project.
- There is another folder called target (currently not visible), which stores the compiled java class files. We will discuss about this in the coming sections
- And lastly, we have the pom.xml file which contains the metadata of the project dependencies.
Maven Core Concepts
Project Object Model
The Project Object Model File(also called as pom.xml) contains the meta-data of the project and is also responsible to manage dependencies and to configure plugins which helps us in automating many repetitive tasks.
Here is how a basic pom.xml file looks like:
Exit fullscreen mode
- project is the top level tag of our pom.xml file, which encapsulates all the information related to our Maven Project.
- modelVersion represents what version of POM you are using. The modelVersion for Maven 3 is always 4.0. This will never change unless you are using another major version of Maven.
Now as we know what is a POM file, let’s have a look at different type’s of POM files. We have basically 3 types of POM files:
- Simple POM file
- Super POM file
- Effective POM file
Simple POM File
This is the same file(pom.xml) which was generated in the previous section. It only contains information which is relevant to our current project.
Super POM File
A Super POM File is a parent for all the Simple POM files, it contains a set of default configuration which is shared by all the Simple POM files.
You can find the Super POM file inside the Maven installation directory under the path M2_HOME/lib and inside the JAR file maven-model-builder-XXX.jar where XXX represents the version of the maven version you are using.
We can find it under the package name org.apache.maven.model under the file name pom-4.0.0.xml.
CAUTION: You should never try to edit the Super POM as it contains sensible defaults from Maven.
Effective POM File
An Effective POM File is nothing but a combination of Simple POM and Super POM File’s.
It’s just a way of checking all the information of the pom.xml files in one place.
We will have a look at how this will be helpful in the upcoming sections.
You can have a look at the Effective POM of our pom.xml file by typing the following command
In IntelliJ, you can simply right click on the pom.xml file, select Maven -> Show Effective POM
Dependencies
If you are working on any non-trivial Java Project chances are that you are using many third party JAR files in your project to develop the application. These JAR files can be anything like a Framework or a Library. Examples include Junit, Spring Framework, Selenium etc.
These external libraries are called as dependencies. Maven provides an excellent way to specify and manage dependencies in our pom.xml file.
Without using Maven, you have to manually download the required JAR files from internet and add them one-by-one to the classpath of our project.
Maven provides a dependencies section inside the pom.xml where you can specify the information of the JAR you require in your project (groupId, artifactId and version). Once you have specified the required libraries, maven will automatically download these dependencies into our project and adds them to the classpath of our project.
Inside the dependencies section you can define each individual dependency like below inside the pom.xml file.
Exit fullscreen mode
We have defined Junit5 as a dependency in our pom.xml file.
Notice that I have mentioned the tags groupId, artifactId and version to uniquely identify a dependency and by providing these values, Maven can automatically download these dependencies to our project.
In IntelliJ, make sure to click on the Refresh button under the Maven Tab in the right side, to force IntelliJ to initiate the download of the dependencies. Check the below image:
In this way, you can provide all the dependencies needed in your project inside the pom.xml and Maven will automatically download them.
Transitive Dependencies
In the above example, you can observe that the junit-jupiter-engine indeed depends on other JAR files like apiguardian-api, junit-platform-engine and junit-jupiter-api
These JAR files are called Transitive Dependencies
Excluding Dependencies
There are some instances where we will have some conflicts between the project dependencies and the transitive dependencies, at that time we can manually exclude the transitive dependency we don’t need.
For example, if you are developing your application using Spring Boot, there is a dependency called spring-boot-starter-test which will provide all the dependencies needed to test the Spring Boot applications.
This spring-boot-starter-test dependency contains Junit 4 as the transitive dependency, as we are already using Junit 5 we can exclude the transitive dependency like below:
Exit fullscreen mode
NOTE: The newer Spring Boot versions comes with JUnit 5 dependency, I purposely used the old version 2.1.6.RELEASE as an example.
SNAPSHOT and RELEASE dependencies
A dependency can be categorized into two ways:
- SNAPSHOT
- RELEASE A Snapshot Dependency resembles that the project version is under development.
If you are working on a Java project in a team, chances are that you are following some kind of iterative process where you go through the phases of development and then release the software at the end of the phase.
When the project is under development we generally use the SNAPSHOT dependencies, which looks something like 1.0-SNAPSHOT
Exit fullscreen mode
When the software is ready for release, we generally create a RELEASE version which looks like 1.0.RELEASE (ex: Spring Boot Starter Test dependency)
Exit fullscreen mode
Dependency Scopes
Each Maven Dependency can be categorized 6 different scopes.
Here are the list of scopes available:
- compile: This is the default scope if none is specified. Compile time dependencies are available in classpath of the project.
- provided: Similar to compile scope, but indicates that the JDK or the underlying container will provide the dependency at run-time. The dependency will be available at compile time, but not packaged into the artifact. An example of the usage is the javax.servlet-api dependency
- runtime: The dependencies defined with this scope will be only available at runtime but not at compile time. An example of the usage: Imagine if you are using MySQL Driver inside your project, you can add the dependency with scope as runtime, to ensure that the JDBC API abstraction is used instead of MySQL Driver API during implementation. If the source code includes any classes which is part of the MySQL JDBC API, then the code wont compile as the dependency is unavailable at compile time.
- test: Dependencies are only available at the time of running the tests, typical examples include Junit and TestNG
- system: It’s similar to the provided scope, but only difference is we need to explicitly mention where can the dependency be found in the system, using the systemPath tag:
Repositories
In the previous section, we saw how Maven manages and automatically downloads the dependencies.
These dependencies, are stored inside a special directory called Repository. There are basically 2 kinds of repositories:
- Local Repository A Local Repository is a directory on the machine where the Maven is running.
The default location for the Local Repository is /.m2
In Windows, it looks like:
C:\Users<user-name>.m2\repository
- Remote Repository A Remote Repository is a web-site where we can download Maven Dependencies. This can be a repository provided by Maven (repo.maven.org) or a custom repository setup inside an organization using software like Artifactory or Nexus. Now that we saw different types of repositories, let’s see how Maven Resolves the dependencies.
Now let’s see how Maven Resolves the dependencies.
- When you define a dependency defined inside the pom.xml file, Maven first checks whether the dependency is already present in the Local Repository or not.
- If it is not, then it tries to connect to the Remote Repository, (Ex: https://repo.maven.org) and tries to download the dependencies, and store them inside the Local Repository. We can define the Remote Repository in our pom.xml like below:
Exit fullscreen mode
Snapshot and Release Version Handling
In the previous section, we learned that Maven first checks the Local Repository before downloading a dependency from Remote Repository.
When dealing with SNAPSHOT dependencies Maven periodically downloads the dependency from Remote Repository even though the dependency exists in Local Repository.
This is because SNAPSHOT dependencies are under heavy development, and are subjected to change frequently.
You can change this behavior by adding a section inside the repositories tag.
Exit fullscreen mode
The value XXX inside the updatePolicy can be:
- always: Maven always checks for a latest version
- daily: This is the default value, as the name suggests it downloads the version once every day on the first run.
- interval:XXX: Checks every XXX minutes
- never: Never checks for the updates.
RELEASE versions on the other hand are more stable, and follow the usual dependency resolution.
Maven Build Lifecycle
Till now we learned about the Core Concepts of Maven, now it’s time to dive deep and understand how Maven builds our Java Project.
Maven follows a Build Lifecycle to well… build our project.
This Lifecycle is divided into 3 parts:
- default
- clean
- site
Each Lifecycle is independent of each other and they can be executed together.
The default life cycle is divided into different phases like below:
- validate – verifies whether the pom.xml file is valid or not
- compile – compiles the source code inside the project
- test – runs unit-tests inside the project
- package – packages the source code into an artifact (ZIP, JAR, WAR or EAR)
- integration-test– executes tests marked as Integration Tests
- verify – checks whether the created package is valid or not.
- install – installs the created package into our Local Repository
- deploy – deploys the created package to the Remote Repository
The clean lifecycle is mainly responsible to clean the .class and meta-data generated by the above build phases.
The site lifecycle phase is responsible to generate Java Documentation.
All 3 lifecycles also contains some additional phases, which I am not going to cover in this tutorial, if you are interested you can refer to the Maven Documentation
Plugins and Goals
To be able to execute these Lifecycle Phases, Maven provides us with Plugins to perform each task.
Each plugin is associated with a particular Goal
Let’s have a look at different Plugins and the associated Goals:
Maven Compile Plugin
The Maven Compile Plugin is responsible to compile our Java files into the .class files. It’s equivalent of running javac
This plugin enables the compile phase of the default lifecycle.
You can add this plugin to your project by adding the below section to your pom.xml file under the dependencies
section.
Exit fullscreen mode
At the time of writing this tutorial, Maven Compiler Plugin is at version 3.8.1
After adding the plugin to the project, you can activate the compile phase, by typing the below command:
Exit fullscreen mode
In the above command the compiler is the name of the plugin and compile is the goal which triggers the lifecycle phase – compile
You can already see the message – “Nothing to compile – all classes are up to date”
As there are no Java Files in our project, there is nothing to compile, so let’s create a simple HelloWorld.java file
Exit fullscreen mode
If you try to compile again, you can see the following output:
Exit fullscreen mode
We can see the generated class files under the target folder which resides just under the project root folder.
If you have some Test files, those are also compiled using the Compiler Plugin.
To demonstrate that let’s create the below Test class under the src/test/java folder
Exit fullscreen mode
And here is how you can compile the test classes:
Exit fullscreen mode
As you can see that a change has been detected by the Maven Compiler Plugin and it has compiled our Test classes to the target/test-classes folder
As we are using IntelliJ, we can also use it to run the compilation, by clicking on the compile button under the LifeCycle dropdown as you see in the below image:
If you run the compile option you may see the below error:
Exit fullscreen mode
This is because, by default the Source and Target Compiler Version is set to 1.5 in IntelliJ Configuration. You can add the below configuration to the compiler plugin to override this settings:
Exit fullscreen mode
You can pass many customized option to the Maven Compiler Plugin based on your needs, you can find the examples of the configuration in the Apache Maven Compiler Plugin website
Maven Surefire Plugin
Using Surefire Plugin, we can run the tests inside our project by using the following command:
Exit fullscreen mode
You can see that the HelloWorldTest.java file was executed successfully, and the you can also see how many Tests are executed successfully.
The Surefire Plugin generates Text and XML reports under the target/surefire-reports folder.
Similar to Compiler Plugin, you can also configure Surefire Plugin based on your needs.
Surefire Plugin by default includes all tests, if you have a bunch of tests, you can manually exclude some tests to be executed using below configuration:
Exit fullscreen mode
And if you run the mvn test command now, you can see that no tests are executed.
Exit fullscreen mode
Maven Install Plugin
This is used to package our source code into an artifact of our choice like a JAR and install it to our Local Repository which is /.m2/repository folder.
You can configure Maven Install Plugin by adding the below code:
Exit fullscreen mode
You can run the install phase of the lifecycle by typing the below command:
Exit fullscreen mode
By checking the above output, you can see that the install phase includes also the previous phases in the lifecycle, so as part of this phase maven:
- validates our pom.xml (validate)
- compiles our source code (compile)
- executes our tests (test)
- packages our source code into JAR (package)
- installs the JAR into our local repository (install)
You can see the JAR file in the below screenshot under the target folder.
Maven Deploy Plugin
The Maven Deploy Plugin will deploy the artifact into a remote repository. The deploy goal of the plugin is associated with the deploy phase of the build lifecycle.
The plugin can be configured like below:
Exit fullscreen mode
Before running the deploy phase of the lifecycle, we have to make sure that the remote repository details are configured inside our project.
We can configure this details inside the distributionManagement section:
Exit fullscreen mode
To be able to connect to the remote repository, maven needs access to the credentials, which can be configured inside a special file called as settings.xml file.
This file is usually configured inside the /.m2/ folder, which looks like something below:
Exit fullscreen mode
Maven also provides us a way to encrypt the credentials inside the settings.xml file, you can read about this here
You can run the deploy goal using the following command:
$ mvn deploy
Once you run this command, you will notice that it will run all the lifecycle phases up until deploy.
Although if you run this command in the example project, it will fail because the Remote Repository Details are invalid.
Maven Clean Plugin
Another important plugin in Maven is the Maven Clean Plugin, you saw that when running the above lifecycle phases, the generated files are stored under a folder called target.
Usually when building our source code we need to start of as a clean slate so that there are no inconsistencies in the generated class files or JAR.
For this reason we have the clean phase where we will delete all the contents inside the target folder. You can execute this phase by typing the below commands:
Exit fullscreen mode
You can see that the target folder under our project is deleted successfully.
Other Maven Plugins
There are many other plugins in Maven world, to execute other phases in the Maven Build Lifecycle, you can check them out here
Maven Multi Module Projects
Till now we saw the Core Concepts of Maven, now it’s time to dive deep into some advanced concepts.
In the real world where we are building some non-trivial projects, the source code is going to be modularized (hopefully) and is divided into different sub projects.
To manage this effectively, Maven provides us Multi Module Projects where you can have nest different projects inside each other. We are basically creating a parent-child relationship between different Maven projects.
Basically, we have a Parent Project (Parent POM) which contains different sub-projects (sub-modules), each of which is again a normal Maven Project.
The Parent POM usually encapsulates other child’s and that’s why its packaged as a POM instead of usual packaing format’s like JAR.
If you recall the section Project Object Model , we discussed about Super POM which is basically a kind of Parent POM which encapsulates default settings configured by Maven for us.
Creating Multi Module Project using IntelliJ
We will see how to generate Multi Module Projects using our IntelliJ IDE.
To create the project, first right click on the project root folder and select New -> Module and click on Next.
Give a name to the child project and click on Finish.
You can see the new project structure in the above picture after we created the child project.
Now if you open the pom.xml under the root folder, you can observe the following tags which are added by creating the maven module.
Exit fullscreen mode
We can create multiple projects in the same way and you can see all the modules will be listed one-by-one under the modules tag.
Exit fullscreen mode
As we create these 3 modules, having the src folder under the root project folder doesn’t make much sense, so let’s copy and paste this folder onto other child-projects, so that we have some code configured inside these modules.
This is how our project structure now looks like:
And if you check the pom.xml of child-project-1,child-project-2 and child-project-3. You can see that the root project is configured as a parent project.
Exit fullscreen mode
Now you can build all the projects at once by running the mvn install under the Parent Project, and Maven scans through all the POMS and builds all of them one-by-one
Exit fullscreen mode
You can see that Maven built all the projects and provided us a nice report of the Build Status of each project.
Maven uses something called as a Reactor which is responsible to scan the whole project and identify the parent and child maven projects. If there are any dependencies, then Reactor makes sure to execute the projects in the required order.
For example, if child-project-2 is dependent on child-project-3 , then Maven Reactor makes sure to first build child-project-3 and then child-project-2.
Managing Dependencies inside Maven Multi Module Project
When you are working with Multiple Maven Modules, you may be working with different dependencies in different modules, and chances are that you may be using similar dependencies in multiple modules.
Maven provides us a way to effectively manage the dependencies in your project by allowing us to define the dependencies in centralized location (parent project) and use those dependencies across the different child projects.
This minimizes the dependency version mismatch across multiple projects, as we have a single place we can manage all the dependencies and its versions.
Let’s see how to do that in our example project.
I am going to move all the dependencies which are defined inside the parent project into the dependencyManagement section, like below:
Exit fullscreen mode
The change in the pom.xml is minor, we just moved the dependencies under the dependencyManagement tag.
Now if you analyze the dependencies under the child-project-1 you can see that it’s empty.
Exit fullscreen mode
This is because we moved all the dependencies inside the Parent POM into dependencyManagement section, now to access any dependencies the Child Projects should define them manually inside their pom.xml.
In this way, the child projects can have only the dependencies they need inside the pom.xml.
Now, let’s go ahead and add the junit-jupiter dependencies inside the child-project-1 and see what happens.
Exit fullscreen mode
Exit fullscreen mode
You can now see that the junit-jupiter dependency is available inside the child-project-1.
Managing Plugins inside Maven Multi Module Project
We can also manage Plugins inside our Maven Multi Module project, similar to the dependencies.
To Manage Plugins, we have the pluginManagement section inside the pom.xml and each child project can chose the plugin it needs.
This is how our parent pom.xml looks like after introducing the pluginManagement.
Exit fullscreen mode
Using Profiles
Profiles can be used in Maven to created customized build configurations. This means customizing the behavior of our builds based on specific conditions.
For example: Sometimes we need to test whether the source code packaging is working correctly or not, in that case we can skip the test execution by activating the skip.tests property like below:
Exit fullscreen mode
Now we can try to run the build by specifying which profile to activate using the -P flag.
Exit fullscreen mode
If you observe the logs carefully, you can see that the test-execution is skipped:
Exit fullscreen mode
This is just a simple usage of the profiles, you can configure multiple profiles in our project to customize the build behavior.
Conclusion
So we came to the end of this tutorial, I hope this tutorial improved your understanding of Maven.
Apache Maven Tutorial
Apache Maven is an powerful build tool primary for Java software projects. It is implemented in Java which makes it platform-independent.
Build tools performs the compilation, testing, packaging and deployment of the final product. The advantages of performing these steps automatically instead of a human performing these steps is that the build is reproducible, faster and less error prone.
Maven can also perform related activities, e.g., create web sites, upload build results or generate reports.
Maven also supports the creation of the initial folder structure for applications to make it easy to get started.
The key features of Maven are:
Convention over configuration: avoid as much configuration as possible, by choosing real world default values and supplying project templates (archtypes).
Dependency management: support the definition and usage of dependencies to other libraries and projects. During the build, the Maven build system resolves the dependencies and it also builds the dependent projects if needed.
Extensible via plug-ins: The Maven build system is extensible via plug-ins, which allows to keep the Maven core small. The Maven core does for example not know how to compile Java source code, this is handled by the compiler plug-in.
The dependencies can be sourced from the local file system, from the Internet or public repositories. Maven Central is an open repository for Java libraries, which is used by default to search for required libraries. The local repository is found in the .m2/repository folder of the user’s home directory, Maven uses this directory to cache downloaded artifacts.
2. How to use this Maven tutorial
This tutorial covers the core concepts of the Maven build tool.
If you do not care about understanding the underlying technology, just ensure you installed the command line tooling and jump to Maven examples.
You may want to primary use an IDE for Maven. Modern IDEs contain great support for Maven, e.g. the Eclipse IDE support. This tutorial covers the command line usage and a deeper understanding of Maven itself, if you more interested in using the Maven tooling from the IDE, please see the Maven with Eclipse tutorial.
3. Installing Maven
To run a Maven build from the command line / terminal, you need to install the Maven command line tooling. To test if you have Maven already installed, type the following command into your command line:
If you see output which includes Apache Maven you already have Maven installed and can skip this section.
3.1. Requirements
You need to have a Java SDK installed and and set the JAVA_HOME environment variable to point to a valid Java SDK.
For a manual installation you can download Maven from the Maven Download page. Extract the downloaded distribution to a selected folder on your computer and add the M2_HOME environment pointing to this directory. Add M2_HOME/bin to your path variable.
See Official Maven installation for a detailed installation guide.
For Linux most distributions include Maven into their main repositories. On Ubuntu you can use the following command on the command line to install it.
3.2. Validate installation
To validate that Maven was correctly installed, open a console and use the following command:
You should receive as output feedback which version of Maven you have installed.
3.3. Optional: Code completion for bash shells
The bash shell is the default shell on Linux.
See https://github.com/juven/maven-bash-completion for a bash shell extension for the command line to have code completion for Maven commands. This should also work with the git bash von Windows.
3.4. Proxy settings
To configure you proxy, add a file named .m2/settings.xml to your user home with the proxy settings, similar to the following:
User and password is only required if you proxy request base authentication.
4. Core concepts of Maven
By default, the configuration of a Maven project is done via at least one pom.xml configuration file. This name pom file is derived from the term Project Object Model.
Maven uses a declarative style of describing the build, i.e., you describe what should be build not how it is build. This allows Maven to use default for performing the build steps.
The pom file defines:
identifiers for the project to be build
properties relevant for build configuration
plugins which provide functionality for the build via a build section.
library and project dependencies via the dependencies section
Each project has its own pom file. You can configure Maven to build one project or multiple projects. A multi project typically defines a pom file in the root of the directory and lists the individual projects in a modules section.
The result of a build is called artifact and can be, for example, an executable JAR file or zip file.
A minimal pom file for a single project is listed in following snippet. This project does not define any properties, dependencies nor any additional plugins.
1 | 4.0.0 is the latest version of the pom file structure, usable for Maven 2.x or 3.x |
2 | Unique identifier of the organization or the project |
3 | Name of the project which is built |
4 | Defines the currently version of the project |
5 | Set Java compiler level for the Java project |
The groupId, artifactId and version attributes are further explained in the next section. For a full reference of possible entries in the pom file, see Maven pom reference.
4.1. Project identifiers via the group, artifact and version (GAV)
A Maven project uses the groupId, artifactId, version (also knows as GAV) and the packaging property to uniquely identify a Maven component. These attributes are explained in the following table.
Defines a unique base name of the organization or group that created the project. This is normally a reverse domain name or the name of an open source project. For the generation of new projects, the groupId also defines the package of the main class.
Defines the unique name of the project within the groupId. If you generate a new project via Maven this is also used as root folder for the project.
This defines the version of the project. If a new version of the project is build, this version should change so that consumers can see that a different version is used.
Defines the packaging method. This could be e.g. a jar, war or ear file. If the packaging type is pom, Maven does not create anything for this project, it is just meta-data.
For example, you can use the GAV to specific which exact version of a library you want ot use.
The full Maven coordinates are often written in the following format: groupId:artifactId:packaging:version.
4.2. Parent pom and effective pom
Each pom file inherits from a parent (super) pom. If no explicit parent pom is defined it inherits from the base pom of Maven.
Maven always executes against an effective pom. This is a combination of settings from this project’s pom.xml, all parent pom, a super-pom defined within Maven, user-defined settings, and active profiles.
To see the effective pom, use the following command:
4.3. Dependencies
4.3.1. Maven repositories and dependency resolution
A repository is a collection of libraries and project artifacts stored in a directory structure similar to the Maven coordinates of the project.
During the initial phase of a build Maven validates, if you have the specified version of all required artifact dependencies and Maven plug-ins. If required, it retrieves them from a Maven repository.
If necessary, Maven downloads these artifacts and plug-ins into a local repository. The default local repository is located in the home directory of the user in the .m2/repository folder. If an artifact or a plug-in is available in the local repository, Maven uses it for the build to avoid unnecessary network traffic.
Maven uses a default remote repository location (http://repo1.maven.org/maven2) from which it downloads the core Maven plugins and dependencies. You can configure Maven to use more repositories and replace the default one.
Every project can define dependencies using the unique identifier (GAV) of the library it requires.
During a build, the Maven system tries to resolve the dependencies of the modules which are build. To resolve dependencies, Maven uses the following sources in the given order:
Projects which are included in the same Maven run (the so called Maven reactor)
Maven central repository
Maven supports direct and transitive dependencies. Direct dependencies are the ones that are explicitly included in the pom file of the project. Transitive dependencies are dependencies required by our direct dependencies.
Maven handles direct and transitive dependencies.
For this, you specify in the pom file the external libraries your project depends on using their GAV (groupId, artifactId and version) then Maven downloads them, puts them in your local Maven repository and make them available for the project build. The transitive dependencies of the required libraries are also made available.
The following listing shows a pom file with a dependency to JUnit5.
1 | This build section is required as starting with version 2.22.0, Maven Surefire and Maven Failsafe provide native support for executing tests on the JUnit Platform. |
2 | This defines dependencies for the software tests (via the scope attribute) to JUnit5 (also known as JUnit Jupiter) |
Maven will download the defined dependencies and their transitive dependencies from the Maven central repository and add them to the users local Maven repository. If the dependencies are already found in your local repository, Maven will use these and download them again.
You can also define an (external of a Maven repository) location for a library.
1 | Requires that the library is defined via a system path |
You can also define snapshot dependencies. These are libraries which can constantly under development. Maven downloads these snapshots on every build, even if a matching version is already available in the local repository.
4.3.2. Excluding transitive dependencies
Sometimes your dependencies have conflicting transitive dependencies. For example library A requires library C in version 1.0.0 and library B requires it in version 1.1.0. To use library C in version 1.0.0 you can exclude C from the dependencies of A.
Name already in use
Work fast with our official CLI. Learn more about the CLI.
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.adoc
This guide walks you through using Maven to build a simple Java project.
What you’ll build
You’ll create an application that provides the time of day and then build it with Maven.
What you’ll need
Set up the project
First you’ll need to setup a Java project for Maven to build. To keep the focus on Maven, make the project as simple as possible for now. Create this structure in a project folder of your choosing.
Within the src/main/java/hello directory, you can create any Java classes you want. To maintain consistency with the rest of this guide, create these two classes: HelloWorld.java and Greeter.java .
Now that you have a project that is ready to be built with Maven, the next step is to install Maven.
Maven is downloadable as a zip file at https://maven.apache.org/download.cgi. Only the binaries are required, so look for the link to apache-maven- -bin.zip or apache-maven- -bin.tar.gz.
Once you have downloaded the zip file, unzip it to your computer. Then add the bin folder to your path.
To test the Maven installation, run mvn from the command-line:
If all goes well, you should be presented with some information about the Maven installation. It will look similar to (although perhaps slightly different from) the following:
Congratulations! You now have Maven installed.
INFO: You might like to consider using the Maven wrapper to insulate your developers against having the correct version of Maven, or having to install it at all. Projects downloaded from Spring Initializr have the wrapper included. It shows up as a script mvnw in the top level of your project which you run in place of mvn .
Define a simple Maven build
Now that Maven is installed, you need to create a Maven project definition. Maven projects are defined with an XML file named pom.xml. Among other things, this file gives the project’s name, version, and dependencies that it has on external libraries.
Create a file named pom.xml at the root of the project (i.e. put it next to the src folder) and give it the following contents:
With the exception of the optional <packaging> element, this is the simplest possible pom.xml file necessary to build a Java project. It includes the following details of the project configuration:
<modelVersion> . POM model version (always 4.0.0).
<groupId> . Group or organization that the project belongs to. Often expressed as an inverted domain name.
<artifactId> . Name to be given to the project’s library artifact (for example, the name of its JAR or WAR file).
<version> . Version of the project that is being built.
<packaging> — How the project should be packaged. Defaults to «jar» for JAR file packaging. Use «war» for WAR file packaging.
At this point you have a minimal, yet capable Maven project defined.
Build Java code
Maven is now ready to build the project. You can execute several build lifecycle goals with Maven now, including goals to compile the project’s code, create a library package (such as a JAR file), and install the library in the local Maven dependency repository.
To try out the build, issue the following at the command line:
This will run Maven, telling it to execute the compile goal. When it’s finished, you should find the compiled .class files in the target/classes directory.
Since it’s unlikely that you’ll want to distribute or work with .class files directly, you’ll probably want to run the package goal instead:
The package goal will compile your Java code, run any tests, and finish by packaging the code up in a JAR file within the target directory. The name of the JAR file will be based on the project’s <artifactId> and <version> . For example, given the minimal pom.xml file from before, the JAR file will be named gs-maven-0.1.0.jar.
To execute the JAR file run:
Maven also maintains a repository of dependencies on your local machine (usually in a .m2/repository directory in your home directory) for quick access to project dependencies. If you’d like to install your project’s JAR file to that local repository, then you should invoke the install goal:
The install goal will compile, test, and package your project’s code and then copy it into the local dependency repository, ready for another project to reference it as a dependency.
Speaking of dependencies, now it’s time to declare dependencies in the Maven build.
The simple Hello World sample is completely self-contained and does not depend on any additional libraries. Most applications, however, depend on external libraries to handle common and complex functionality.
For example, suppose that in addition to saying «Hello World!», you want the application to print the current date and time. While you could use the date and time facilities in the native Java libraries, you can make things more interesting by using the Joda Time libraries.
First, change HelloWorld.java to look like this:
Here HelloWorld uses Joda Time’s LocalTime class to get and print the current time.
If you were to run mvn compile to build the project now, the build would fail because you’ve not declared Joda Time as a compile dependency in the build. You can fix that by adding the following lines to pom.xml (within the <project> element):
This block of XML declares a list of dependencies for the project. Specifically, it declares a single dependency for the Joda Time library. Within the <dependency> element, the dependency coordinates are defined by three sub-elements:
<groupId> — The group or organization that the dependency belongs to.
<artifactId> — The library that is required.
<version> — The specific version of the library that is required.
By default, all dependencies are scoped as compile dependencies. That is, they should be available at compile-time (and if you were building a WAR file, including in the /WEB-INF/libs folder of the WAR). Additionally, you may specify a <scope> element to specify one of the following scopes:
provided — Dependencies that are required for compiling the project code, but that will be provided at runtime by a container running the code (e.g., the Java Servlet API).
test — Dependencies that are used for compiling and running tests, but not required for building or running the project’s runtime code.
Now if you run mvn compile or mvn package , Maven should resolve the Joda Time dependency from the Maven Central repository and the build will be successful.
Maven
IntelliJ IDEA supports a fully-functional integration with Maven that helps you automate your building process. You can easily create a new Maven project, open and sync an existing one, add a Maven support to any existing IntelliJ IDEA project, configure and manage a multi-module project.
You can also create a Maven project and store it in the WSL environment or open it from the WSL file system. For more information, refer to the WSL section.
If you want to use a custom Maven version that is not bundled with IntelliJ IDEA, you need to install it locally.
Create a new Maven project
If no project is currently open in IntelliJ IDEA, click New Project on the Welcome screen. Otherwise, select File | New | Project from the main menu.
Name the new project and change its location if necessary.
Select the Create Git repository to place the new project under version control.
You will be able to do it later at any time.
Select a language that you want to use in your project. Click if you want to add other languages available via plugins.
Select Maven in the list of Build system .
Specify project’s SDK (JDK) or use the default one.
The selected Add sample code option will create a file with a basic code sample.
In Advanced Settings , specify the following Maven coordinates that are added to the pom.xml file:
GroupId — a package of a new project.
ArtifactId — a name of your project.
For more information on Maven coordinates, see Maven naming conventions.
IntelliJ IDEA creates a Maven project with the pom.xml file that includes compiler and target versions of Java, dedicated Maven tool window, and all the necessary dependencies to start your work.
The version of Java specified in the pom.xml file overrides the version specified in the JDK for Importer option, located in the Maven settings.
Create a new project with Maven archetype
Launch the New Project wizard. If no project is currently opened in IntelliJ IDEA, click New Project on the welcome screen. Otherwise, select File | New | Project from the main menu.
Select Maven Archetype from the options on the left.
Using options on the right, configure your project:
Name : specify the name of your project.
Location : specify the location of your project.
Create Git repository :
Select the Create Git repository to place the new project under version control.
You will be able to do it later at any time.
JDK : specify project’s SDK (JDK) or use the default one.
Catalog : specify which Maven repository you want to use in your project.
The internal Maven catalog is a default one. You can also select the local repository that is located in the .m2 directory, or you can select Maven central repository.
You can also click Manage Catalogs and add a custom repository if you need.
Archetype : select the needed Maven archetype. Click Add to specify the custom archetype.
Version : the version is specified automatically.
Additional properties : add additional properties
If you are creating a project using a Maven archetype, IntelliJ IDEA displays the Maven settings that you can use to set the Maven home directory and Maven repositories. Also, you can check the archetype properties.
To modify or add archetype catalogs later in your project, refer to the Archetype Catalogs settings.
Create a Java EE project with Maven as a build tool
Launch the New Project wizard. If no project is currently opened in IntelliJ IDEA, click New Project on the welcome screen. Otherwise, select File | New | Project from the main menu.
Select Jakarta EE from the list of generators.
Leave the default option Maven as your build tool system.
Select additional libraries and frameworks.
Specify your project’s name, location, and artifact coordinates. Click Create .
IntelliJ IDEA creates a Maven project with the dedicated Maven tool window and adds necessary dependencies.
For the more detailed information, refer to Tutorial: Your first Java EE application.
Open an existing Maven project
From the main menu, select File | Open .
Alternatively, click Open on the welcome screen.
If you have some custom plugins that require you to import your project from the IntelliJ IDEA model, press Ctrl+Shift+A and search for the Project from Existing Sources action.
In the dialog that opens, select the pom.xml file of the project you want to open.
In the dialog that opens, click Open as Project .
IntelliJ IDEA opens and syncs the Maven project in the IDE. If you need to adjust importing options when you open the project, refer to the Maven settings. For example, if you have Maven options configured in the maven/config file and want to use them in your project, select the Use settings from .mvn/maven.config option in the Maven setting.
If you have a Maven project with the configured Maven wrapper then IntelliJ IDEA will take the Maven version from the maven.properties file and add it as the Maven home path.
Configure the Maven settings before opening a new project
You can configure IntelliJ IDEA to display Maven settings before you open a new Maven project. (A new Maven project in this case is the existing project that you open in IntelliJ IDEA for the first time.) Since these are application-level settings, they are applied to any new project you open.
On the Welcome screen, select Customize | All Settings .
Alternatively, from the main menu, select File |New Project Setup | Preferences for New Projects .
In the Settings dialog, select Build, Execution, Deployment | Build Tools | Maven .
In the Maven settings dialog, select the Show settings dialog for new Maven projects .
Click OK to save the changes.
Next time you open a new project, IntelliJ IDEA displays the Maven Settings dialog where you can specify a location of the local Maven repository and a user settings file.
Add a new Maven module to an existing project
You can add a Maven module to the project in which you are already working.
In the Project tool window, right-click the project folder and select New | Module . Alternatively, from the main menu, select File| New | Module to open the New Module wizard.
If you used main menu to add a module then the process of adding a module is the same as Creating a new Maven project.
If you are adding sub modules by right-clicking the root folder then the process of adding a new module is shorter. You need to specify the name of your module in the Name field. The rest of the information is added automatically and you can use either the default settings or change them according to your preferences.
Configure a multi-module Maven project
You can create a multi-module Maven project in IntelliJ IDEA. The multi-module project is defined by a parent POM file with several sub modules.
If you have the Maven version 3.7 or later installed, IntelliJ IDEA will support importing a project from the MNG-6656 model.
In this case when you open a child POM file in the editor, you don’t have to specify a version inside the parent tags if it is located in the relativePath by default. If you add a dependency to a module in the same project, you don’t have to specify a version of the dependent module.
Create a Maven parent project. IntelliJ IDEA creates a standard Maven layout including an src folder.
In the Project tool window, remove the src folder since you would only need it in the very rare cases. For your general project, you don’t need the src folder for the parent POM.
In the Project tool window, right-click your project (or from the main menu, click File ) and select New | Module to add a sub project.
In the New Module wizard following the instructions on how to add a module, specify the necessary information and click Finish .
The src folder is created automatically and you can open POM and add a packaging that you need. IntelliJ IDEA adds the module to the parent project. IntelliJ IDEA also adds name and the description of the sub project to the parent POM.
In a multi-module project, the parent POM needs to have a pom packaging.
Last, but not least, IntelliJ IDEA adds the description of the parent POM to the sub project’s POM.
You can click in the left gutter to quickly open the parent POM from your sub project.
You can also add dependencies to the parent POM that will be inherited by the sub projects.
Open Maven tool window to see that all changes made in the parent POM are reflected in sub projects.
Access the Maven settings
Use the Maven settings to configure options such as Maven version, local repository, offline mode, and so on.
In the Settings dialog ( Ctrl+Alt+S ), go to Build, Execution, Deployment| Maven .
Click on the toolbar, in the Maven tool window to access the Maven settings.
On the Maven settings page, configure the available options and click OK to save the changes.
Use the Maven wrapper or a custom version of Maven
Since the Maven2 support is not bundled with IntelliJ IDEA, download and enable the Maven2 Support plugin.
For a custom version, Download the needed Maven version on your computer.
From the main menu select File | Settings | Build, Execution, Deployment |Build Tools | Maven .
On the Maven settings page, in the Maven home directory field, specify the location of the Maven custom version installation. For the Maven wrapper, select the use Maven wrapper option from the list. In this case the version of Maven defined in the .mvn/wrapper/maven-wrapper.properties file will be used.
Change the JDK version in a Maven project
There are several places where you can change the JDK version that will affect not only your current project, but the whole application as well.
Change the JDK version in the Project Structure
Changing the JDK version in the Project Structure dialog will only affect the current project.
From the main menu, select File | Project Structure Ctrl+Alt+Shift+S .
In the dialog that opens, in Project SDK , specify the JDK version and click OK to save the changes.
Change the JDK version for the Maven runner
When IntelliJ IDEA runs Maven goals, it will use the JDK version specified for the Maven runner. By default, IntelliJ IDEA uses the project’s JDK.
Changing the JDK for the Maven runner will only affect the current project.
In the Settings dialog ( Ctrl+Alt+S ), go to Build, Execution, Deployment | Maven | Runner .
On the page that opens, in the JRE field, select the JDK version.
Change the JDK version for the Maven importer
Changing the JDK version for the Maven importer will affect the whole application since it is a part of the Maven global settings. If you want to use the same JDK version as you use in your project for syncing or resolving dependencies, change the JDK version for the importer.
In the Settings dialog ( Ctrl+Alt+S ), go to Build, Execution, Deployment | Maven | Importing .
On the page that opens, in the JDK for importer field, select the same JDK version as you used in the Project Structure and click OK to save the changes.