[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Artifact relocation with the Maven helpers



Hi all,

I've implemented a new interesting feature in maven-repo-helper 1.9 and
maven-debian-helper 2.1, it's now possible to relocate an artifact
toward another one. This is roughly the equivalent of symlinks but for
the Maven dependencies.

For example, if the library FooBar 1.0 had the Maven coordinates
foo:bar, and the version 2.0 changed the coordinates to org.foo:bar,
it's possible to instruct Maven to redirect the dependencies on foo:bar
to org.foo:bar (if the two versions are compatible of course).

This feature has been supported by Maven for a long time and can now be
used in maven-repo-helper and maven-debian-helper by adding the
--relocate option in the debian/*.poms files. The syntax looks like this:

  pom.xml --relocate=groupId:artifactId[:version]

Multiple relocations can be specified by appending more coordinates
separated by a comma. The version is optional and defaults to 'debian'.

This mechanism can conveniently replace the maven.publishedRules files.
For example with Guava we can now do this:

  guava/pom.xml --has-package-version --java-lib
--relocate=com.google.code.google-collections:google-collect,com.google.collections:google-collections

This redirects the old com.google.code.google-collections:google-collect
and com.google.collections:google-collections dependencies to the new
one com.google.guava:guava, and the packages depending on libguava-java
no longer have to declare any rule in debian/maven.rules. Old and new
dependencies are resolved out of the box with no substitution rule.

Another use case is the modification of the debian version of an
artifact. For example the testng package currently installs its artifact
with the 6.x version. This isn't optimal because the packages depending
on testng have to declare a Maven rule (org.testng testng * s/.*/6.x/ *
*). Now we can modify the testng package to install its artifact with
the 'debian' version and relocate the old 6.x artifact to the new one.
The pom options for testng would look like this:

  pom.xml --has-package-version --java-lib --relocate=testng:testng:6.x

With this we can change the debian version without breaking the reverse
dependencies.

Relocations are also useful for specification jars implementing a
standard API but deploying the artifact with custom coordinates. This
happens typically with the geronimo-*-spec packages. For example the
geronimo-jcache-1.0-spec package installs the
org.apache.geronimo.specs:geronimo-jcache_1.0_spec artifact which is
equivalent to javax.cache:cache-api. We can redirect the
javax.cache:cache-api dependency to the geronimo implementation with:

  pom.xml --java-lib --relocate=javax.cache:cache-api


The relocation is performed by installing an extra pom file in the
repository [1]. The overhead is ~450 bytes per relocation.

I started using this feature in javassist/3.20 and it works well, here
the Maven 1 style coordinates (javassist:javassist) changed to the Maven
2 style (org.javassist:javassist).

This relocation mechanism will probably be handy when dealing with
transitions. I haven't tested but I think that libfoo2-java could
declare "Provides: libfoo1-java" and install the relocation poms to
avoid updating all the reverse dependencies.

Enjoy :)

Emmanuel Bourg

[1] https://maven.apache.org/guides/mini/guide-relocation.html


Reply to: