Merged
Conversation
Adds a new recipe that detects classes appearing in multiple dependencies on the classpath, similar to basepom's duplicate-finder-maven-plugin. The recipe uses JavaSourceSet.gavToTypes to invert the GAV→types mapping and find types that appear in more than one dependency. Results are reported via a DuplicateClassesReport data table with project, source set, type name, and the dependencies containing the duplicate. Filters out module-info and package-info false positives from multi-release JARs. Fixes moderneinc/customer-requests#878
| import org.openrewrite.java.tree.JavaType; | ||
|
|
||
| import java.util.*; | ||
| import java.util.stream.Collectors; |
Contributor
There was a problem hiding this comment.
Suggested change
| import java.util.stream.Collectors; | |
| import static java.util.Collections.emptyList; | |
| import static java.util.stream.Collectors.joining; |
src/main/java/org/openrewrite/java/dependencies/search/FindDuplicateClasses.java
Show resolved
Hide resolved
src/main/java/org/openrewrite/java/dependencies/search/FindDuplicateClasses.java
Show resolved
Hide resolved
|
|
||
| @Override | ||
| public Collection<? extends SourceFile> generate(Accumulator acc, ExecutionContext ctx) { | ||
| return Collections.emptyList(); |
Contributor
There was a problem hiding this comment.
Suggested change
| return Collections.emptyList(); | |
| return emptyList(); |
JavaVisitor is more appropriate since Java source files are more likely to have the JavaSourceSet marker needed for duplicate detection.
Comment on lines
+42
to
+52
| @Override | ||
| public String getDisplayName() { | ||
| return "Find duplicate classes on the classpath"; | ||
| } | ||
|
|
||
| @Override | ||
| public String getDescription() { | ||
| return "Detects classes that appear in multiple dependencies on the classpath. " + | ||
| "This is similar to what the Maven duplicate-finder-maven-plugin does. " + | ||
| "Duplicate classes can cause runtime issues when different versions " + | ||
| "of the same class are loaded."; |
Contributor
There was a problem hiding this comment.
Suggested change
| @Override | |
| public String getDisplayName() { | |
| return "Find duplicate classes on the classpath"; | |
| } | |
| @Override | |
| public String getDescription() { | |
| return "Detects classes that appear in multiple dependencies on the classpath. " + | |
| "This is similar to what the Maven duplicate-finder-maven-plugin does. " + | |
| "Duplicate classes can cause runtime issues when different versions " + | |
| "of the same class are loaded."; | |
| String displayName = "Find duplicate classes on the classpath"; | |
| String description = "Detects classes that appear in multiple dependencies on the classpath. " + | |
| "This is similar to what the Maven duplicate-finder-maven-plugin does. " + | |
| "Duplicate classes can cause runtime issues when different versions " + | |
| "of the same class are loaded."; |
Comment on lines
+113
to
+115
| String additionalDeps = gavs.size() > 2 | ||
| ? gavs.subList(2, gavs.size()).stream().collect(joining(", ")) | ||
| : ""; |
Contributor
There was a problem hiding this comment.
Suggested change
| String additionalDeps = gavs.size() > 2 | |
| ? gavs.subList(2, gavs.size()).stream().collect(joining(", ")) | |
| : ""; | |
| String additionalDeps = gavs.size() > 2 ? | |
| gavs.subList(2, gavs.size()).stream().collect(joining(", ")) : | |
| ""; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
FindDuplicateClassesrecipe that detects classes appearing in multiple dependencies on the classpathDuplicateClassesReportdata table with project, source set, type name, and conflicting dependenciesmodule-infoandpackage-infofalse positives from multi-release JARsProblem
Duplicate classes on the classpath can cause runtime issues when different versions of the same class are loaded. The basepom
duplicate-finder-maven-pluginhelps detect this, but there was no OpenRewrite equivalent.Solution
The recipe uses
JavaSourceSet.gavToTypesto invert the GAV→types mapping and find types that appear in more than one dependency. ThegavToTypesmap is populated when the full classpath is scanned (e.g., via mod CLI orJavaSourceSet.build()), providing accurate dependency-to-type mappings.Test plan
Existing tests pass
New tests added using real SLF4J binding duplicates (logback-classic vs slf4j-nop)
Tests verify no false positives with single-dependency classpath
Fixes moderneinc/customer-requests#878