Maven — The underrated champion

Mohit Kanwar
Xebia Engineering Blog
4 min readJun 13, 2020

Apache Maven, as the name suggests is the trusted expert in managing the Java builds and dependencies.

While Gradle's popularity is increasing, owing to its flexible lifecycle, Maven is still the most popular tool for Java build and dependency management.

Almost every Java developer today has experienced the taste of Maven. I have been using maven for over 8 years now, and have become very comfortable while working with it.

The declarative approach used by Maven makes it easy to use. A new developer can start working with maven within few minutes of introduction.

Convention over configuration approach beautifully reduces the amount of code to be written by the developer.

This simplicity, however, conflicts with our mindset that simple things cannot be powerful, and as I have experienced during interviews, most candidates know just a couple of things about Maven

Rarely though, some people are aware of the different plugins that maven offer. Or even rare anyone has developed a custom plugin.

Today, I am not going to write about anything new. The following topics consist of some common problems that my team members believed are complex, but have simple solutions provided by Maven out of the box. When I shared this information with my team, it was highly appreciated. I hope you like it too.

  1. How to check unused dependencies?
  2. How to check a new version of dependencies?

How to check unused dependencies in pom

Having unused dependencies in our pom.xml can easily go unnoticed. Unused dependencies may arise due to iterations of development, where a dependency was added, but with changes, it is not needed anymore.

Keeping such dependencies in the system makes our code-heavy without providing any benefits. Hence it is a good idea to remove unused dependencies.

Manually identifying the usage of dependencies is tedious and time taking.

Maven provides a simple plugin to check for dependencies

As an example, I am using the sample project available at https://github.com/mohitkanwar/playing-with-dependencies. This is a simple Spring-Boot project generated from the starter.

To demonstrate unused dependencies, I added a few dependencies in pom, but I am not using them in the code.

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>

</dependencies>

So to identify which dependencies are unused, I need to go to the project directory and run a simple command

mvn dependency:analyze

Running the above command produces the below output

The output of the command has two sections and this answer by Raghuram beautifully explains both.

Below is the extract from the answer

Used undeclared dependencies are those which are required, but have not been explicitly declared as dependencies in your project. They are however available thanks to transitive dependency of other dependencies in your project. It is a good idea to explicitly declare these dependencies. This also allows you to control the version of these dependencies (perhaps matching the version provided by your runtime).

As for unused declared dependencies, it is a good idea to remove them. Why add unnecessary dependency to your project? But then transitivity can bring these in anyway, perhaps, conflicting with your runtime versions. In this case, you will need to specify them — essentially to control the version.

How to check newer versions of project dependencies?

One of our banking customers had mandated that their security team needs to be made aware of any new version being released for the dependencies that we are using. The security team needed this information irrespective of if we are using the latest dependency or not. They used this information to certify our product to prevent it having any security flaws.

This means to achieve this functionality we needed a periodic check on hundreds of dependencies that we had in our project.

Maven has already made me lazy enough to not worry about finding the right jar from internet and add to my classpath, just a small 5 line config is sufficient, do you think someone like me would periodically check the latest dependencies versions?

(Now, git hosts e.g. Github provide this facility out-of-the-box, but it wasn’t available earlier)

Well, maven has a simple to use plugin for this as well

mvn versions:display-dependency-updates

When we run this plugin, it identifies all the dependencies in our system, and goes to the linked remote repositories to check the latest version.

Since the operation involves all the dependencies (x) and all the linked repositories (y) it performs (x*y) network calls and hence is a bit slow.

But this saves us from manually checking all the dependencies.

Here is a snapshot of output when I ran the above command on the same project on 13th June 2020. The results might differ at later point, when newer versions are released.

--

--

Mohit Kanwar
Xebia Engineering Blog

I am a software developer and learner. I love to read code written by other people, understand the logic and the architecture. I love “Why”s.