10 minutes read

In this topic, you are going to create and study your first project with Maven. It is assumed that you have downloaded and installed Maven on your computer. If you have not done so, please follow the Download and Installation instructions.

Before we start learning the structure of the simplest project, let's discuss how to distinguish it from other Maven-based projects.

Project coordinates

Every project managed by Maven is uniquely identified by three coordinates:

  • groupId: is generally unique in an organization or a project. For example, org.hyperskill or org.hyperskill.learnmaven.
  • artifactId: is the name that the project is known by. For example, first-maven-app.
  • version: is the last piece of the full project name. It looks like 1.0, 1.1, 1.0.1, etc.

These three values make up the full project name according to the following rule:

<groupId>:<artifactId>:<version>

For example, we can name a project like this:

org.hyperskill.maven:first-maven-proj:1.0

To understand these coordinates better, look through these several existing Java projects created with Maven:

com.beust:jcommander:1.72
org.testng:testng:6.14.3
org.hibernate:hibernate-core:5.3.3.FINAL

A version may contain an additional word like FINAL or SNAPSHOT. Do not worry about this for now; we will learn more about it later.

There is another option packaging that determines the type of the resulting artifact (file): jar, pom, maven-plugin, war, ear, etc. When no packaging is declared, Maven assumes it is jar by default. In this topic, we will not specify it.

Generating the simplest project

It is time to generate the simplest project using Maven. In a terminal (for UNIX-like systems), go to the directory where you want to create this project and type the following command:

mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.3 -DgroupId=com.hyperskill -DartifactId=first-maven-app -DinteractiveMode=false 

If you're using Windows, type the following command in the command prompt or PowerShell:

 mvn archetype:generate "-DarchetypeArtifactId=maven-archetype-quickstart" "-DarchetypeVersion=1.3" "-DgroupId=com.hyperskill" "-DartifactId=first-maven-app" "-DinteractiveMode=false"

This command will start generating a project based on the archetype maven-archetype-quickstart; groupId is specified as com.hyperskill, and the artifactId is set to first-maven-app. If you like, you can specify other values for these parameters (like com.companyname.app, my-app), but do not modify the archetype name.

Project generation may take some time. Please wait until it is finished to continue.

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:3.0.1:generate (default-cli) @ standalone-pom >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:3.0.1:generate (default-cli) @ standalone-pom <<<
[INFO] 
[INFO] --- maven-archetype-plugin:3.0.1:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: basedir, Value: /home/art/Projects
[INFO] Parameter: package, Value: com.hyperskill
[INFO] Parameter: groupId, Value: com.hyperskill
[INFO] Parameter: artifactId, Value: first-maven-app
[INFO] Parameter: packageName, Value: com.hyperskill
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /home/art/Projects/first-maven-app
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12 seconds
[INFO] Final Memory: 13M/45M
[INFO] ------------------------------------------------------------------------

The command created a new directory with the name we've specified artifactId: first-maven-app. Let's go to this directory.

Basic project structure

The generated project has a standard project structure:

first-maven-app
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── hyperskill
    │               └── App.java
    └── test
        └── java
            └── com
                └── hyperskill
                    └── AppTest.java

The root directory is first-maven-app; it has the same name as the artifactId. It includes the pom.xml file and the src directory.

The pom.xml is a file that describes this project (POM: Project Object Model). All Maven-based projects contain this file.

The src directory contains all of the source material needed to build the project. The directory src/main/java contains the project source code, and the src/test/java contains the source code of tests. In both cases, .java files are located inside the package com.hyperskill that is the same as the groupId.

Maven also created the sample Java source code file called App.java. It just prints HelloWorld to the standard output. We will not explain it here, because we assume that you already know how to write programs like that. If you want, you may open this file.

Our project structure is simple enough, but real projects have some additional files and directories. The basic structure (project root, pom.xml, src) is always the same.

The POM file

pom.xml is the basic unit of work in Maven. It contains the Project Object Model (POM) that provides all the information required to build a project. In our project, the file contains a small piece of information. But in reality, it can be huge.

Let's open this file. It should look like the text below. We have slightly formatted the file to make it more readable:

<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.hyperskill</groupId>
  <artifactId>first-maven-app</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>first-maven-app</name>
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

This is a very simple POM, but still there are the key elements that every POM contains:

  • project - is the top-level element in any Maven pom.xml file;
  • modelVersion - is the version of the object model used (4.0.0);
  • groupId - is the unique identifier of the organization that created this project;
  • artifactId - is the identifier of this artifact (project);
  • version - is the version of this artifact (SNAPSHOT indicates that this version of the project is in development);
  • name - is the display name for the project;
  • url - is the URL where the project's site can be found;
  • properties - section contains a set of common project settings;

The dependencies section is used to include libraries and other projects into your project. In this topic, we will not go into details.

Remember that the minimal requirements for POM are project, modelVersion, and three project coordinates: groupId, artifactId, and version.

Lifecycle of the Maven build

The Maven build lifecycle is based on the sequence of phases. A phase represent a specific stage of the build. Each phase performs a specific set of actions necessary for a successful project build. The build lifecycle includes three main sets of phases: default, clean, and site.

default manages project deployments:

  • validate validates if the project is correct and all necessary information is available;
  • compile compiles the source code;
  • test tests the compiled source code using a suitable unit testing framework;
  • package takes the compiled code and package it in JAR or WAR;
  • verify checks the integrity and correctness of the project;
  • install installs the package into the local repository to use as a dependency in other projects locally;
  • deploy in the build environment, copies the final package to the remote repository.

clean is used to clean the project:

  • pre-clean performs additional operations before cleaning the project;
  • clean deletes all files generated with the previous build from the project;
  • post-clean performs additional operations after cleaning the project.

Finally, site is used to create the project's site documentation:

  • pre-site executes the necessary processes prior to the actual project site generation;
  • site generates the project's site documentation;
  • post-site executes processes necessary to finalize the site generation;
  • site-deploy deploys the generated site documentation to the specified web server.

This is not a complete list of phases. You can read about the rest of them on the official Maven website.

Each phase can be performed using the mvn [phase-name] command.

Building and starting the project

To build a Maven-based project, you should be inside the root directory of your project, at the same level as the pom.xml file. There are several ways to do that:

  • Building a project without cleaning the project and without running tests:
mvn compile
  • Building a project without cleaning the project, but running tests:
mvn package
  • Cleaning a project and then building (with tests):
mvn clean package
  • Using install Instead of package:
mvn clean install

Later, you will study how all these ways of building a project differ from one another. For now, just choose one you like and use it. We recommend using one of the last two ways. However, the first way is the fastest because it runs no tests.

If no errors occur, you will see the success message:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.345s
[INFO] Final Memory: 8M/28M
[INFO] ------------------------------------------------------------------------

This message means that you have built your project. Now, there is a new directory target at the same level as pom.xml and src.

first-maven-app
├── pom.xml
├── src
└── target

The target directory contains the results of building the project. The most important thing here is the first-maven-app-1.0-SNAPSHOT.jar file. This file may have a different name if you use another artifactId.

To start this project, enter the following command in the terminal:

java -cp target/first-maven-app-1.0-SNAPSHOT.jar com.hyperskill.App

Your program must output:

Hello World!

If you want to remove the result of the last build from the project file, use this command:

mvn clean

It will remove the target directory.

Congratulations, you are one step closer to writing real applications that need external dependencies and a lot of environment configurations! Maven will help you with that.

Possible problems

Finally, let's look at some common problems that beginners tend to have with Maven.

  • No POM file in this directory. Commands to build and manage a project require the POM file in the directory. If there is no POM file, these commands will fail with the following message:
[ERROR] The goal you specified requires a project to execute but there is no POM in this directory (/home/art/Projects). Please verify you invoked Maven from the correct directory.
  • Source/Target option is no longer supported. The latest versions of Maven do not support old versions of Java.
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project first-maven-app: Compilation failure: Compilation failure: 
[ERROR] Source option 1.5 is no longer supported. Use 1.6 or later.
[ERROR] Target option 1.5 is no longer supported. Use 1.6 or later.

To solve this problem, specify the source and target options in the properties section of your POM:

<properties>
  <maven.compiler.source>1.6</maven.compiler.source>
  <maven.compiler.target>1.6</maven.compiler.target>
</properties>

Do not forget to Google your problem if you cannot solve it. Maven is a very popular tool, and there already exists a solution for most of the common issues.

142 learners liked this piece of theory. 2 didn't like it. What about you?
Report a typo