maven icon indicating copy to clipboard operation
maven copied to clipboard

Enhance relocation to work for all versions

Open lprimak opened this issue 2 months ago • 34 comments

New feature, improvement proposal

Currently, relocation feature is version specific. Can this be enhanced to use a version range, or make it work for all versions?

Use Case

MicroProfile is a POM-packaged artifact that points to other dependencies in org.eclipse.microprofile group.

[INFO] +- org.eclipse.microprofile:microprofile:pom:7.1:provided
[INFO] |  +- org.eclipse.microprofile.config:microprofile-config-api:jar:3.1:provided
[INFO] |  +- org.eclipse.microprofile.fault-tolerance:microprofile-fault-tolerance-api:jar:4.1:provided
[INFO] |  +- org.eclipse.microprofile.health:microprofile-health-api:jar:4.0.1:provided
[INFO] |  +- org.eclipse.microprofile.metrics:microprofile-metrics-api:jar:5.1.0:provided
[INFO] |  +- org.eclipse.microprofile.jwt:microprofile-jwt-auth-api:jar:2.1:provided
[INFO] |  +- org.eclipse.microprofile.openapi:microprofile-openapi-api:jar:4.1:provided
[INFO] |  +- org.eclipse.microprofile.rest.client:microprofile-rest-client-api:jar:4.0:provided
[INFO] |  \- org.eclipse.microprofile.telemetry:microprofile-telemetry-api:pom:2.1:provided

What needs to be accomplished (example) is to add a some kind of relocation so that:

  • org.eclipse.microprofile:microprofile:8.0 is the last org.eclipse.microprofile:microprofile artifact published
  • org.eclipse.microprofile:microprofile:8.1 (and later) is automatically redirected to jakarta.microprofile:microprofile:8.1

The end result of (for example) including of org.eclipse.microprofile:microprofile:pom:10.7:provided would result in a tree that looks something like this:

[INFO] +- jakarta:microprofile:pom:10.7:provided
[INFO] |  +- jakarta.config:microprofile-config-api:jar:3.1:provided
[INFO] |  +- jakarta.fault-tolerance:microprofile-fault-tolerance-api:jar:4.1:provided
[INFO] |  +- jakarta.health:microprofile-health-api:jar:4.0.1:provided
[INFO] |  +- jakarta.metrics:microprofile-metrics-api:jar:5.1.0:provided
[INFO] |  +- jakarta.jwt:microprofile-jwt-auth-api:jar:2.1:provided
[INFO] |  +- jakarta.openapi:microprofile-openapi-api:jar:4.1:provided
[INFO] |  +- jakarta.rest.client:microprofile-rest-client-api:jar:4.0:provided
[INFO] |  \- jakarta.telemetry:microprofile-telemetry-api:pom:2.1:provided

Why do this?

MicroProfile wants to merge with Jakarta EE. However, it wants to avoid the mistakes that happened with Java EE -> Jakarta EE transition. MicroProfile wants to provide a smooth, non-breaking migration path from MicroProfile to Jakarta EE.

What are the alternatives?

Just publish both artifacts - Unfortunately this will introduce duplication and confusion, in addition to dependency clashes from transitive dependencies including both / either variants of the artifact

Why don't everybody just change / update the GAV coordinates? - There are many dependncies to these coordinates, and changes require "waiting" for many dependencies to upgrade, which breaks the smooth upgrade path the the new artifacts.

lprimak avatar Oct 13 '25 15:10 lprimak

The <relocation> element in the pom?

For the pom.xml, I don't see how that would work. The pom itself is version specific, and deployed to a specific version.

There would need to be something like a maven-metadata.xml change to support that. (That's a piece of XML on the repository that sits at various levels (group, artifact, etc) to support things outside of a specific pom.xml.

joakime avatar Oct 13 '25 16:10 joakime

Maven 4 introduces new kind of relocation, essentially supporting 2 kind of relocations:

  • distribution based, a la Maven 3 had (100% same)
  • user provided relocation, where user provides relocation info

They both kick in very same place and have exactly same effect, the difference is that first is provided by publisher (as before), while latter by consumer.

Note: this is still "preview", so depending on this in production is not recommended yet. Or, if you do, please consider possible changes to them. Still, feedback is welcome.

See sources: https://github.com/apache/maven/tree/master/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/relocation

See documentation for user ones here: https://github.com/apache/maven/blob/master/api/maven-api-core/src/main/java/org/apache/maven/api/Constants.java#L323-L344

cstamas avatar Oct 13 '25 16:10 cstamas

Maven or maven resolver can theoretically be modified to support this.

lprimak avatar Oct 13 '25 16:10 lprimak

Would this new maven 4 relocation support version ranges so you won't have to publish 2 GAV every time?

lprimak avatar Oct 13 '25 16:10 lprimak

This "new maven 4 relocation" (user provided one) does not involve any publishing. It happens on consumer side.

cstamas avatar Oct 13 '25 16:10 cstamas

Initial inspiration for user provided (consumer side) relocation was inspired by things like https://github.com/qos-ch/reload4j The idea is that user can relocate to a "drop in" replacements artifact in build, and consumer could perform these replacements even without touching the sources of built project.

As I said, it is "preview", so any new use case or improvement idea is welcome.

cstamas avatar Oct 13 '25 16:10 cstamas

I'm not sure I understand what that means :(

lprimak avatar Oct 13 '25 16:10 lprimak

I guess the question is will it work for a use case when any version later then micrprofile:config:5.0 could be relocated to Jakarta:EE:config:5.0 without publishing the former GAV every time.

lprimak avatar Oct 13 '25 16:10 lprimak

I updated the heading of the issue to demonstrate the use case better. Hope this helps

lprimak avatar Oct 13 '25 18:10 lprimak

So you publish 8.1 with relocation, once.

But expecting that 9.x and 10.x will relocate too assumes that consumers still use org.eclipse.microprofile:microprofile:pom:10.7 as dependency? So it assumes that consumers do edit their POM (version they consume do changes), but they don't bother with changing the G? What is the rationale here? Once redirection kick in, their build will be sparkled with WARNs anyway (about redirection) and the only way for them to get rid of warnings is to adjust: change the G in their POM to jakarta....

cstamas avatar Oct 13 '25 18:10 cstamas

When older transient dependencies use older GAV, you can use <dependencyManagement> to upgrade the new version. Since some older dependencies won't upgrade GA for some time.

This allows convergence of all actual JAR APIs to the new Jakarta-based artifacts.

lprimak avatar Oct 13 '25 18:10 lprimak

Relocation works like this (timeline):

  • publisher publishes GA:1.0
  • consumer consumes GA:1.0
  • (all fine here)
  • publisher relocates from G to G2 (publishes POM w/ relocation info to GA:1.1, publishes new artifacts to G2A:1.1).
  • consumer who did nothing just up version from 1.0 to 1.1 will still build successfully, but will get a big fat warning about relocation
  • publisher publishes G2A:1.2 only (there is no GA:1.2)
  • consumer going GA:1.1 to GA:1.2 will fail (no such artifact), as he did not his "homework" when he upped from 1.0 to 1.1 and Maven warned him
  • (new consumers go for G2A:1.2 obviously)
  • ...

cstamas avatar Oct 13 '25 18:10 cstamas

Yes, and I would like to enhanced so that:

consumer going GA:1.1 to GA:1.2 will fail (no such artifact), as he did not his "homework" when he upped from 1.0 to 1.1 and Maven warned him

Instead of failing, consumer going to GA:1.2 will go to G2A:1.2 automatically.

lprimak avatar Oct 13 '25 18:10 lprimak

When older transient depnendencies use older GAV, you can use <dependencyManagement> to upgrade the new version. Since some older dependencies won't upgrade GA for some time.

In that case just publish relocation POM (in old G) for each published artifact (in new G) too, but this raises question about the quality of those builds, as obviously we talk about builds that do warn (loud warn) users, and they just do nothing? If you assume this is acceptable, then you should provide the relocation POMs for each POM you publish to new G. Publisher relocation is up to publisher, not Maven.

cstamas avatar Oct 13 '25 18:10 cstamas

Instead of failing, consumer going to GA:1.2 will go to G2A:1.2 automatically.

Again, publisher relocation is controlled by publisher, not Maven nor anyone else. If you want to fancy this, just publish relocation for each new artifact and you are done. And it already works with Maven 3 and Maven 4 as well.

cstamas avatar Oct 13 '25 18:10 cstamas

Obviously this can be done. However, it introduces confusion, as in which artifact is "legit / latest" even though obviously they would both be the same. We want to avoid this, hence the enhancement request

lprimak avatar Oct 13 '25 18:10 lprimak

w00t? Relocation POM, that is in documentation, that I guess you did read looks like this:

<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>bar</groupId>
  <artifactId>foo</artifactId>
  <version>1.0</version>
  <distributionManagement>
    <relocation>
      <groupId>org.bar</groupId>
    </relocation>
  </distributionManagement>
</project>

So basically just a template with version and bam, publish it.

cstamas avatar Oct 13 '25 18:10 cstamas

I would love to avoid this.

lprimak avatar Oct 13 '25 19:10 lprimak

And the confusion is introduced by publisher, by relocating but not really.... 😄 So really unsure what you really want.

cstamas avatar Oct 13 '25 19:10 cstamas

It's auto-relocation of all versions > X instead of manually having to publish each relocation separately. Just a bit of automation.

Relocations (I believe) show up in maven central just like any other artifact no? Wouldn't that be source of confusion?

lprimak avatar Oct 13 '25 19:10 lprimak

It looks like this https://central.sonatype.com/artifact/ant/ant/1.7.0 And I really don't get you: what do you mean by "introduces confusion, as in which artifact is "legit / latest""? You are aware that in GA:1.1 there is no "main artifact" (ie JAR), right? As documented, that that coordinate contains only the relocation POM, right?

cstamas avatar Oct 13 '25 19:10 cstamas

@lprimak a global relocation can mess up things, in particular for MP specs which got abandonned so the sanest is to release all artifacts which must be relocated IMHO, will be better for end users and is quite easy to automate since it is mainly automated with mvn + eclipse procedure so a no brainer IMHO

rmannibucau avatar Oct 13 '25 19:10 rmannibucau

Users typically will not look at the contents of the stuff. They will just ask "what's the latest" and it'll show up as both GA. This will cause confusion.

lprimak avatar Oct 13 '25 19:10 lprimak

Romain, the relocated is only for "microprofile:microprofile:pom" artifact, which will contain only the APIs that are proper for the correct version, so this is OK

lprimak avatar Oct 13 '25 19:10 lprimak

This is what I do:

lprimak@Lennys-Mac-Nov-2024 ~ % mcs search ant:ant
Searching for ant:ant...
Found 13 results

  Coordinates       Last updated
  ===========       ============
  ant:ant:1.7.0     20 Jan 2008 at 18:40 (CST)
  ant:ant:1.6.5     15 Oct 2010 at 07:48 (CDT)
  ant:ant:1.6.4     08 Nov 2005 at 16:24 (CST)
  ant:ant:1.6.3     08 Nov 2005 at 16:24 (CST)
  ant:ant:1.6.2     08 Nov 2005 at 16:24 (CST)
  ant:ant:1.6.1     08 Nov 2005 at 16:24 (CST)
  ant:ant:1.6       08 Nov 2005 at 16:24 (CST)
  ant:ant:1.5.4     08 Nov 2005 at 16:24 (CST)
  ant:ant:1.5.3-1   08 Nov 2005 at 16:24 (CST)
  ant:ant:1.5.2     08 Nov 2005 at 16:24 (CST)
  ant:ant:1.5.1     08 Nov 2005 at 16:24 (CST)
  ant:ant:1.5       08 Nov 2005 at 16:24 (CST)
  ant:ant:1.4.1     08 Nov 2005 at 16:23 (CST)

Now I would love to use ant:ant:1.10.15 in the same way :) I would never look at the contents nor would I parse the relocation settings

lprimak avatar Oct 13 '25 19:10 lprimak

Also maybe tools like dependabot or maven versions plugin should look at the latest version, check if it's a relocation and check that for newer versions. I personally thought that some projects were long abandoned, but they just renamed their GA

lprimak avatar Oct 13 '25 19:10 lprimak

Report this to @mthmulders as mcs has a bug: ant:ant:1.7.0 does not really exists, Maven would never discover it (ie when using version range): https://repo.maven.apache.org/maven2/ant/ant/maven-metadata.xml

Proper tools say this:

[cstamas@angeleyes ~]$ jbang toolbox@maveniverse list ant:ant
ant:ant:1.4.1
ant:ant:1.5
ant:ant:1.5.1
ant:ant:1.5.2
ant:ant:1.5.3-1
ant:ant:1.5.4
ant:ant:1.6
ant:ant:1.6.1
ant:ant:1.6.2
ant:ant:1.6.3
ant:ant:1.6.4
ant:ant:1.6.5
[cstamas@angeleyes ~]$ 

cstamas avatar Oct 13 '25 19:10 cstamas

Users typically will not look at the contents of the stuff. They will just ask "what's the latest" and it'll show up as both GA. This will cause confusion.

Anymore, people will not look at the poms, they just trust the update process from tooling like dependabot or renovatebot.

joakime avatar Oct 13 '25 19:10 joakime

Anymore, people will not look at the poms, they just trust the update process from tooling like dependabot or renovatebot.

I get you, this is (I think) third thread in last 7 days where users say "I write this but would like that" as result. But again, that is the point of relocation: you get past it once (at the cost of warnings in build, something @lprimak was eager to get rid of, but strangely not now), but subsequently you have to do your homework and migrate, as next step will not be simple. Or, as I said, deploy relocation POMs for each deployed version, for as long as you want to support this "status quo", where users don't touch anything except version, and magically they end up with other artifact.

cstamas avatar Oct 13 '25 19:10 cstamas

Oh trust me, I still want to get rid of warnings. For this type of relocation (auto-relocate) I would not want any kind of warnings.

lprimak avatar Oct 13 '25 20:10 lprimak