openrewrite / openrewrite/rewrite

Renaming a parent's dependencyManagement leaves child modules with a stale MavenResolutionResult

Open
#8,463 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
3.7k
Forks
570
Avg merge
13h 12m
Merged PRs (30d)
261

Description

What version of OpenRewrite are you using?

Latest main (reproduced at 560b40cc63).

What is the smallest, simplest way to reproduce the problem?

In a multi-module build, a child module declares a dependency without a <version> and the parent POM manages it. ChangeDependencyGroupIdAndArtifactId renames the dependency in the child and the <dependencyManagement> entry in the parent — deliberately not writing an explicit version into the child (see providedDependencyManagedByLocalParentDoesNotGetExplicitVersion, parentAndBomManagedToJustParentManaged).

That output is correct on disk, but the child document's MavenResolutionResult still holds the parent's parse-time model, in which the old coordinates are managed and the new ones are not. Any recipe that runs afterwards in the same run and calls maybeUpdateModel() on the child then re-resolves against that stale parent and fails:

rewriteRun(
  spec -> spec.recipes(
    new ChangeDependencyGroupIdAndArtifactId("com.squareup.okhttp3", "mockwebserver", null, "mockwebserver3", "5.x", null),
    new RemoveDependency("org.awaitility", "awaitility", null)),   // any recipe that updates the model
  // parent POM: <dependencyManagement> for com.squareup.okhttp3:mockwebserver
  // child POM:  <dependency> com.squareup.okhttp3:mockwebserver with no <version>
);
What did you expect to see?

No marker: after the run, the parent manages mockwebserver3 and the child resolves.

What did you see instead?
<!--~~(No version provided for direct dependency com.squareup.okhttp3:mockwebserver3:compile)~~>--><dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>mockwebserver3</artifactId>
</dependency>

Two consequences:

  1. Error markers on every child module, on POMs that are actually fine. Observed in a Moderne SaaS run of "Spring Boot 4.0 best practices": 56 markers across spring-cloud/spring-cloud-sleuth (30) and spring-projects-experimental/spring-cloud-sleuth-otel (26), all from UpgradeOkHttpMockWebServer -> ChangeDependency. The full spring-cloud-sleuth POM chain (root → teststests/brave → module) reproduces it exactly.
  2. Worse, later recipes make decisions from the stale model. AddDependency for the new coordinates sees a model that still lists the old ones and can add a second, duplicate <dependency> next to the renamed one — which is what finos/legend-shared shows for jakarta.ws.rs:jakarta.ws.rs-api.

The staleness is structural: each document has its own MavenResolutionResult, and UpdateMavenModel re-resolves a child through getProjectPoms(), which yields the parent's requested Pom as captured at parse time. Edits to the parent document do not propagate to a child document's getParent() within the same pass.

Are you interested in contributing a fix?
  • Not immediately — filing so the marker signature is not confused with #8462, which is a genuinely broken POM rather than a stale model.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with UpdateMavenModel, getProjectPoms(), and the MavenResolutionResult parent relationship described in the issue. Reproduce with the ChangeDependencyGroupIdAndArtifactId followed by RemoveDependency in the shown rewriteRun, then verify that the child resolves the renamed dependency without an error marker or duplicate dependency.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
build-system
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.