Skip to content

Speed up ModuleHasDependency and RepositoryHasDependency by removing DependencyInsight#176

Open
steve-aom-elliott wants to merge 1 commit intomainfrom
fix/module-repository-has-dependency-direct-lookup
Open

Speed up ModuleHasDependency and RepositoryHasDependency by removing DependencyInsight#176
steve-aom-elliott wants to merge 1 commit intomainfrom
fix/module-repository-has-dependency-direct-lookup

Conversation

@steve-aom-elliott
Copy link
Copy Markdown
Contributor

@steve-aom-elliott steve-aom-elliott commented Apr 22, 2026

What

Both org.openrewrite.java.dependencies.search.ModuleHasDependency and RepositoryHasDependency ran a fresh DependencyInsight visitor against every source file during scanning, just to answer a binary yes/no question about whether the module contains a given GAV.

Replace the visitor with a direct check against:

  • MavenResolutionResult.findDependencies(groupId, artifactId, scope) for Maven modules, and

  • GradleProject's configurations + ResolvedDependency.findDependency walk for Gradle modules.

  • This mirrors the pattern Sam applied to the single-build-system ModuleHasDependency classes in openrewrite/rewrite (commit 919c9f5 / PR #6664) — these cross-build-system versions weren't updated alongside.

Why

These recipes are used as preconditions in many declarative migration recipes — in the Spring Boot 4 recipe tree alone, ModuleHasDependency is a precondition in 11+ places across mockito.yml, spring-boot-20.yml, spring-boot-25.yml, and spring-cloud-2025.yml.

Allocating a DependencyInsight and running its Gradle + Maven visitors per source file is wasteful when all we need is a single boolean per module. With Sam's fix in place for the single-build-system versions, the cross-build-system wrappers became the remaining hot path.

How

  • ModuleHasDependency#hasDependency(Tree) and RepositoryHasDependency#hasDependency(Tree) now:
    1. Look up MavenResolutionResult on the tree's markers. If present, use findDependencies(g, a, scope) with version-comparator filtering.
    2. Otherwise look up GradleProject and walk GradleDependencyConfiguration#getDirectResolved(), calling ResolvedDependency#findDependency(g, a) to catch matches in the transitive tree.
  • No option signatures or behavior visible to callers changed.

Tests

  • Full rewrite-java-dependencies:test suite passes.
  • ModuleHasDependencyTest and RepositoryHasDependencyTest cover Maven-only, Gradle-only, mixed multi-module, direct/transitive, and version-glob cases.

…DependencyInsight

Both recipes ran a fresh DependencyInsight visitor against every source file during
scanning, which performs exhaustive Gradle + Maven dependency analysis just to answer
a binary yes/no question about whether the module contains a given GAV.

Replace the visitor with a direct check against MavenResolutionResult.findDependencies
for Maven modules, and against GradleProject's configurations + ResolvedDependency.findDependency
for Gradle modules. This mirrors the pattern Sam applied to the single-build-system versions
of ModuleHasDependency in openrewrite/rewrite (commit 919c9f5 / PR #6664).

These recipes are used as preconditions in many declarative migration recipes.
Avoiding the DependencyInsight allocation + traversal per source file substantially
reduces scanner time on repositories with many Java files.
@github-project-automation github-project-automation Bot moved this from In Progress to Ready to Review in OpenRewrite Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Ready to Review

Development

Successfully merging this pull request may close these issues.

2 participants