Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Build Automation using Maven
2.1.
Example Project Structure
2.1.1.
pom.xml for NinjaBackendAPI
2.1.2.
pom.xml for NinjaWebFrontend
2.1.3.
pom.xml for NinjaAppFrontend
2.2.
Automating Build using Maven Invoker Plugin
3.
Frequently Asked Questions
3.1.
Can I tell the Invoker Plugin to exclude some pom.xml files too?
3.2.
What is the benefit of using build automation?
3.3.
What if I need some other project to be compiled before I run my current project?
4.
Conclusion
Last Updated: Mar 27, 2024
Hard

Build Automation in Maven

Author Satvik Gupta
0 upvote
Leveraging ChatGPT - GenAI as a Microsoft Data Expert
Speaker
Prerita Agarwal
Data Specialist @
23 Jul, 2024 @ 01:30 PM

Introduction

Maven is a software project management tool. It helps us automate certain parts of software development, such as compiling, testing, etc. It is popular with JVM languages, such as Java, Scala,  Kotlin,etc. 

Maven Build Automation

In large software, projects are often interdependent on each other. Thus, changes to one project can affect another project. We can use Maven to help us automate testing across different projects. Let us look how. 

Build Automation using Maven

Suppose we have software that has been divided into 3 parts. One part is for the backend, another for the frontend of the website, and the last one for the mobile application frontend. The mobile application and the website use the same backend to maintain consistency in both of them. 

Thus, changes to the backend code should not cause any errors in the mobile/website frontend code. Checking for errors across different projects is generally a part of integration testing

Maven has a phase for integration testing in its lifecycle. You can read more about Maven phases by visiting our article on Maven Phases -  Introduction to Maven Phases. So, we will need to include our website and mobile frontend projects in the integration testing phase of the backend project.

Let's see how we can do this. 

Example Project Structure

Let's look at the structure for the example project we are considering. 

We have three projects - NinjaAppFrontend, NinjaWebFrontend, and NinjaBackendAPI. 

NinjaAppFrontend and NinjaWebFrontend projects both depend on the NinjaBackendAPI. 

All three projects are Maven projects. 

pom.xml for NinjaBackendAPI

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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>com.codingninjas</groupId>
    <artifactId>NinjaBackendAPI</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <maven.compiler.source>9</maven.compiler.source>
        <maven.compiler.target>9</maven.compiler.target>
    </properties>


</project>

 

pom.xml for NinjaWebFrontend

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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>com.codingninjas</groupId>
    <artifactId>NinjaWebFrontend</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>9</maven.compiler.source>
        <maven.compiler.target>9</maven.compiler.target>
    </properties>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>com.codingninjas</groupId>
            <artifactId>NinjaBackendAPI</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>


</project>

 

pom.xml for NinjaAppFrontend

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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>com.codingninjas</groupId>
    <artifactId>NinjaAppFrontend</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <maven.compiler.source>9</maven.compiler.source>
        <maven.compiler.target>9</maven.compiler.target>
    </properties>


    <dependencies>
        <dependency>
            <groupId>com.codingninjas</groupId>
            <artifactId>NinjaBackendAPI</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>


</project>


As you can see, NinjaBackendAPI is present under dependencies section of both NinjaAppFrontend and NinjaWebFrontend. 

Automating Build using Maven Invoker Plugin

Apache provides the Maven Invoker plugin. It is a plugin that is useful in running multiple Maven projects together. This ability makes it perfect for our purpose of integration testing. 

Integration testing is one of the most important uses for this plugin. Unless specified otherwise, this plugin is executed in the integration test phase by default. 

We want to run the builds of NinjaWebFrontend and NinjaAppFrontend, anytime we perform integration testing for NinjaBackendAPI. This will ensure that changes to NinjaBackendAPI do not cause errors in the other 2 projects. If any errors are found, the Maven Invoker Plugin will detect them and report them to us, and the integration test will fail. 

Let us see how we can use it. 

We need to add the plugin to the pom.xml of NinjaBackendAPI and configure it. The final pom.xml should look like this. 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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>com.codingninjas</groupId>
    <artifactId>NinjaBackendAPI</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <maven.compiler.source>9</maven.compiler.source>
        <maven.compiler.target>9</maven.compiler.target>
    </properties>


    <build>
    <plugins>
        <plugin>
            <artifactId>maven-invoker-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
                <pomIncludes>
                    <pomInclude>NinjaWebFrontend/pom.xml</pomInclude>
                    <pomInclude>NinjaAppFrontend/pom.xml</pomInclude>
                </pomIncludes>
                <projectsDirectory>C:\Administrator\NinjaProject</projectsDirectory>
            </configuration>
            <executions>
                <execution>
                    <id>build</id>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    </build>


</project>


Let us understand the meaning of the lines we have added. 

  • The plugin has been added under the <build> tag because it is a build plugin. 
     
  • The artifactId for the plugin is maven-invoker-plugin. We are using the latest version, 3.3.0.
     
  • In the <configuration> section, we specify a <pomIncludes> tag. In this, we specify which pom.xml files we want to include in our integration testing. We specify the paths to the pom.xml files. 
     
  • The <projectsDirectory> is the directory in which the plugin will look for the projects we specified in the <pomIncludes> section. By default, the plugin looks in "/src/it" of the current project. 
    Here, we have specified a different value because our project structure is different.
     
  • The <execution> tag specifies what executions need to be done when this plugin is run during its phase (integration testing phase in our case). 
    We can specify as many executions as we want. Here, we only have one. 
    The <id> tag of the execution is so that we ourselves can distinguish it from other executions. It serves no purpose to Maven. 
    The <goals> are the goals of the invoker plugin that we want to run during this execution. 
    Here, we only want to run one goal - run. The run goal will run each of the projects we specified in <pomIncludes>. It will output any logs collected to the command line. 
     

Let's try running it now. Type

mvn integration-test 


Into the terminal. This will run the integration test phase. You can also run the install, deploy, or any other phases that come after integration testing. Integration testing will run as a part of them by default. 

The output is shown below. 

Output-1
Output-2
Output-3 - dependents have also been run.

As you can see in the last screenshot, the invoker plugin has run both NinjaAppFrontend and NinjaWebFrontend. Both of them have passed. If either failed, the entire Maven build would have also failed. 

Must Read Apache Server

Get the tech career you deserve, faster!
Connect with our expert counsellors to understand how to hack your way to success
User rating 4.7/5
1:1 doubt support
95% placement record
Akash Pal
Senior Software Engineer
326% Hike After Job Bootcamp
Himanshu Gusain
Programmer Analyst
32 LPA After Job Bootcamp
After Job
Bootcamp

Frequently Asked Questions

Can I tell the Invoker Plugin to exclude some pom.xml files too?

Yes, you can. Similar to the <pomIncludes> property, a <pomExcludes> property also exists. In that, we can specify which pom.xml files we don't want to be included in our integration test.

What is the benefit of using build automation?

Software projects undergo many changes every day. It would be tedious and time-consuming to run tests on all dependents manually. The dependency structure could also be very complex if there are a large number of projects. Automation makes all of this simple and easy.

What if I need some other project to be compiled before I run my current project?

We can do this with the invoker plugin as well. We can specify a tag <setupIncludes> and configure it in the same way we did for <pomIncludes>. Then the invoker plugin will run those projects before the current one.

Conclusion

This blog has explored build automation in Maven. We have seen how we can structure dependencies in projects, and we saw how we could link the builds of different projects to each other. We have verified the same by running it on an example project.

We hope you leave this article with a broader knowledge of Maven and Software project management. We recommend that you explore our different articles on these topics as well, such as:

What do you mean by Maven

Introduction to Maven Command

Ant vs Maven

You can practice questions on various problems on Coding Ninjas Studio, attempt mock tests. You can also go through interview experiences, interview bundle, go along guided paths for preparations, and a lot more!

 

Keep coding, keep reading Ninjas. 

 

Live masterclass