Know your pom.xml

Updated: Jul 12


Know you pom.xml

In this blog, we will learn about different components of pom and how each part of pom plays a crucial role in providing required information to other classes present in the project.


If you find this too long to read, you can skip to the Key Takeaway section.


Introduction

POM stands for 'Project Object Model.' We can see that POM comprises three words, and each word has its own significance.

  • Project: It is the logical container for any software/feature where every functionality is implemented.

  • Object: Each project comprises different objects like classes, methods, user-defined variables, etc.

  • Model: Model is an abstract view of any project and object, i.e., it has the information of what projects/object looks like.

Now, suppose we put all three (Project, Object, and Model) pieces together. In that case, it can be observed that POM contains all the necessary information required by Project and different objects associated with the project.


Some Important Points

  • POM contains a configuration file, developer information, dependencies, their versions, defect tracking system, repository information, organization, licenses, and all other crucial information for giving life to your codebase.

  • POM has all the information regarding the build process in the form of plugin configuration.

  • POM contains an answer about WHO, WHAT, and WHERE of the projects.



Below is the pom showing different sections. The below section is taken from the official maven website.

The currently supported version of POM is 4.0.0 that you can find in modelVersion tag.

Jump If you want

If you want to jump to specific types of elements, then you can use the below list.


Bare Minimum

Below pom is the bare minimum for any project (Project does not include any dependency, everything is coded from scratch). The groupId, artifactId, and version make any project unique. A combination of groupId, artifactId, and version is like an address for any project.

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.codewithnk.course</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>


Different sections of POM


The Basic Tags

We will try to understand different tags by taking an example.


Let's take an example of a Vehicle Tracking System, and it will contain different services like vehicle onboard service, vehicle booking service, admin service. In this example, we assume that the company working for wants to have a different groupId for each project.


groupId:

There is no set rule to define groupId. It depends on the company, whether they want to group different services under project or different projects under an organization.

There is not set rule to define groupId, it totally depends on the company, whether they want to group different services under project or different project under an organization.
Different ways to define Group Id

  • In our example, you can name your groupId as com.vehicletracking. There is no set rule to name your groupId.

  • It is generally unique among any organization and project. It's a container for all services falling under the same project.

  • GroupId doesn't need to be separated by dots, but it's a good practice to have it separated by dots.

  • If you are saving a project in the maven repository (local or global), each word separated by a dot will act as a directory. In our example project will live under com/vehicletracking.

  • In some cases, a company can also group all of its projects under an organization. e.g., If there is an XYZ company, and this company wants to have all projects under the same group, it may use com.XYZ.vehicletracking as a groupId.


artifactId:

  • artifactId is the name of services or modules associated with the project.

  • In our example, vehicle-onboarding-service, vehicle-booking-service, and admin-service will be the name of artifactId.

  • It is unique among each groupId.

  • If we are saving services in the maven repository, then the codebase for

vehicle-onboarding-service -> will live under com/vehicletracking/vehicle-onboarding-service.
vehicle booking service will live under -> com/vehicletracking/vehicle-booking-service.
admin service will live under -> com/vehicletracking/admin-service.

version:

  • It helps in maintaining different versions of any service within a project.

  • Companies can define which type of versioning they want for their projects.

  • If we version our services as 1.0, then the codebase for

vehicle-onboarding-service -> will live under com/vehicletracking/vehicle-onboarding-service/1.0
vehicle booking service will live under -> com/vehicletracking/vehicle-booking-service/1.0
admin service will live under -> com/vehicletracking/admin-service/1.0
  • It is not required to have the same versioning for each service within a project, but it is good to follow a similar naming convention.

  • Each service can be updated individually and need not have the same version as others.

groupId:artifactId:version helps us answering the 'WHO' we are dealing with be pointing to a specfic version of a service in a project.


packaging:

<packaging>pom</packaging>
  • It helps us in answering 'WHAT' we are dealing with.

  • Usually, there are two types of packaging system jar and war.

  • So, 'WHAT' is the type of project packaging.

  • The default value of packaging is a jar.

  • Apart from jar and war, there are other types of packing as well. e.g., pom, jar, maven-plugin, ejb, war, rar.


dependencies:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
    <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>
        <type>jar</type>
        <optional>true</optional>
        <version>3.14</version>
    </dependency>
    ...
</dependencies>
...
</project>

  • It is the backbone of a POM.

  • It helps us in defining all dependencies of projects.

  • Maven downloads all dependencies during build/test/validation/other goals.

  • If the dependency you are defining depends on another dependency, then maven will automatically pull those dependencies.

  • Each dependency can be defined using the following tags:

  • groupId: It is the groupId of the dependency.

  • artifactId: It is the artifactId of the dependency.

  • scope: Scope of dependency means during which goal this dependency is required. It can take the test, runtime, provided, system, and test as a value.

  • exclusion: We can define any dependency within this tag to specify that we don't want this transitive dependency.

  • type: It means that in the type of packaging of the dependency.

  • optional: We can set the value to false if the dependency is optional.

  • version: It defines the specific version of the dependency we want to have in our project.

  • Check out this blog to learn how spring manages dependencies.


depenencyManagement:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>azure-spring-boot-bom</artifactId>
            <version>${azure.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

  • It helps in propagating the information of dependencies to all of its children.

  • We specify the dependency and its version in parent pom, and all of its child poms will inherit the same version.

modules:

<modules>
    <module>lib/logging</module>
    <module>lib/security</module>
    <module>lib/exception</module>
    <module>backend-starter</module>
    <module>lib/api-docs</module>
    <module>lib/utility</module>
    <module>lib/notification</module>
    <module>lib/file-handler</module>
    <module>application/course-service</module>
    <module>application/blog-service</module>
    <module>application/user-service</module>
</modules>

  • It will be used in multi-module spring projects, where we separate logics and different modules and then use that logic by import the module.

  • Check out this blog to learn more about the spring boot multi-module project.

properties:

<properties>
    <java.version>11</java.version>
    <azure.version>2.2.1</azure.version>
    <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
    <springfox-swagger2.version>3.0.0</springfox-swagger2.version>
    <sqlserver.version>7.4.1.jre8</sqlserver.version>
    <jsonwebtoken.version>0.10.7</jsonwebtoken.version>
    <unirest.version>3.3.00</unirest.version>
    <maven.test.skip>true</maven.test.skip