You can also check out my Youtube Channel to get access to various tutorials created by me.
Maven is used very often in the industry and I felt it will be good to cover the basics of Maven in this article so that it can be used efficiently😄
This article will cover things like maven basics, maven plugins, maven dependencies and maven build lifecycle.
What is Maven
Maven was created to have a standard way in which Projects can be built. One of its powerful features is dependency management.
Maven is commonly used for dependency management, but it is not the only thing maven is capable of doing.
If you do not know what dependency management means, don’t worry😄. I will cover that in this article as well.
Installing Maven
You can Install Maven from https://maven.apache.org/
Also ensure Maven is set in the PATH so that mvn
comands work.
you can verify if maven is installed and can be accessed using the command
mvn -v
Also ensure JAVA_HOME is set.
By default Maven will use the jdk you provided in JAVA_HOME. This can be overridden, but for this article we will use the jdk provided in JAVA_HOME.
Create your Maven Project
Normally an IDE like eclipse can be used to easily create maven projects. But in this artice I will be running maven commands from command line so that the steps are clearly understood.
Run the following command to Create the project.
mvn -B archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.first.app -DartifactId=first-maven-app
Archetype in the above command is nothing but a sample project template. groupdId tells what group your project comes under and artifactId is the project name.
Once you run the above command, it may take maven a minute or so to download the necessary plugins and create the project.
A folder called as first-maven-app is now created. Open the folder and you will see a file called as pom.xml
pom.xml
POM stands for Project Object Model. pom.xml has all details about your project and this is where you will tell maven what it should do.
The content of this file is shown below
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.first.app</groupId>
<artifactId>first-maven-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>first-maven-app</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
groupdId and artifactId are the same values we gave in the command line.
packaging is the package format of the artifact. Default value is jar. It can have other values as well like ear,war,tar and so on.
version indicates the version number of the artifact. If SNAPSHOT is present, then it indicates the version is still in dev and may not be stable. If the version number does not have SNAPSHOT then its the actual release version.
name is the project name
I Will soon explain about dependencies and plugins in Maven.
Super POM
pom.xml as you can see is pretty small. The reason for this is that a lot of the configuration is present in something called as Super POM which is maintained internally by Maven.
pom.xml extends Super Pom to get all the config present in super Pom.
One of the config present in Super Pom indicates the following
All java source code is present inside src/main/java
All java test code is present inside src/test/java
I mentioned only this config here since we will be dealing with both source code as well as test code in this article.
Code
The entire code discussed here is available in this repo https://github.com/aditya-sridhar/first-maven-app
Let’s add a simple java code. Create the following folder structure
src/main/java/com/test/app/App.java
App.java is the java code we will be adding.
Copy the following code into App.java
package com.first.app;
import java.util.List;
import java.util.ArrayList;
public class App
{
public static void main( String[] args )
{
List<Integer> items = new ArrayList<Integer>();
items.add(1);
items.add(2);
items.add(3);
printVals(items);
System.out.println("Sum: "+getSum(items));
}
public static void printVals(List<Integer> items){
items.forEach( item ->{
System.out.println(item);
});
}
public static int getSum(List<Integer> items){
int sum = 0;
for(int item:items){
sum += item;
}
return sum;
}
}
This is a simple code which has 2 functions.
But one thing to observe is, the code is using lambda expressions inside the forEach loop in printVals function.
Lambda expressions need minimum java 8 to run. But by default Maven 3.8.0 runs using java version 1.6.
So we need to tell maven to use java 1.8 instead. In order to do this we will use Maven Plugins.
Maven Plugins
We will use the Maven Compiler Plugin to indicate which java version to use. Add the following lines to pom.xml
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugins>
</build>
...
</project>
It can be seen that the java source and target versions are set to 1.8
Plugins basically get some action done in maven. The compiler plugin compiles the source files
The full pom.xml is available here
There are a lot of maven plugins available. By knowing how to use plugins well, Maven can be used to do amazing things 😄
Maven Dependencies
Normally while writing code, we will be using a lot of existing libraries. These existing libraries are nothing but dependencies. Maven can be used to manage dependencies easily.
In the pom.xml of our project you can see the following dependency
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
This dependency is telling that we will be needing junit. Junit is used to write Unit Tests for java code. Similarly a lot of other dependencies can be added.
Let’s say you want to handle JSON’s in the code. Then you can add gson dependency as shown below
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
You can search for Maven artifacts in https://search.maven.org
Transitive Dependencies
Let’s say you Add a dependency A to the Project. Now A depends on a dependency called as B. B depends on a dependency called C.
Since you are using A in the project, ideally you will also need B and C.
But fortunately, it is enough if you add only A in pom.xml. Because Maven can figure out that A depends on B and that B depends on C. So internally Maven will automatically download B and C.
Here B and C are transitive dependencies.
Custom Maven Repository
All these dependencies are available in a Public Maven Central Repository http://repo.maven.apache.org/maven2
It is possible that there are some artifacts which are private to your company. In this case you can maintain a private maven repository within your organization. I won’t be covering this portion in this tutorial.
Adding the test class
Since junit dependency is present in the project, we can add test Classes.
Create the following folder structure
src/test/java/com/test/app/AppTest.java
AppTest.java is the Test Class
Copy the following code into AppTest.java
package com.first.app;
import junit.framework.TestCase;
import java.util.List;
import java.util.ArrayList;
public class AppTest extends TestCase
{
public AppTest( String testName )
{
super( testName );
}
public void testGetSum()
{
List<Integer> items = new ArrayList<Integer>();
items.add(1);
items.add(2);
items.add(3);
assertEquals( 6, App.getSum(items) );
}
}
This class tests the getSum() function present in App Class.
Maven Build Lifecycle and Phases
Maven follows a build lifecycle to build and distribute artifacts. There are 3 main lifecycles
- Default lifecycle: This deals with building and deploying the artifact.
- Clean lifecycle: This deals with project cleaning
- Site lifecycle: This deals with Site documentation. Will cover this in a different article
A Lifecycle is made up of phases. Here are some of the important phases in default lifecycle
validate: Check if all necessary information is available for the project
- compile: Used to compile the source files. Run the following command to compile
mvn compile
After running this command, a folder called target is created with all the compiled files.
- test: Used to run all the unit tests present in the project. This is why Junit dependency was needed. Using Junit, Unit tests can be written. Test classes can be run using the command
mvn test
- package: This will run all the above phases and then package the artifact. Here it will package it into a jar file since pom indicates a jar is needed. Run the following command for this
mvn package
The jar file is created inside target folder
verify: This will ensure if quality criteria is met in the project
- install: This will install the package in a local repository. The local repository location is usually ${user.home}/.m2/repository. Use the following command for this
mvn install
- deploy: This is used to deploy the package to a remote repository
One more command which is commonly used is the clean command which is given below
mvn clean
This command cleans up everything inside the target folder
References
Maven’s Offical Guide: https://maven.apache.org/guides/getting-started/
More about POM : https://maven.apache.org/guides/introduction/introduction-to-the-pom.html
More about Build Lifecycle : https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
Congrats 😄
You know how to use Maven now. This article covered just the basics of pom, plugins, dependencies and build lifecycle. To know more about Maven check the links I have given above.
Happy Coding 😄