Break New Ground

Mastering Maven: Getting Started

Welcome to a new series of posts where we'll explore the Apache Maven build tool and how to make the most of it. Let's begin with the basics.

The goal of a build tool such as Apache Maven is to apply a series of transformations unto source code to turn it into a deliverable artifact; the most obvious transformation for Java sources is compilation into Java byte code for example. Transformations may be applied one after the next, with intermediate results combined by other transformations, such as pre- and post-processing of resources files, generation of source code via annotation processors, generation of metadata in various formats (typically but not only limited to XML or JSON), to later be packaged as single JAR file.

As the name implies, Apache Maven is a project harbored by the Apache Software Foundation and as such it does not come bundled with a JDK distribution; you must install Apache Maven in a way that's compatible for your platform. There are many ways to make this work, the typical way is to download and install Apache Maven yourself, however you can also use popular package formats (.rpm, .deb) and package managers (rpm, yum, apt-get, brew) to achieve this goal. My personal choice is to use SDKMAN! as it works in all major platforms.

Assuming you've successfully installed Apache Maven on your system the next step is to create a project. You also have several choices to make this happen, such as using your IDE of choice or a project bootstrapping tool such as Apache Maven archetypes (to be discussed at a later date), JBoss Forge, Lazybones, or other. To keep things simple I'll assume a simple text editor and the command line are the only tools we'll need for the time being. Open up a command prompt and execute the following commands (works on Linux and MacOSX, for Windows you'll have to find compatible commands).

The last command creates and empty file named pom.xml. This file contains the instructions that Apache Maven follows in order to apply transformations to the source code. It's name is derived from Project Object Model, you can find more information about the format itself at this link. For now we'll add the minimum required content to this file, mainly what are known as the GAV (Group, Artifact, Version) coordinates for this project however bear in mind that these GAV coordinates are important as they become part of the identity of the generated artifacts, also you must follow a series of rules for picking GAV coordinates if you intend to publish artifacts to the Central Repository. We'll cover repositories in a follow up post. These are the contents of our pom.xml file:

Apache Maven is configured by default to build Java projects, and it does so by providing a lot of behavior out of the box that relies on conventions, this lets you define as little configuration as needed in the pom.xml file. The default conventions for Java projects is to place source code under the src/main/java folder, thus adding a class such as com.acme.Sample shown in the following screenshot

Means that the following file structure must be put in place

All that's left for now is to invoke Apache Maven and let it build our project. Apache Maven relies on commands to perform its duties. Commands are intrinsically related to other concepts such as lifecycles, phases, and goals which we'll cover later, but for now the command we should invoke to build the project is mvn verify. Invoking this command on the command prompt should result in an output similar to this one

Notice that Apache Maven indicates the steps it executes along the way to fulfill its duty; these steps are the actual transformations performed on the source code, of which there's a single file at the moment. Apache Maven places all intermediate and final files under a particular folder based on conventions once again. Here's how the file structure looks like after the project has been built

Notice that the compiled classes can be found under target/classes, as well as the final package whose name matches the GAV coordinates we specified in the POM file. You'll find the compiled class inside the JAR file alongside other metadata files that Apache Maven adds.

Well this conclude the first post in this series. We barely scratched the surface on what Apache Maven can do for you. In the next post we'll cover one of the most well known features that Apache Maven provides: dependency resolution.

Join the discussion

Comments ( 3 )
  • Lloyd Rochester Monday, January 13, 2020
    Great post and thanks for the simple getting started method. It's unfortunate, however, that Maven doesn't support a simple `mvn init` that creates a basic maven skeleton project and we have to manually enter in XML for the pom ...
  • Andres Monday, January 13, 2020
    Lloyd, Maven does provide support for bootstrapping projects via archetypes. The thing is, what constitutes a minimal project setup? Is it a simple JAR library? Or is it an trivial executable JAR? Could it be a web application packaged as a WAR? What about a small microservice paired with the next hot framework?

    Agreeing in what constitutes this minimal bootstrapped project likely leads to a heated bike-shed discussion, which is why the Maven team opted to not force a single path and let developers choose from the wide range of standard archetypes. The problem may be now that there are too many choices.

    If on the other hand, the idea behind `mvn init` would be to provide similar behavior as `gradle init` does today, the latter used to bootstrap a trivial Java library project, nowadays it gives you a few options for project types as well as a choice of Groovy or Kotlin DSL. Not nearly as powerful as Maven archetypes but it may be slowly moving towards that direction.
  • Lloyd Rochester Wednesday, January 15, 2020
    Thanks and I understand the problem of having no hard definition of a "standard project" but I feel like the problem can still be solved. Popular projects like helm.sh and sbt are able to do it by keeping it minimal/small and simple. There is a common denominator. My basic comment is Maven is great, but I sure wish it was easier to use.

    In some sense I think this post is case and point how it's not easy to get started as typing an XML blob into pom.xml would not be fun.

    I have used Java for a long time from ant, maven, gradle. I prefer Maven over all. It is deep and vast tool. The challenge I have with it is that it is so deep and vast that documentation for me usually resorts to Google and Stack Overflow.

    When I want to create a quick project this ends up being my workflow:
    1) it's gonna be better this time, run mvn and I can easily bootstrap
    2) Number 1 didn't work I'll Google and find a simple archetype, or possible be lucky and find the archetype I used last time.
    3) There are too many archetypes and I can't get the one I need.
    4) OK I'll just copy from one of my previous projects what I've used before ...

    When I do a `helm create` of `sbt new` I'm up in seconds. Granted these projects don't have the surface area of maven.

    In closing I want to say thank you for the post! I look forward to continue to use Maven. It's great to have the support of Oracle to keep Maven relevant and running strong. The world is much better with Maven!
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.