openrewrite / openrewrite/rewrite
Renaming a parent's dependencyManagement leaves child modules with a stale MavenResolutionResult
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:
- 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) andspring-projects-experimental/spring-cloud-sleuth-otel(26), all fromUpgradeOkHttpMockWebServer -> ChangeDependency. The fullspring-cloud-sleuthPOM chain (root →tests→tests/brave→ module) reproduces it exactly. - Worse, later recipes make decisions from the stale model.
AddDependencyfor 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 whatfinos/legend-sharedshows forjakarta.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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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