Extend RemoveRedundantDependencyVersions to also remove redundant dependencyManagement entries managed by an imported BOM
Maintainers usually reply within 1 day
@SwatiKumari250 is already working on this.
Since Oct 16, 2026.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 70/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- java
- Domain
- build-system, tooling
Research direction
Start with RemoveRedundantDependencyVersions and the RemoveRedundantDependencyVersionsImportedBomTest reproduction described in the issue. Compare the existing direct-dependency behavior with dependencyManagement entries, including the onlyIfManagedVersionIs comparator. Done means the redundant management version is removed when covered by an imported BOM while intentional version overrides remain unchanged.
Written by the indexing model from the issue text.
Description
What version of OpenRewrite are you using?
rewrite-maven8.89.0(viarewrite-maven-plugin6.46.0; also observed with6.37.0)- Recipe:
org.openrewrite.maven.RemoveRedundantDependencyVersions, default configuration
What problem are you trying to solve?
RemoveRedundantDependencyVersions already strips a redundant explicit version from a direct dependency whose version is managed by an imported BOM. We'd like it to also remove the equivalent redundancy when it appears as a <dependencyManagement> entry sitting alongside that same imported BOM.
Today the two cases behave differently even though they differ only in <dependencies> vs <dependencyManagement>: the direct dependency is cleaned up, the management entry is left in place.
- This matters because
UpgradeParentVersion/ChangeParentPompins previously-inherited managed versions into a project's own<dependencyManagement>(its "retain dependency management no longer provided by the new parent" behavior). When those pinned versions are also covered by a BOM the project already imports, they're genuinely redundant — butRemoveRedundantDependencyVersions(including as invoked insideChangeParentPom) can't remove them, so the pins linger and have to be cleaned up by hand. Possibly related: #5796.
Example
The first test passes today; the second is the behavior we'd like (it currently makes no change).
class RemoveRedundantDependencyVersionsImportedBomTest implements RewriteTest {
@Override
public void defaults(RecipeSpec spec) {
spec.recipe(new RemoveRedundantDependencyVersions(null, null, null, null));
}
// Already works: a redundant version on a direct dependency is removed.
@Test
void removesRedundantVersionFromDirectDependency() {
rewriteRun(
//language=xml
pomXml(
"""
<project>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.10.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.2</version>
</dependency>
</dependencies>
</project>
""",
"""
<project>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.10.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
</dependencies>
</project>
"""
)
);
}
// Desired: the equivalent redundant version in a dependencyManagement ENTRY is also
// removed. Currently the recipe makes no change here.
@Test
void removesRedundantEntryFromDependencyManagement() {
rewriteRun(
//language=xml
pomXml(
"""
<project>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.10.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- it'd be nice if this could be removed as there is an imported pom managing it -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.2</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
""",
"""
<project>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.10.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
"""
)
);
}
}
Is this intended, or open to an enhancement?
It's possible the current behavior is deliberate — e.g. treating an explicit dependencyManagement entry as an intentional override rather than redundancy. If so, we'd love to understand the reasoning. If you're open to the enhancement, one option would be to also consider imported-BOM–managed versions when evaluating dependencyManagement entries (mirroring the direct-dependency path), perhaps gated by the existing onlyIfManagedVersionIs comparator so an intentional override to a different version is preserved.
Are you interested in contributing this feature?
Yes — we're happy to open a PR if you'll point us at the direction you'd prefer (extend RemoveRedundantDependencyVersions directly vs. a related visitor). We already have a hermetic reproduction and the example above.
- Dominant language
- Java
- Stars
- 3.9k
- Forks
- 599
- Avg merge
- 9h 38m
- Merged PRs (30d)
- 557
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing 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.
More from openrewrite/rewrite
-
Difficulty 2/5 1-3 hours Newbie friendliness 79/100
openrewrite/rewrite#9835 ·
Maintainers usually reply within 1 day
-
bug gradle
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
openrewrite/rewrite#7576 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
openrewrite/rewrite#9834 ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
openrewrite/rewrite#9819 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 4/5 3-5 days Newbie friendliness 55/100
openrewrite/rewrite#9817 ·
Maintainers usually reply within 1 day
All issues in openrewrite/rewrite
Similar issues
-
Four TestConstraintBasedAlgorithm tests pass when nothing is thrownPossibly taken @sharanggupta claimed this today. Open
Difficulty 1/5 1-3 hours Newbie friendliness 85/100
-
bug documentation good first issue help wanted priority low size XS
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
martin-francois/symphony-trello#1351 ·
Maintainers usually reply within 1 day
-
Add test coverage for ConvertUtil.parseDate() with NULL inputPossibly taken @mirajul-mollah7 claimed this today. Open
Difficulty 1/5 Under an hour Newbie friendliness 78/100
eclipse-sw360/sw360#4792 · 1 comment ·
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
aws/aws-emulator#30 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 4 days