Monday, March 24, 2014

Moving a Maven artifact to new coordinates



Sometimes it can be necessary to move a Maven artifact to new project coordinates (groupId, artifactId, version). Fortunatly Maven does supports this use case.

Suppose the Maven project foo.bar:hello-world needs to be moved to lorem.ipsum:hello-world. foo.bar:hello-world is published and you can not remove it (from the world). So you have to describe that in case of foo.bar:hello-world the new project lorem.ipsum:hello-world should be used. This can be done by the relocation element of the Maven pom (of the old project) like this
<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>foo.bar</groupId>
  <artifactId>hello-world</artifactId>
  <version>4.5.1</version>

  <distributionManagement>
    <relocation>
      <groupId>lorem.ipsum</groupId>
      <artifactId>hello-world</artifactId>
      <version>1.0.0</version>
    </relocation>
  </distributionManagement>


</project>
The relocation element describes the new home of the artifact. So whenever some other module includes the foo.bar:hello-world dependency the build process will automatically use lorem.ipsum:hello-world.

Thus, the dendencies of a project with the following pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>test</groupId>
  <artifactId>test</artifactId>
  <version>1.0.0</version>

  <dependencies>
    <dependency>
      <groupId>foo.bar</groupId>
      <artifactId>hello-world</artifactId>
      <version>4.5.1</version>
    </dependency>

  </dependencies>

</project>
will be resolved to:
...\src\test>mvn dependency:resolve
[INFO] Scanning for projects...
[INFO]
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethrea
ded.SingleThreadedBuilder with a thread count of 1
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building test 1.0.0
[INFO] ------------------------------------------------------------------------
[WARNING] The artifact foo.bar:hello-world:jar:4.5.1 has been relocated to lorem
.ipsum:hello-world:jar:1.0.0

[INFO]
[INFO] --- maven-dependency-plugin:2.8:resolve (default-cli) @ test ---
[INFO]
[INFO] The following files have been resolved:
[INFO]    lorem.ipsum:hello-world:jar:1.0.0:compile
Of course you should pay attention to the warning and change the dependency in your project according to the new dependency coordinates. If you are not aware of the relocation this can be a pitfall in some situations.

I found out about this feature because I wanted to mark an artifact as deprecated and this was a hint on the feature request I opened (MNG-5604).

A detailed explanation of this mechanism can also be found in the Maven documentation. It is called
Guide to relocation.