Extend RemoveRedundantDependencyVersions to also remove redundant dependencyManagement entries managed by an imported BOM

Open
#8,862 2 comments 0 reactions 0 assignees View on GitHub

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

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

enhancement maven recipe
What version of OpenRewrite are you using?
  • rewrite-maven 8.89.0 (via rewrite-maven-plugin 6.46.0; also observed with 6.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 / ChangeParentPom pins 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 — but RemoveRedundantDependencyVersions (including as invoked inside ChangeParentPom) 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

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.

More from openrewrite/rewrite

All issues in openrewrite/rewrite

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.