Problem
After a Gradle sync, the External Libraries node in the Project tool window lists one library several times, with different versions:
Gradle: commons-io:commons-io:2.11.0
Gradle: commons-io:commons-io:2.18.0
Gradle: com.example:example-lib:1.12.0
Gradle: com.example:example-lib:1.15.2
Reloading the Gradle project, File | Invalidate Caches, deleting the Gradle cache, and rebuilding do not remove the extra entries.
A Gradle sync or task that fails with PKIX path building failed ... unable to find valid certification path to requested target is a separate problem. The IDE does not update the library list from a sync that fails, so fix that error first: PKIX path building failed in Maven, Gradle, or run configurations: CA missing from the JDK.
Cause
Gradle resolves version conflicts separately for each configuration of each project, for example runtimeClasspath of one subproject and testCompileClasspath of another. It does not align versions across the whole build. When two subprojects or source sets resolve different versions of the same library, IntelliJ IDEA imports each version as a separate library. External Libraries shows the libraries of all modules together, so both versions appear.
The build scripts produce this result. IDE cache operations do not change it.
Resolution
Step 1. Find which module uses each version
- Open the Gradle tool window and click the toolbar icon that opens the Dependency Analyzer window. Alternatively, right-click a module in the Project tool window and select Analyze Dependencies.
- Select Show Conflicts Only.
- Select the library. The Usages part shows which dependency requests each version.
The Gradle dependency analyzer documentation describes the window in detail.
From the terminal, the dependencyInsight task prints the same information for one subproject and one configuration:
./gradlew :<subproject>:dependencyInsight --dependency commons-io --configuration runtimeClasspath
Run it for each subproject that uses the library.
Step 2. Align the version for the whole build
Force one version for all projects in the root build.gradle:
allprojects {
configurations.all {
resolutionStrategy {
force 'commons-io:commons-io:2.18.0'
force 'com.example:example-lib:1.15.2'
}
}
}
The same block in build.gradle.kts:
allprojects {
configurations.all {
resolutionStrategy {
force("commons-io:commons-io:2.18.0")
force("com.example:example-lib:1.15.2")
}
}
}
A configurations.all block outside allprojects applies to the root project only. Subprojects then keep their own versions.
For a long-term setup, declare the versions once in a platform (BOM) or with dependency constraints, so that a transitive dependency cannot bring in another version. The Gradle dependency management documentation describes both.
Step 3. Reload the project
Click Reload All Gradle Projects on the Gradle tool window toolbar. Expand External Libraries and make sure that each library appears with one version.
Step 4. Re-create the IDE project model
Do this step only when dependencyInsight reports one version in every subproject and External Libraries still lists several.
- Close the project.
- In the project root, back up and delete the
.ideadirectory and all*.imlfiles. - Select File | Open, select the root
build.gradleorsettings.gradlefile, and click Open as Project.
Step 5. Remove stale artifacts from the local Maven repository
This step applies only when a repositories block contains mavenLocal(). Gradle checks repositories in the declared order, so an old artifact in ~/.m2/repository can be used instead of the one from the remote repository.
- Delete the directory of the library, for example
~/.m2/repository/commons-io/commons-io. - Click Reload All Gradle Projects on the Gradle tool window toolbar.
Comments
0 comments
Please sign in to leave a comment.