Hi everyone, welcome back to SrishCodes where I teach you interesting tech concepts that you should know about as a current or aspiring software developer. Today I will be sharing with you about the basics of Maven and why it is needed. Basic understanding of a Java program and dependencies is needed for this article. This is a super important tool and honestly the bread and butter of every successful backend developer.
What is Maven?
Maven is a powerful build tool developed by Apache Software Foundation. It is commonly used for dependency management (details later), publish the artifacts and share packages like JAR and WAR.
For dependency management, Maven dynamically downloads libraries and Maven plug-ins from one or more repositories such as the Maven Central Repository and stores them in a local cache. Maven is primarily used in Java projects, however it can also help you build and manage projects written in Ruby, Scala, C# and other languages.
You can also manage your Java project through Maven as it uses a standard directory layout shown below and a default build lifecycle. This means that it knows where and how your code is structured.
Maven encompasses the following:
- a project object model,
- a set of standards,
- a project lifecycle,
- a dependency management system, and
- the logic for executing plugin goals at defined phases in a lifecycle.
Why do we need Maven?
Most Java projects use dependencies, which are libraries or packages that your project uses. Generally, you need to download and add them manually. Now imagine doing this manually for hundreds of dependencies. Now if you are thinking of writing a script to do this, that is basically what Maven does - but much, much better.
The Maven build script documents the build process, gets dependencies automatically and also automates the complete build from building the project, running unit tests and tuning environment properties, etc. Now let's deep dive into Maven.
Structure of a Maven project
Code | Location |
source code | ./src/main/java |
resources | ./src/main/resources |
test | ./src/test |
compiled byte code | ./target |
distributed artifacts | ./target/classes |
downloaded dependencies | ~/.m2/repository/ |
mvn script that executes Maven | bin/ |
creates ClassLoader that Maven executes | boot/ |
global configuration for Maven behaviour | conf/ |
user specific configuration for Maven behaviour | ~/.m2/settings.xml |
JAR file that contains core of Maven | ~/.m2.lib/ |
Maven POM file
When you use Maven, you describe your project using a well-defined Project Object Model or the POM file. Project Object Model(POM) file is an XML file that contains information related to the project and configuration information such as dependencies, source directory, plugins, resources needed, etc. used by Maven to build the project. In addition, it contains the other projects it depends on and inherits POM settings from parent projects.
Maven can then apply cross-cutting logic from a set of plugins. When you execute a maven command you give maven a POM file to execute the commands. Maven reads the pom.xml file to accomplish its configuration and operations.
There are two important identifiers that you must know about.
- groupId - Identifies a set of related artifacts. For example,
org.apache.maven
is the base groupId for all artifacts produced by the Apache Maven project - artifactId - The project’s main identifier. When you generate an artifact, it is going to be named with this
artifactId
. When you refer to a project, you are going to refer to it using theartifactId
.
The presence of a pom.xml file defines a Maven project. In short, it is a fundamental part of the entire Maven system.
Dependencies and Repositories
Like mentioned earlier, Maven maintains the dependencies needed by your project. If the dependencies are not found in the local Maven repository, Maven downloads them from a central Maven repository and puts them in your local repository. The local repository is just a directory on your computer's hard disk. You can specify where the local repository should be located if you want to. You can also specify which remote repository to use for downloading dependencies.
Build Life Cycles, Phases and Goals
Build Life Cycles
There is a specific life cycle that Maven follows to deploy and distribute the target project. This life cycle consists of a sequence of build phases, and each build phase consists of a sequence of goals.
There are three built-in life cycles:
- clean (3 phases) - Clean project and remove all files generated by the previous build
- default/build (23 phases) - Responsible for project deployment
- site (4 phases) - Create the project’s site documentation
Build Phases
The order that the build phase is executed matters. This means that if we execute a specific phase, Maven executes all the phases before that phase, and then the specific phase. Below are some build phases:
Phase | Action |
validate | Check if necessary information for build is available |
compile | Compile source code |
test-compile | Run unit tests |
package | Package compiled code |
integration-test | Process and deploy package for integration tests |
install | Install package to local repository |
deploy | Copy package to remote repository |
Maven Goals
A sequence of goals make up a phase and each goal executes a specific task. When you run a phase, then Maven executes all the goals in an order that are associated with that phase.
plugin: goal
Some examples are shown below:
- compiler: compile - compile phase
- compiler: test - test-compile phase
- surefire: test - test phase
- install: install - install phase *jar and war: war - package phase
Maven Plugins
Here's where the magic starts. Maven doesn’t know how to do much beyond parsing a few XML documents and keeping track of stuff.
All of this stuff is handled by plugins. For example, the Maven Surefire plugin is the plugin that is responsible for running unit tests. A Maven plugin is a group of goals. Plugins are retrieved from the Central Maven Repository. I won't go into too much detail about this but you can also add your own custom plugin if you need to set of actions for your project which are not covered by the standard Maven build phases and goals.
Build Profiles
We also mentioned earlier how Maven maintains environment variables. Now this means there can be different variables and even different ways to build your project on your local computer, test and production environment. We can add <profiles>
in POM.xml to set or override default values. To enable different builds you can add different build profiles using an identifier <id>
, and then specify which profile to use before executing your Maven build using the -P
command line flag.
Versioning
Versions are defined using the below format:
<major version>.<minor version>.<incremental version>-<qualifier>
For example, in the version 4.7.3-beta-01
, the major, minor and incremental versions are 4, 7 and 3 respectively. beta-01
is the qualifier.
You can identify if a Maven project is under active development if version contains the string -SNAPSHOT
. When you deploy a snapshot, you are releasing a snapshot of a component at a specific time. On the other hand, when your project depends on a SNAPSHOT
release, Maven will periodically attempt to download the latest snapshot from a repository when you run a build.
And that was all for this now! If you would like me to also provide an example Maven project, make sure to leave a comment and follow me for more content. Until next time