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