Hello there,
I discovered a weird behaviour in gradle projects regarding the classpath(OrderEntries).
The scenario is the following:
- We have a gradle project
- The project is already built with gradle - that means classes built by gradle exist in the build directory
- We have configured a different module output path than the gradle directory
- We have also built the project by using Intellij Build → Rebuild Project
If the above is true then determining the classpath with the following code leads to duplicate entries:
for(final Module m : ModuleManager.getInstance(project).getModules()){
System.out.println("module "+m.getName());
for(final VirtualFile vf : ModuleRootManager.getInstance(m).orderEntries().withoutSdk().withoutDepModules().getClassesRoots()){
System.out.println(vf);
}
}
In my example project this produces the following output:
module aTestGradleProject
file://C:/smo/projects/aTestProject/aTestGradleProject/build/classes/java/main
module aTestGradleProject.main
file://C:/smo/projects/aTestProject/aTestGradleProject/out/production/aTestGradleProject.main
file://C:/smo/projects/aTestProject/aTestGradleProject/build/classes/java/main
module aTestGradleProject.test
jar://C:/Users/smo/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter/5.10.0/8fea1d9c58b2156f1b998f2f18da04bc9e087f74/junit-jupiter-5.10.0.jar!/
jar://C:/Users/smo/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-params/5.10.0/9041c7365495a897a64782ea5a6fdb99dab1814e/junit-jupiter-params-5.10.0.jar!/
jar://C:/Users/smo/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-api/5.10.0/2fe4ba3d31d5067878e468c96aa039005a9134d3/junit-jupiter-api-5.10.0.jar!/
jar://C:/Users/smo/.gradle/caches/modules-2/files-2.1/org.apiguardian/apiguardian-api/1.1.2/a231e0d844d2721b0fa1b238006d15c6ded6842a/apiguardian-api-1.1.2.jar!/
jar://C:/Users/smo/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-commons/1.10.0/d533ff2c286eaf963566f92baf5f8a06628d2609/junit-platform-commons-1.10.0.jar!/
jar://C:/Users/smo/.gradle/caches/modules-2/files-2.1/org.opentest4j/opentest4j/1.3.0/152ea56b3a72f655d4fd677fc0ef2596c3dd5e6e/opentest4j-1.3.0.jar!/
jar://C:/Users/smo/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-engine/5.10.0/90587932d718fc51a48112d33045a18476c542ad/junit-jupiter-engine-5.10.0.jar!/
jar://C:/Users/smo/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-engine/1.10.0/276c4edcf64fabb5a139fa7b4f99330d7a93b804/junit-platform-engine-1.10.0.jar!/
Problematic are these two entries which both contain the same classes(in my example project only a single class Main)
file://C:/smo/projects/aTestProject/aTestGradleProject/out/production/aTestGradleProject.main
file://C:/smo/projects/aTestProject/aTestGradleProject/build/classes/java/main
Is it possible to filter those duplicated entries somehow such that the classpath contains only one of those entries?
Thanks you and kind regards,
Samuel
PS I created an example project to make it easier to understand the problem - however seems like I am not allowed to upload a ZIP file. Is there any other way I can upload this file?
Hello Samuel Motal!
- We have configured a different module output path than the gradle directory
How do you configure this module directory?
I tried to change the module output directory from build.gradle.kts
.
sourceSets {
main {
java.destinationDirectory.set(file("out/production/${project.name}.main"))
}
}
I tried to change the module output directory from Project Structure
.
In both cases, I have only one output directory in module class path.
surly-golems
module surly-golems
file:///Users/Sergey.Vorobyov/Documents/Samples/Untitled/surly-golems/out/production/surly-golems.main
module surly-golems.main
file:///Users/Sergey.Vorobyov/Documents/Samples/Untitled/surly-golems/out/production/surly-golems.main
module surly-golems.test
jar:///Users/Sergey.Vorobyov/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter/5.10.0/8fea1d9c58b2156f1b998f2f18da04bc9e087f74/junit-jupiter-5.10.0.jar!/
jar:///Users/Sergey.Vorobyov/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-params/5.10.0/9041c7365495a897a64782ea5a6fdb99dab1814e/junit-jupiter-params-5.10.0.jar!/
jar:///Users/Sergey.Vorobyov/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-api/5.10.0/2fe4ba3d31d5067878e468c96aa039005a9134d3/junit-jupiter-api-5.10.0.jar!/
jar:///Users/Sergey.Vorobyov/.gradle/caches/modules-2/files-2.1/org.apiguardian/apiguardian-api/1.1.2/a231e0d844d2721b0fa1b238006d15c6ded6842a/apiguardian-api-1.1.2.jar!/
jar:///Users/Sergey.Vorobyov/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-commons/1.10.0/d533ff2c286eaf963566f92baf5f8a06628d2609/junit-platform-commons-1.10.0.jar!/
jar:///Users/Sergey.Vorobyov/.gradle/caches/modules-2/files-2.1/org.opentest4j/opentest4j/1.3.0/152ea56b3a72f655d4fd677fc0ef2596c3dd5e6e/opentest4j-1.3.0.jar!/
jar:///Users/Sergey.Vorobyov/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-engine/5.10.0/90587932d718fc51a48112d33045a18476c542ad/junit-jupiter-engine-5.10.0.jar!/
jar:///Users/Sergey.Vorobyov/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-engine/1.10.0/276c4edcf64fabb5a139fa7b4f99330d7a93b804/junit-platform-engine-1.10.0.jar!/
IDE Script (Groovy)
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.roots.ModuleRootManager
for (var project: ProjectManager.getInstance().openProjects) {
println project.name
for (var m : ModuleManager.getInstance(project).getModules()) {
println "module " + m.getName()
for (var vf : ModuleRootManager.getInstance(m).orderEntries().withoutSdk().withoutDepModules().getClassesRoots()) {
println vf
}
}
}
Hello Sergey,
here is how the project is configured:
The compiler path is set in the project structure on project level:
The modules are configured to inherit the compiler path from the project:
However the main and the test project have a different module path configured:
I admit this is a little bit a weird configuration - I think however it is easy to encounter such a situation. What I did was just setup a gradle project and afterwards change the compiler output path on project level. The compiler output path on main and test I did never touch - I think it was initialized with the creation of the gradle project.
Thank you for your investigation so far. Is there any more information that would help?
Best regards,
Samuel
Hi! Thank you for the clarification.
All output directories looks good on your screen shots. Could you please share screenshots of the Project Structure’s dependencies tab for project with duplicated classpath entries? Which IntelliJ API do you use for changing project and module output paths?
I tried to change project level compiler output by UI in IDEA 2024.3.5. And I don’t see any unexpected class-path elements.
project untitled1
module untitled1
...
module untitled1.main
file:///Users/Sergey.Vorobyov/Documents/Samples/Untitled/untitled1/build/classes/java/main
module untitled1.test
...
Also, I tried to change build delegation mode to the IntelliJ IDEA (in IDE Gradle Settings). And rebuild project.
project untitled1
module untitled1
...
module untitled1.main
file:///Users/Sergey.Vorobyov/Documents/Samples/Untitled/untitled1/out/production/classes
module untitled1.test
...
Hi!
I did some investigation today.
First I want to correct my last screenshot. Seems like due to copying the project something did get mest up. This part of my last answer is wrong:
“However the main and the test project have a different module path configured”
Instead they also inherit from project - this is now a correct screenshot:
So now to your last questions 
Here are the screenshots of the dependency tab:
I am using the API provided by the UI in IntelliJ 2024.3.3. However I did run the IntelliJ instance via the Run Plugin Gradle Task.
What I found out today is that the issue seems to be related to autobuild.
I can only reproduce the issue if the autobuild is activated. If not it does not occur. However even with the autobuild enabled it appears that it is not always the case that the class path entries are duplicated. Usually when I switch to another project and then switch back to the example project I can reproduce it though.
I hope this information is helpfull.
Best regards,
Samuel
Hi, @Samuel Motal! Thank you for your response)
Could you please create an issue in YouTrack? Our support team can help investigate your issue closely and recommend some workarounds.
https://youtrack.jetbrains.com/newIssue
1 Like