Pages

Tuesday, November 5, 2013

Maven 101: Day 2: Understanding POM

Goto Prev: Day 1: Install and Setup                          Goto : Next: Compile, Test, Pckg,Inst


This is Day 2 of my maven journey. On Day 1, I setup maven on my laptop and created a maven project.
I also tried to understand the basics of the command that I used to create the maven project.

Today I plan to understand the basics of POM.

I am going back to my trusted Apache Maven Tutorial as a guide.

Introduction to POM- Project Object Model

This is an XML file that contains the project and configuration details required by Maven to build the project. You can specify project dependencies, plugins that would be used and information like version, description etc. When we execute a maven goal, Maven looks for the POM in the current directory, it reads the POM to get all required information to execute the goal.


Maven has a default POM, this POM is called the Super POM, all POMs extend the super POM unless explicitly set. The Super POM has meaningful default configurations and these configurations are inherited by the POMs created in a project. Here is a snippet from the Maven 2.1.x super POM, this snippets show the Super POM contains default values for some common directories:

 <directory>${project.basedir}/target</directory>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
 
 
One good thing about inheriting default is that you only have to specify a handful of things in your project's POM and rely on Super POM for the rest. The minimum required values for a project POM are as follows:
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gsm.app</groupId>
  <artifactId>namaste</artifactId>
  <version>1.0-SNAPSHOT</version>
</project>


project: This is the top level element of all pom.xml files
modelVersion : This is the version of the object model used by this POM. Not something I as a beginner would worry about. I plan to go with what ever the skeleton archetype gives me.
groupId : The unique identifier of the organization that created the project.
artifactId : The unique name of the primary artifact
version : The version of the artifact generated by the project.

This minimal pom does not require you to specify a packaging type, it uses the default value , which would be "jar".

For a project built with the above minimal POM the out put would be a jar file named as follows:
namaste-1.0-SNAPSHOT.jar

Since the above POM does not specify repositories it will download any required files (dependencies)
from the default maven repository http://repo.maven.apache.org/maven2.
It inherits this value from the Super POM.


Parent Project

Please don't quote me on my description of a Parent Project , but from what I gathered. Parent projects can be used at least in these two contexts:
 
Inheritance: If you have several Maven projects with similar configurations, you can pull the similar configurations our and make a parent project. You then specify this common project as the parent project for the rest of your Maven projects and the child projects would inherit all the parent project configurations.

Aggregation: If you have a group of projects that always need to be  built together, you can create a parent project and declare all the required projects as its modules. You then build only the parent project and the rest will get built automatically.

You can use either Inheritance or Aggregation or both as long as :
  • Every Child POM has a reference to its Parent POM
  • Parent Poms packaging is set set to "pom"
  • Parent POM has references to its child modules' directories


So if our project Namaste is now a parent project of project Smile. And the directory structure is:

  • Namaste
    • pom.xml
  • Smile
    • pom.xml
Here is how their pom.xml files would look.
Namaste:

*Using Aggregation, ie build Namaste and Smile builds along with it.
 
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gsm.app</groupId>
  <artifactId>Namaste</artifactId>
  <version>1</version>
  <packaging>pom</packaging>

  <modules>
    <module>../smile</module>
  </modules>
</project>
Smile:
 *Using Inheritance to inherit properties from Namaste

<project>
  <parent>
    <groupId>com.gsm.app</groupId>
    <artifactId>namaste</artifactId>
    <version>1</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent> 
 <modelVersion>4.0.0</modelVersion>
 <version>1</version> 
 <groupId>com.gsm.app</groupId>
 <artifactId>smile</artifactId>
 </project>
 
If we want to use the same version number or group ID as the parent, we have the option of leaving that out in the child pom. Thus the child pom will look something like this:

<project>
  <parent>
    <groupId>com.gsm.app</groupId>
    <artifactId>namaste</artifactId>
    <version>1</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>smile</artifactId>
</project>


POM Variables/Properties

You can use predefined or user defined variables, the idea is to specify the value for the variable once and reference it everywhere else.
Any  single valued element in the model can be referenced as a variable. So if you need to access the value of the  groupId you would access it as ${project.groupId}, sourcedirectory would be
${project.build.sourceDirectory}.

You also get ready made variables that you can be used, For ex.
${project.basedir} : gives you the current directory of the project

You can define properties and use them as a variable later in the pom.


 Important point to note is that the variables are processed after inheritance and thus child values will override parent values.



Goto Prev: Day 1: Install and Setup                             Goto : Next: Compile, Test, Package Install                                                                                             

No comments:

Post a Comment