Basic Paradigms

What is POM.xml
A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used by Maven to build the project. It contains default values for most projects. Examples for this is the build directory, which is target. Super POM is Mavens default POM. All POMs extend the Super POM unless explicitly set

Maven works in two modes in Command Prompt –
Interactive Mode – Takes command one after another
Batch Mode – takes all command at once

Archetype – Archetype is the one which defines the type of project and project structure. i.e. mvn archetype generate
ArtifactID – Specifies the name of the project.
GroupID – Group Id is one by which similar products or components are tied together under one groupId
i.e.

org.springframework
org.apache
org.commons

If you don’t specify the package name during creation it will take the groupId as package name for classes.

Types of Repo
Remote Repo is of Two type – Internal and External

  1. Central Repo-is mavens own repo accessed over mvn.com
  2. External Repo– are those whose JARs are provided by organizations like IBM for DB2. Those JARs are initially not available in Central Repo.Paid drivers are not available in Central repo rather available in organizations repo
  3. Internal Repo-Internal repos are the one provided by working organization.The main goal of such repos are to provide stable JARs and avoiding downloads of unstable jar directly from Central or external repos and to avoid network traffic

Apart from the above we have one more repo called local repo.
Local Repo – Local repo is the one which we have in the development system under .m2 folder. Local repos would be holding old JARs even when you run clean command which does nothing more than cleaning .class files. Inorder to get rid of old JARs we need to purge

purge local repo

Other Notable Points

  1. Maven is intelligent when you run install it would instatiate before phases(validate,compile and test).When one java file is changed in the list of 100 only 1 file would be compiled rather than 100 files
  2. mvn install – will deploy the JAR fils in the local repo(local .m2 folder) where as mvn deploy(disabled by default) – will deploy the JAR in the remote repo(Internal Repo)
  3. mvn compile – will compile only the java files in the source folder not the java classes in the Test Folder
  4. The Scope of the dependency JARs would be PROVIDED incase you are planning to deploy your code in environment which has someother higher version of JAR than dev environment.The default scope is compile.Though scope is compile the JARS would be available till target container.
  5. If the Team has completed coding for release then the JAR files would be named as RELEASE (or) FINAL.If the Project is still under development than the JAR would be named as SNAPSHOTThis is to make other development team to understand that there would be still code changes accompanied with JAR.
  6. .m2 folder should not be created manually.When you create your first project(maven project) .M2 folder would be created on its own.

An artifact in maven is a resource generated by a maven project. Each maven project can have exactly one artifact like a jar, war, ear, etc.Each maven project has a unique identifier consiting of [groupId, artifactId, version]. When a maven project requires resources of another project a dependency is configured in it’s pom.xml using the above-mentioned identifier. Maven then automatically resolves the dependencies when a build is triggered. The artifacts of the required projects are then loaded either from the local repository, which is a simple directory in your user’s home, or from other (remote) repositories specified in you pom.xml.

Now the once mvn install is done the same snapshots are available in repository location as below

A snapshot version in Maven is one that has not been released.

The idea is that before a 1.0 release (or any other release) is done, there exists a 1.0-SNAPSHOT. That version is what might become 1.0. It’s basically “1.0 under development”. This might be close to a real 1.0 release, or pretty far (right after the 0.9 release, for example).

The difference between a “real” version and a snapshot version is that snapshots might get updates. That means that downloading 1.0-SNAPSHOT today might give a different file than downloading it yesterday or tomorrow.

Usually, snapshot dependencies should only exist during development and no released version (i.e. no non-snapshot) should have a dependency on a snapshot version.

The snapshot is not necessarily more stable: it is just the latest build. The snapshot precedes the actual release, it does not come after it. Indeed, version numbers typically do not refer to branches

When you build an application, Maven will search for dependencies in the local repository. If a stable version is not found there, it will search the remote repositories (defined in settings.xml or pom.xml) to retrieve this dependency. Then, it will copy it into the local repository, to make it available for the next builds.

For example, a foo-1.0.jar library is considered as a stable version, and if Maven finds it in the local repository, it will use this one for the current build.

Now, if you need a foo-1.0-SNAPSHOT.jar library, Maven will know that this version is not stable and is subject to changes. That’s why Maven will try to find a newer version in the remote repositories, even if a version of this library is found on the local repository. However, this check is made only once per day. That means that if you have a foo-1.0-20110506.110000-1.jar (i.e. this library has been generated on 2011/05/06 at 11:00:00) in your local repository, and if you run the Maven build again the same day, Maven will not check the repositories for a newer version.

Maven provides you a way to can change this update policy in your repository definition:

<repository>
    <id>foo-repository</id>
    <url>...</url>
    <snapshots>
        <enabled>true</enabled>
        <updatePolicy>XXX</updatePolicy>
    </snapshots>
</repository>

where XXX can be:

always – Maven will check for a newer version on every build;
daily – the default value;
interval:XXX – an interval in minutes (XXX)
never – Maven will never try to retrieve another version. It will do that only if it doesn’t exist locally. With the configuration, SNAPSHOT version will be handled as the stable libraries.

Updating Maven Snapshots are helpful during development where the maven first looks for local version of snapshot and adds to working set but still we get a build error we can force update snapshots which gets the snapshots from the repository

What is difference between Eclipse Project -> Clean and mvn clean?

Eclipse project clean is only clearing out the folders that are set as output folder in the project’s preferences.It Deletes previously generated Eclipse files (like .project and .classpath and .settings) and then generates new ones, thus, effectively updating them.

It may be useful if you introduced some changes in pom.xml

mvn clean command deletes target directory and then builds all you code and
installs artifacts into local repository.

What Maven update Project Does?

It syncs the Eclipse project settings with that of the pom. If you for example change important plugin settings, such as the output java version, you will find that Eclipse will ask you to update the project and afterwards the configured Java runtime in the project will have changed to reflect what your Maven pom indicates.

  1. That is an important thing to keep in mind: the Maven pom is the lead in this kind of project setup. If you want settings to change, try to do that through the pom and not through Eclipse project settings directly or doing a project update might revert what you have changed. There are usually some things I have to correct myself anyway though, such as build path exclusions that m2eclipse likes to put in and strange deployment assembly configurations.
  2. Update Project also provides more options such as Force Update of Snapshots / Releases which is extremely helpful when you have dependencies that are looking for the latest. (e.g.: [1.0) will find 1.0.* – whatever’s the latest.)

Two types of Maven dependencies
Direct: These are dependencies defined in your pom.xml file under the section.
Transitive: These are dependencies that are dependencies of your direct dependencies.

What are dependencies with provided scope meant to?
Either be excluded from the final artifact (for example, for war files you would not want to include servlet-api, servlet-jsp, etc) since the server itself has the servlet related jar files

Difference Between Update Snapshots and Update Dependency
By default Maven is supposed to update snapshots once a day.Specific dependency is determined using group, name and version. These attributes can be identical for two different snapshots. Maven uses the latest snapshot based on internal time stamp.

what is the difference between classpath and build path?
The classpath is the conventional way to tell the Java compiler and the Java runtime where to find compiled classes.The class path is used at runtime to load compiled classes and resources.

The build path is used for building your application. It contains all of your source files and all Java libraries that are required to compile the application.The IDE uses this to figure out the classpath and sourcepath for compiling the Java code.The build path is used at compile time to find the dependencies needed to build your project.

For example, an Eclipse build path for a project includes the other projects that it depends on, and lists any additional library JARs that the project contains / relies on. It also lists the packages in the current project that downstream projects can depend on.

If you are using Maven for your project, the IDE buildpath mechanism is secondary to the dependencies declared in the POM files. For example, using Eclipse with the m2eclipse, the buildpath is synthesized from the POM files.

What is .project and .classpath files in Eclipse
The .project file is maintained by the core Eclipse platform, and its goal is to describe the project from a generic, plugin-independent Eclipse view.When a project is created in the workspace, a project description file is automatically generated that describes the project. The sole purpose of this file is to make the project self-describing, so that a project that is zipped up or released to a server can be correctly recreated in another workspace.

.classpath Classpath specifies which Java source files and resource files in a project are considered by the Java builder and specifies how to find types outside of the project. The Java builder compiles the Java source files into the output folder and also copies the resources into it.

what mvn eclipse:eclipse does
Sometimes the dependencies don’t update even with Maven->Update Project->Force Update option checked using m2eclipse plugin.

mvn eclipse:eclipse

This will update your .classpath file with the new dependencies while preserving your .project settings and other eclipse config files.

If you want to clear your old settings use


mvn eclipse:clean
mvn eclipse:eclipse

mvn eclipse:clean will erase your old settings, then mvn eclipse:eclipse will create new .project, .classpath and other eclipse config files

What is Maven artifact?
An artifact is a file, usually a JAR, that gets deployed to a Maven repository.

Maven is based around the central concept of a build lifecycle.
There are three built-in build lifecycles

There are three lifecycle phases in maven

  1. clean
  2. build (default)
  3. site

You can Either trigger a phase or goal in maven

When the clean lifecycle is called it has three phases internally.For example, the clean life cycle has 3 phases (pre-clean, clean, post-clean).

For example the default lifecycle comprises of the following Build Phases:

◾validate – validate the project is correct and all necessary information is available
◾compile – compile the source code of the project
◾test – test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
◾package – take the compiled code and package it in its distributable format, such as a JAR.
◾integration-test – process and deploy the package if necessary into an environment where integration tests can be run
◾verify – run any checks to verify the package is valid and meets quality criteria
◾install – install the package into the local repository, for use as a dependency in other projects locally
◾deploy – done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

So to go through the above phases, we just have to call one command:

>> mvn

i.e

>> mvn install

For the above command, starting from the first phase, all the phases are executed sequentially till the ‘install’ phase. A command can be used in a multi-module scenario mvn clean install.

A Build Phase is Made Up of Plugin Goals
Most of Maven’s functionality is in plugins. A plugin provides a set of goals that can be executed using the following syntax:

mvn [plugin-name]:[goal-name]

For example, a Java project can be compiled with the compiler-plugin’s compile-goal by running mvn compiler:compile

Build lifecycle is a list of named phases that can be used to give order to goal execution.

Goals provided by plugins can be associated with different phases of the lifecycle

mvn test

When the preceding command is executed, Maven runs all goals associated with each of the phases up to and including the test phase. In such a case, Maven runs the resources:resources goal associated with the process-resources phase, then compiler:compile, and so on until it finally runs the surefire:test goal.

A goal not bound to any build phase could be executed outside of the build lifecycle by direct invocation. The order of execution depends on the order in which the goal(s) and the build phase(s) are invoked. For example, consider the command below. The clean and package arguments are build phases, while the dependency:copy-dependencies is a goal (of a plugin).

mvn clean dependency:copy-dependencies package

If this were to be executed, the clean phase will be executed first (meaning it will run all preceding phases of the clean lifecycle, plus the clean phase itself), and then the dependency:copy-dependencies goal, before finally executing the package phase (and all its preceding build phases of the default lifecycle).

Furthermore, a build phase can also have zero or more goals bound to it. If a build phase has no goals bound to it, that build phase will not execute. But if it has one or more goals bound to it, it will execute all those goals.

The image showing various plugins goals used for different phase during execution.To take the other way round plugins executing goals at different phases.

Maven is a “build management framework”

You could define how your .java files get compiled to .class, packaged into .jar (or .war or .ear) files, (pre/post)processed with tools, managing your CLASSPATH, and all others sorts of tasks that are required to build your project.

 Though it doesn’t give fine grain control like  Apache Ant or Gradle or Makefiles in C/C++, but it attempts to be completely self-contained in it that you shouldn’t need any additional tools or scripts by incorporating other common tasks like downloading & installing necessary libraries etc.

It is also designed to around “build portability” so that you don’t get issues as having the same code with the same buildscript working on one computer but not on another one (this is a known issue, we have VMs of Windows 98 machines since we couldn’t get some of our Delphi applications compiling anywhere else). Because of this, it is also the best way to work on a project between people who use different IDEs since IDE-generated Ant scripts are hard to import into other IDEs, but all IDEs nowadays understand and support Maven.

There are few inflexibility in maven and some developers stick with Ant or similar, but a growing number of them are people who have moved on to Maven successors such as Gradle and Buildr. These successors inherit from Maven the idea of providing a powerful set of build steps out of the box, but make it immensely easier to add custom steps too.

How to Run a Java file from ANT Script

 <java classname="com.mugil.tutor.Sample">
   <classpath path="test/classes/"></classpath>
 </java>

Where Sample points to Sample.class which we got through compilation and test/classes/ contains the Sample.class file. Below is the whole code in build.xml file

<project name="ANT2" default="copyTarget">
  <target name="copyTarget">
  <mkdir dir="test/classes/"/>
  <javac srcdir="src/com/mugil/tutor/" destdir="test/classes/" includeantruntime="false"></javac>
    <java classname="com.mugil.tutor.Sample">
  	<classpath path="test/classes/"></classpath>
     </java>
   </target>
</project>

How to get Current time in ANT Script

 <project name="default" default="target1">
     <target name="target1">		
	<tstamp>
	   <format property="current.time" pattern="yyyyMMdd" />
	   <format property="archive.name" pattern="'MyArchive_'yyyyMMdd_hh:mmaa'.jar'" />
	</tstamp>
	<echo>${current.time}</echo>
	<echo>${archive.name}</echo>		
     </target>
</project>

ANT Script to concatenate two variables and Create directory based on that

<project name="default" default="target1">
  <property name="mugil.dir" value="D:/Mugilvannan/"/>		
     <target name="target1">		
	<tstamp>
	  <format property="current.time" pattern="yyyyMMdd" />
	  <format property="archive.name" pattern="'MyArchive_'yyyyMMdd_hhmmaa" />
	</tstamp>
	<property name="whole.dir" value="${mugil.dir}${archive.name}"/>
	  <echo>
	    ${whole.dir}
	  </echo>		
	<mkdir dir="${whole.dir}"></mkdir>
     </target>
</project>
Posted in ANT.

Error

warning: ‘includeantruntime’ was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds

Reason
It is caused by a misfeature introduced in Ant 1.8

Include attribute includeantruntime and set it to false as shown below

Solution 1

 <javac .... includeantruntime="false" .../>  

Solution 2
In case if your project contains many build.xml files which one cannot, or prefers not to, edit
Use presetdef add these lines in top of build.xml file

 <presetdef name="javac">
    <javac includeantruntime="false" />
  </presetdef>

If your projects do actually need ant runtime libraries, you can either add them explicitly to your build files OR set includeantruntime=”true”

<javac destdir="out" includeantruntime="true">
  <src path="foo.java" />
  <src path="bar.java" />
</javac>

Now all subsequent javac tasks will essentially inherit includeantruntime=”false”

For working with ant you need to first set the path of the environment variables.I am going to do this in command prompt by executing the following line in command prompt as follows

STEP 1
I should set the Path for Java Directory and for ant bin directory as above.

 C:\Users\Mugil>set PATH=D:\Java\jdk1.6.0_32\bin;D:\Mugil\apache-ant-1.9.0\bin;

STEP 2
Now I should create a build.xml file which the ant looks for deployment as follows
build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="codethataint" default="default target">
 <target name="default target">
  <echo>
   Executing Default Target
  </echo>
 </target>
</project>

STEP 3
To run the ant file use the following line in command prompt as below

 d:\Mugil\staging>ant

In build.xml is a ANT Script that starts with root node project.
Project will have set of Targets
Targets will have set of Tasks

What if I named my build file to some other name other than build.xml say build2.xml
In such case you can use the below command as follows

 d:\Mugil\staging>ant -buildfile 

What if I want to run a different target

build2.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="codethataint" default="default target">
 <target name="default target">
  <echo>
   Executing Default Target
  </echo>
 </target>
 <target name="target 2">
  <echo>
    Target 2 
  </echo>
 </target>
</project>
 d:\Mugil\staging>ant -buildfile  "target 2"

You can enforce dependency in ANT script by using depends keyword as in the following script below

<?xml version="1.0" encoding="UTF-8"?>
<project name="codethataint" default="target2">
 <target name="target1">
  <echo>
   Target 1
  </echo>
 </target>
 <target name="target2" depends="target1">
  <echo>
   Target 2
  </echo>
 </target>
</project>

When you run the ANT script you will see Target 1 and Target 2 displayed on the Screen.Though the default target is target2 since it depends on target1 both are getting displayed.

If there are two targets which depends on each other then circular dependency will occur

<?xml version="1.0" encoding="UTF-8"?>
<project name="codethataint" default="target2">
 <target name="target1" depends="target2">
 .
 .
 <target name="target2" depends="target1">
 .
 .

Creating a Folder using build.xml

 <?xml version="1.0" encoding="UTF-8"?>
 <project name="ANT1" default="makedir"> 
 <property name="build.dir" location="D:\build"/> 
  <target name="makedir">
   <mkdir dir="${build.dir}" /> 
  </target>
 </project>

Before you are making a Folder you need to clean it as below

<?xml version="1.0" encoding="UTF-8"?>
<project name="ANT1" default="makedir"> 
 <property name="build.dir" location="D:\build"/>
 <target name="clean">
  <delete dir="${build.dir}"/>
 </target> 
 <target name="makedir" depends="clean">
  <mkdir dir="${build.dir}" /> 
  <mkdir dir="${build.dir}/classes"/>
 </target>
</project>

Below is a Simple java project which uses an ANT script and creates three folder build.The build contains classes and jar folder.The compiled class files will sit in classes folder and jar files will sit in jar folder.

<?xml version="1.0" encoding="UTF-8"?>
<project name="ANT1" default="makejar" basedir=".">
<property name="src.dir" location="src"/>
<property name="build.dir" location="D:\build"/>
<property name="project.name" value="ANT1"/>
<target name="clean">
 <delete dir="${build.dir}"/>
</target> 
<target name="makedir" depends="clean">  
 <mkdir dir="${build.dir}" />  
 <mkdir dir="${build.dir}/src/classes"/>
</target>
<target name="compile" depends="makedir">
  <javac srcdir="src" destdir="${build.dir}/src/classes" includeantruntime="false"/>
 </target>
<target name="makejar" depends="compile">
  <jar destfile="${build.dir}/jars/${project.name}.jar" basedir="${build.dir}/src/classes" />  
</target>
</project>

Project Java File – Sample.java

package com.mugil.tutor;

public class Sample 
{
  public static void main(String[] args) 
  {
    System.out.println("Its working...!"); 
  }
}

Once you run an ANT script it does the following task as below
1.Target Clean – Deletes the folder build
2.Target makedir – Creates two directory build and Classes
3.Target compile – Compiles code and puts in classes folder as specified in destdir
4.Target makejar – Creates the JAR file as specified in the jar tag

  • You can see in the above code src.dir is given location as src which takes the src folder relative to the folder in which the build.xml exists.
  • In the line above absolute path is used for build.dir as D:\build

Copying folder from one Location to Another

<target name="makecopy">	
  <copy todir="D:/build/web">
   <fileset dir="WebContent">
   </fileset> 
  </copy>
</target>

The above code copies the content in from WebContent folder to D:/build/web

Simple Copying of File from one directory to another

<project name="ANT2" default="copyTarget" basedir=".">
 <target name="copyTarget">
   <copy file="WebContent/index.jsp" tofile="D:/build/mugil/index2.jsp"/>
  </target>
</project>

Above I am copying a file index.jsp into location D:/build/mugil/ and saving it as index2.jsp

If you want to copy the file and Save it in to directory use the below code

 <copy file="WebContent/index.jsp" todir="D:/build/mugil/"/>

If there is no folder then folder will be created before copying file

Excluding certain type of files while copying
Now I want to exclude certain types of files from get copied say XML files.

 <target name="copyTarget">
  <copy todir="D:/build/web">
    <fileset dir="WebContent">
      <exclude name="*.xml"/>
    </fileset> 
  </copy>
 </target>

The above code excludes XML file in current folder from getting copied.Now what if i want the XML files in the sub folder from getting copied

 <target name="copyTarget">
  <copy todir="D:/build/web">
    <fileset dir="WebContent">
      <exclude name="**/*.xml"/>
    </fileset> 
  </copy>
 </target>

** is going to look for files in sub folder and excludes those from getting copied.

How to pack files into Zip

<zip destfile="D:/build/web/zip/Sample.zip">
 <fileset dir="WebContent"/>
</zip>

The above code creates a Zip file with contents in WebContent

Note:
Never hard code version numbers and folder location in build.xml as they are constantly updated over a period of time.You can create a separate file where you can put your version numbers and replace it as properties in build.xml file as shown below

build.properties
appversion=1.0

build.xml

 <project name="ANT2" default="copyTarget">
   <property file="build.properties"/>
     <target name="copyTarget">
   	    <echo>${appversion} </echo>
     </target>
 </project>

OP:1.0

Now I am going to add directory name in build.properties file as below

build.properties
dest.dir=D:\\NewFiles

The above code creates a folder in D drive with name NewFiles

Why Double Backward slash?
If you are not giving double backward slash then it will take absolute path and creates folder in project work space

Is there any other way I define my folder path?
Yes.you can define it by absolute path by using forward slash as below.

build.properties
dest.dir=D:/NewFiles

ANT properties are Immutable
Now consider the below code.

build.properties
appversion=1.1

<project name="ANT2" default="copyTarget">
  <property file="build.properties"/>
  <property name="appversion" value="1.0"/>
  <target name="copyTarget">
     <echo>${appversion} </echo>
  </target>
</project>

In line 2 I am getting the appversion value set to 1.1. Later I am trying to redefine the same property by setting the value of the attribute to 1.0.But if you print the value using echo statement you can see 1.1 getting printed on console

OP:1.1

Hence ANT Properties are immutable.

Now you want to dynamically make changes in build.properties file on fly.

 <project name="ANT2" default="copyTarget">
   <property   file="build.properties"/>
     <propertyfile   file="build.properties"  comment="My properties">
       <entry  key="appversion" value="1.3"/>
     </propertyfile>	
     <target name="copyTarget">
       <echo>${appversion} </echo>
     </target>
 </project>

In build.properties file appversion value is set to 1.1.But by using propertyfile tag i am resetting the value to 1.3.This Change will also be made in the original build.properties file.So next time when you open build.properties you can note the appversion value got changed to 1.3 and time of change as commented text.

Posted in ANT.