Used to perform a release of a project with Maven.

Key goals in mvn release Plugin

  1. release:clean Clean up after a release preparation.
  2. release:prepare Prepare for a release in SCM(Source Code Management i.e. nexus).
  3. release:rollback Rollback a previous release.
  4. release:perform Perform a release from SCM.

Prerequisite
Since this plugin releases artifacts(could be JAR’s, ZIP’s WAR’s or TAR’s) into the repository we need to make sure
credentials are properly configured in settings.xml in the conf folder, Maven installation directory. Failing to do so would
end up in authorization error while running the goals in the plugin

Syntax

>>mvn release:clean release:prepare
>>mvn release:perform

How it Works

  1. Once you run release:clean it would clean the old class files just like maven clean
  2. When you run release:prepare it would read the pom.xml in the project. If you don’t have snapshot version defined you would end up with snapshot not found error since the
    plugin assumes snapshot is the one which needs to be released.
  3. Now on running release:prepare will ask for the name of the version and will change the line snapshot in pom.xml. It also does a git push of pom.xml in the remote repo
  4. When you run release:perform it will push the jar in the nexus repo so it would be available for other teams.
  5. When you are working on App-Model-0.0.1-SNAPHSOT using mvn:prepare and mvn:perform would put App-Model-0.0.1 in repo at the same time modifying pom.xml in local and git to 0.0.2-SNAPSHOT. So the dependent project needs to be updated likewise

Other know issues:
Sometime the release:perform fails because it complains tag already exists in repo. In such a case, you need to delete the tags and perform release again.
During the release, the list of files that needs to go along release would be tagged to particular version. In some cases, there would be files with the same tag name. In such case, maven-plugin complains the tag already exists.

To get the recent Tag

//Recent Tags
git describe --tags

//Latest Tags - With --abbrev=0 it should return closest annotated tag
git describe --abbrev=0

To delete the tag
git fetch is needed to get the remote tags to be displayed in local, kind of refresh

 
//To delete tag locally
git tag -d TAG_NAME  

git fetch

//To delete tag remote
git push --delete origin TAG_NAME

To get the Latest tags for different commits done across various branches

 
git describe --tags $(git rev-list --tags --max-count=1)

There would be scenarios where you need to skip few modules when building parent project because the unit test fail in child project. In such scenario we should define the surefire plugin at parent pom.xml and include and exclude the child modules for which the unit test should be executed.

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.4.2</version>
        <configuration>
          <skipTests>true</skipTests>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

Rather than defining plugin(in our case surefire plugin), we can create a profile and define the behavior of plugins within the profile.

<project>
  [...]
  <profiles>
    <profile>
      <id>noTest</id>
      <activation>
        <property>
          <name>noTest</name>
          <value>true</value>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.4.2</version>
            <configuration>
              <skipTests>true</skipTests>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
  [...]
</project>

Now lets include and exclude child modules for which unit test should be carried out

Including Unit Test
Only the following(ChildModule3.java) file would be included and others would be excluded

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M4</version>
        <configuration>
          <includes>
            <include>ChildModule3.java</include>
          </includes>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

Excluding Unit Test
Only the following(ChildModule1.java, ChildModule2.java) file would be excluded

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M4</version>
        <configuration>
          <excludes>
            <exclude>**/ChildModule1.java</exclude>
            <exclude>**/ChildModule2.java</exclude>
          </excludes>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

How to activate profile in command prompt

>>mvn clean install -PnoTest

How to see list of active Profiles

>>mvn help:active-profiles

If you want to know what version of an specific plugin you have installed you can do this:

mvn -Dplugin=org.codehaus.mojo:wagon-maven-plugin help:describe
mvn -Dplugin=groupId:artifactId help:describe
mvn help:effective-pom

How to execute life cycle task using specific plugin

>>mvn groupID:artifactID:version:goal
>>mvn org.apache.maven.plugins:maven-checkstyle-plugin:2.5:checkstyle

This is caused by setting something too large on a 32-bit HotSpot vm, for example:If you have running the x86 JVM instead of the 64 bit you may end up with this issue

While running Maven Sure fire plugin you may endup with this problem mostly when you are using 32 bit version of Java

org.apache.maven.plugins
maven-surefire-plugin
2.7.2

-Xms1024m -Xmx1024m -XX:MaxPermSize=512m
 set "JAVA_OPTS=-Xms512m -Xmx512m -XX:MaxPermSize=512m


The MaxPermSize allowed is 512m, but it still throws error when you try to run a build setting to max of 512m.

Set MaxPermSize less than 500m

Solution

 set "JAVA_OPTS=-Xms512m -Xmx400m -XX:MaxPermSize=512m

This may also happen if maven is not using the right JVM if more that one JVM is installed in the system or set MAVEN_OPTS = -Xmx512m -XX:MaxPermSize=128m

parent-pom.xml

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8</version>
    </dependency>
 </dependencies>
</dependencyManagement>

child-pom.xml

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
 </dependencies>

Two Main Differeneces

  1. Dependency Management allows to consolidate and centralize the management of dependency versions without adding dependencies which are inherited by all children. This is especially useful when you have a set of projects (i.e. more than one) that inherits a common parent.Another extremely important use case of dependencyManagement is the control of versions of artifacts used in transitive dependencies.You still need to define them in the child POM to show that you are using them. They are not actually included in the child projects just because they are in in the parent POM. Enclosing dependencies in centralizes management of the version, scope, and exclusions for each dependency, if and when you decide to use it.
  2. Artifacts specified in the section <dependencies> will ALWAYS be included as a dependency of the child module(s).Artifacts specified in the section will only be included in the child module if they were also specified in the section of the child module itself. Why is it good you ask? because you specify the version and/or scope in the parent, and you can leave them out when specifying the dependencies in the child POM. This can help you use unified versions for dependencies for child modules, without specifying the version in each child module.

To sum up the above points in simple words in the parent-pom.xml if you are adding things inside tag then it would be available to the child-pom.xml. If you are adding the same thing within tag then you should manually add them to the child-pom.xml.In the child-pom.xml if the version is not specified it will take the parent-pom.xml version of the dependency as default else you can override them by specifying one in child-pom.xml

References Read It

Failure to find org.jfrog.maven.annomojo:maven-plugin-anno:jar:1.4.0 in http://myrepo:80/artifactory/repo was cached in the local repository, resolution will not be reattempted until the update interval of MyRepo has elapsed or updates are forced -> [Help 1]

The above statement tells that the artifact is cached in local repository.Now the artifact is not going to get downloaded unless it is

  1. It is forced to update from client Side
  2. Forcing from server side the expiration time

From Client Side 3 Solutions

  1. Using Maven Update to force update Snapshots(Mostly doesn’t work)
  2. Deleting the failed directory of Snapshot and forcing it to download
  3. By setting the Time interval for looking for Snapshot
    c:\Users\mugilvannan\maven\conf\settings.xml

    <profile>
      <id>nexus</id>
      <!--Enable snapshots for the built in central repo to direct -->
      <!--all requests to nexus via the mirror -->
      <repositories>
        <repository>
          <id>central</id>
          <url>http://central</url>
          <releases><enabled>true</enabled><updatePolicy>always</updatePolicy></releases>
          <snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots>
        </repository>
      </repositories>
     <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <url>http://central</url>
          <releases><enabled>true</enabled><updatePolicy>always</updatePolicy></releases>
          <snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots>
        </pluginRepository>
      </pluginRepositories>
    </profile>
    

There may be times direct access to JAR files are not allowed due to license restrictions.In such case declaring dependency in POM.xml has no effect. In such case the jar files should be manually downloaded and copied to maven local repository so while defining dependency in POM.xml it would take from mavens local repository

In Terminal

$ mvn install:install-file -Dfile={Path/ojdbc6.jar}
      -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0 -Dpackaging=jar

In my case I have downloaded the file to Downloads Directory

 mvn install:install-file -Dfile=C:\\Downloads\\ojdbc14.jar
           -DgroupId=com.oracle -DartifactId=ojdbc7 -Dversion=12.1.0 -Dpackaging=jar

On executing the above command it would be copied to maven .m2 local repository

Now the above will add the file to maven local repository.This should be followed by definition in pom.xml for dependency

<dependencies>  

  	<dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc14</artifactId>
            <version>12.1.0</version>
        </dependency>
   </dependencies>
<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

Specifying Version

      <!--Version should be 3.8.1-->
      <version>3.8.1</version>

      <!--Version should less than or up to  3.8-->
      <version>[,3.8]</version>
      
      <!--Version should less than 3.8-->
      <version>[,3.8)</version>

      <!--Version should be between 3.1 to 3.8-->
      <!--If 3.8 is available it picks those-->
      <version>[3.1,3.8]</version>

Specifying Scope


<!--Jar file would be available to JUnit Test Folder-->
<scope>test</scope>

<!--available as Part of Web Server i.e tools.jar-->
<scope>provided</scope>

<!--Jar File available only during runtime-->
<!--Use of Interface at Compile Time and actual class at runtime-->
<scope>runtime</scope>

<!--Use of Interface at Compile Time and actual class at runtime-->
<scope>runtime</scope>

Defines the Maven Plugin with which the compilation has to be carried out

<plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.6.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>

Effective POM
Tells the Details of Super POM.xml Lists default configuration.

.
.
<build>
    <sourceDirectory>D:\java\TestMvnProj2\src\main\java</sourceDirectory>
    <testSourceDirectory>D:\java\TestMvnProj2\src\test\java</testSourceDirectory>
    <outputDirectory>D:\java\TestMvnProj2\target\classes</outputDirectory>
</build>
.
.

The above XML code specify the details of sourceDirectory, outputDirectory

You can also see list of plugins called at different phases of maven life cycle.

Parent POM
List of Child Projects are added into modules as separate module.

.
.
<packaging>pom</packaging>

<modules>
<module>Service</module>
<module>Controller</module>
<module>Model</module>
</modules>
.
.

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