Getting Started with Maven | Basics of the pom.xml File | Maven's Core pom.xml

Maven can create and build projects with simple commands. The example project created earlier was very small, with only a source code file named App.java.

Maven’s strength is that it manages the libraries, frameworks, and other pieces used by a project. To handle this kind of “project management,” simply running Maven commands is not enough. You also need to understand the “build file” that manages the project.

If you open the project folder, you will find a file named “pom.xml.” POM stands for “Project Object Model,” an object model for handling a project’s various pieces of information. In pom.xml, project settings are written as XML tags.

First, let’s look at the basic source code it contains.

<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.devkuma</groupId>
  <artifactId>SampleMavenApp</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SampleMavenApp</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

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

This can be considered the basic code for pom.xml. If you remove everything unnecessary, the basic structure is as follows.

<project ... omitted ...>

    <modelVersion>4.0.0</modelVersion>
    <groupId>Group ID</groupId>
    <artifactId>Artifact ID</artifactId>
    <version>Version</version>
    <packaging>jar</packaging>
    <name>Name</name>

    <properties>
        ...... property information ......
    </properties>

    <dependencies>
        ...... dependency library information ......
    </dependencies>

</project>

All information in pom.xml is written inside the root tag <project>. This <project> tag has several attributes, such as xmlns, xmlns:xsi, and xsi:schemaLocation. These are fixed values, so you can think of them as values to copy and reuse. There is usually no need to modify them.

After that, the required information is written as tags. The following sections summarize each part.

Basic Project Properties

After the <project> tag, there are tags that configure the basic project properties. Most projects need these, so you should at least remember their roles.

<modelVersion>4.0.0</modelVersion>

This is the POM model version. Set it to “4.0.0.” This version is unlikely to change for the time being.

<groupId>Group ID</groupId>

This is the group ID. You entered it when creating the project. It identifies the creator, company, organization, and so on.

<artifactId>Artifact ID</artifactId>

The artifact ID is the unique ID assigned to the project.

<version>Version</version>

This is the program version. By default, 1.0-SNAPSHOT is set.

<packaging>jar</packaging>

This specifies the package type, such as jar or zip. For web application development, war can also be specified.

<name>Name</name>

This is the program name. In many cases, the artifact ID is used as-is.

<url>URL</url>

This is the URL of the website related to the project. By default, the Apache Maven website URL is set.

<properties>
    ...... property information ......
</properties>

This section collects property values used in this pom.xml. Write these as needed. By default, it contains only the following property.

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

The project.build.sourceEncoding property indicates the default encoding of the source code. It is generally set to UTF-8.

<dependencies>
    ...... dependency library information ......
</dependencies>

“Dependency libraries” are the libraries referenced by this program. Java’s standard system libraries are excluded.

Except for <properties> and <dependencies>, many of the final items are values you entered when creating the project. Since each item is automatically recorded when the project is created, you rarely edit them yourself. It is enough to understand their roles.

<dependencies> and <dependency>

In the generated pom.xml, there was one part with especially complex tags: <dependencies>.

As mentioned earlier, this is used to write dependency library information. However, because the tags are layered, it can be somewhat difficult to understand. The basic form is as follows.

<dependencies>
    <dependency>... omitted ...</dependency>
    <dependency>... omitted ...</dependency>
    ...... omitted ......
</dependencies>

<dependencies> gathers dependency libraries in one place. Each dependency library is described with a <dependency> tag. Write as many <dependency> tags as needed inside <dependencies>.

The <dependency> Tag

The <dependency> tag that describes library information specifies the library by writing several pieces of information inside the tag. In summary, it has the following form.

<dependency>
    <groupId>Group ID</groupId>
    <artifactId>Artifact ID</artifactId>
    <version>Version</version>
    <scope>Scope</scope>
</dependency>

The group ID, artifact ID, and version are the same kind of values used for the project. Because libraries are also made as Maven programs, they also have group IDs and artifact IDs. By specifying these values, Maven can identify which library to use.

The <scope> value may be harder to understand. It specifies the range in which the library is used. In other words, it indicates “when it is used.” If the library is used when running the application, you do not need to specify anything special. You can think of scope as something prepared only for special cases.

The <scope> of a <dependency> Tag

The scope is an item under dependency that defines the range where that dependency is included. The available scopes are as follows.

  • compile:
    • This is the default scope. It is applied by default even if you do not enter it.
    • It is included in all situations.
  • provided
    • Like compile, it is available in all situations.
    • However, if an API is provided by an external container, specifying provided prevents it from being included in the final package.
    • For example, because Tomcat provides the Servlet API by default, setting the Servlet API to provided excludes it during packaging.
  • runtime
    • Use this when it is not needed at compile time but is needed at runtime.
    • It is added to the classpath at runtime and during tests, but not during compilation.
    • test: Used only during tests.
  • system
    • Similar to provided.
    • Specifies a reference to a specific system path.
    • Does not use Maven Central Repository.
  • import
    • This scope is used for POM dependencies in the dependencyManagement section.

The JUnit Library

In the sample project, library information for “JUnit” is written in <dependencies>. This is a Java library that provides features for unit testing. In Java, most testing uses JUnit.

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>3.8.1</version>
  <scope>test</scope>
</dependency>

The library information is as follows.

Group ID: junit
Artifact ID: junit
Version: 3.8.1 (may vary depending on the case)
Scope: test

Both the group ID and artifact ID are fixed as “junit.” These are the values assigned to JUnit. The version is usually set to a minimum version when the project is created.

The scope is “test.” This means it is used only when running tests. It cannot be used when actually running the program. Therefore, the JUnit library is not included when the program is built and packaged.

When Maven builds and packages a program, it always runs unit tests at the same time. If the test library is not included at that point, the build fails. Therefore, the default <dependency> tag for the JUnit library can be considered a “library setting required for a Maven project.” Do not delete it just because you are not using it directly.