Introduction to the POM
A Project Object Model or POM is a fundamental unit of work in Maven. It is an XML file that contains not only the information about the project but also the configuration details used by Maven to build a project.
When executing a task or goal, Maven looks for the POM in the current directory; it reads the POM, gets the needed configuration information, and then executes the goal.
Before maven 2, the XML file was named project.xml. Since maven 2, it is renamed as pom.xml.
Note: In a POM, there are some default values considered for example the build directory is target, similarly the source directory is src/main/java, the test source directory is src/test/java, and so on. The path's considered in each default value is a relative path given in accordance with the POM location.
POM Elements
Following are the bare minimum elements/tags required to create a POM:
Element
|
Description
|
project
|
Specifies the project
root tag where you need to specify the basic schema settings such as apache
schema and w3.org specification
|
modelVersion
|
Specifies the model version which should be
set to 4.0.0
|
groupId
|
Specifies the id of the
project's group. This is generally unique amongst an organization or a
project
|
artifactId
|
Specifies the id for the artifact. An
artifact is either produced or used by a project, for example: JARs, source
and binary distributions, and WARs
|
version
|
Specifies project version which when used
alongside groupId, in the repository, separates different version
|
Note: Along with the groupId, the artifactId defines the artifact's location within the repository which when combined with version separates multiple version of the same artifact. For example:
<groupId>:<artifactId>:<version>
com.coding.anomaly:anomaly-detection:1
com.coding.anomaly:anomaly-detection:2
Following is an example of a POM having bare minimum elements/tags:
<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.coding.anomaly</groupId> <artifactId>anomaly-detection-app</artifactId> <version>1</version> </project>
|
Custom Parent POM
A Custom Parent POM can be used in conditions where you have multiple projects which refer to same set or sub set of dependencies. A Custom Parent POM can be considered as a common place to provide dependencies, properties and so on.
Let us consider an example of how a custom parent POM can be used.
Consider following folder structure:
| - - anomaly-detector | `- - implementation | `- - anomaly-detector-app | `- - pom.xml | `- - pom.xml
|
In the example above, consider the POM under implementation to be parent POM and the one under anomaly-detector-app to be a child POM.
Following will be the configuration for both the POM's
Parent POM
<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.coding.anomaly</groupId> <artifactId>anomaly-detection-parent</artifactId> <version>1</version> </project>
|
Child POM
<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> <parent> <groupId>com.coding.anomaly</groupId> <artifactId>anomaly-detection-parent</artifactId> <version>1</version> </parent> <groupId>com.coding.anomaly<groupId>
<artifactId>com.coding.anomaly</artifactId>
<version>1</version> </project>
|
In the example above, we have added a section <parent> which allows us to specify the parent POM. The other information we need to provide is the groupId, artifactId and the version of the parent POM. Including a parent section in the POM allows the POM to inherit almost all the properties of the parent POM.
The above works considering that the parent POM is placed just one directory above the child POM directory.
Note: If you want to have the groupId or version of the child POM to be same as that of the parent, you can simply do it by removing the groupId or version tag from the child POM.
Child POM
<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> <parent> <groupId>com.coding.anomaly</groupId> <artifactId>anomaly-detection-parent</artifactId> <version>1</version> </parent> <artifactId>anomaly-detection-app</artifactId> </project> |
|
Similarly, if the parent POM is in a directory other than one directory above child POM, the following tag needs to be added:
Consider following folder structure:
| - - anomaly-detector | `- - implementation | `- - anomaly-detector-app | `- - pom.xml | `- - parent | `- - pom.xml |
Child POM
<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> <parent> <groupId>com.coding.anomaly</groupId> <artifactId>anomaly-detection-parent</artifactId> <version>1</version> <relativePath>../parent/pom.xml</relativePath> </parent> <artifactId>anomaly-detection-app</artifactId> </project>
|
The relative path provided in the above example is in respect to that of child POM.
Build multiple modules using a single parent POM
A module can be considered as a directory that consists of a POM. Maven provides way's to build multiple modules using a single parent POM. In such cases, when we run Maven command against a parent POM, the modules specified will also be built. Hence to build multiple POM, we now need to run Maven command on one single parent POM, which in turn builds the required child POM.
Consider following folder structure
| - - anomaly-detector | `- - implementation | `- - anomaly-detector-app | `- - pom.xml | `- - pom.xml |
|
Parent POM
<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.coding.anomaly</groupId> <artifactId>anomaly-detection-parent</artifactId> <version>1</version> <modules> <module>anomaly-detection-app</module> </modules> </project>
|
In the example above, the tag <modules> specifies a collection of modules/directories that are to be built when Maven command is run against this parent POM. Each directory name, consisting of a POM, can be specified under the tag <module>.
If the parent POM is residing in some other directory, the following can still be achieved as specified:
Consider following folder structure
| - - anomaly-detector | `- - implementation | `- - anomaly-detector-app | `- - pom.xml | `- - parent | `- - pom.xml
|
Parent POM
<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.coding.anomaly</groupId> <artifactId>anomaly-detection-parent</artifactId> <version>1</version> <modules> <module>../anomaly-detection-app</module> </modules> </project>
|
Variables/Properties
Maven provides ways to define variables/properties inside a POM and use it across the same POM or child POM. This helps in reducing the same text across the POM and provides a single place to make changes in future.
There are special variables that can be referenced using the prefix "project." for example: ${project.groupId}, ${project.version} and so on.
Refer to POM reference to get list of other such variables.
Note: There are other variables prefixed with pom. or without pom. which are now deprecated.
To define our own variables which can be used across the POM, a tag named <properties> can be used. Properties tag is a collection of user-defined variables that can be used across the POM.
Following is the way to define and use a user variable/property:
<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"> .... <properties> <mavenVersion>4.0</mavenVersion> </properties> <dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-artifact</artifactId> <version>${mavenVersion}</version> </dependency> </dependencies> .... </project>
|
Note: A variable/property defined in parent POM can be used in child POM.
Parent POM
<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.coding.anomaly</groupId> <artifactId>anomaly-detection-parent</artifactId> <version>1</version> <properties> <mavenVersion>3.0</mavenVersion> </properties> <modules> <module>anomaly-detector-app</module> </modules> <dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-artifact</artifactId> <version>${mavenVersion}</version> <packaging>pom</packaging> </dependency> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-core</artifactId> <version>${mavenVersion}</version> </dependency> </dependencies> </project>
|
Child POM
<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> <parent> <groupId>com.coding.anomaly</groupId> <artifactId>anomaly-detection-parent</artifactId> <version>1</version> <relativePath>../parent/pom.xml</relativePath> </parent> <artifactId>anomaly-detection</artifactId> <dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-core</artifactId> <version>${mavenVersion}</version> </dependency> </dependencies> </project>
|
Conclusion
From the points specified above, we can conclude that POM defines a structured and robust way to define dependencies, properties, and so on to ease the way to build a project.
Running a maven command from a specific POM location will build the POM along with downloading the specified dependencies and creating the package.
References
0 Comments