eclipse-jdtls / eclipse-jdt-core-incubator

Eclipse Public License 2.0
8 stars 1 forks source link

Javac compiler initialization error with a gradle project with annotation processors #304

Open gayanper opened 4 months ago

gayanper commented 4 months ago

When loading the CU in gradle project with a annotation processor like Lombok, there are multiple output folders emitted which cause a validation error in JavaFileManager in used.

Gradle file

plugins {
    id 'application'
}

repositories {
    mavenCentral()
}
java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
    implementation 'com.google.guava:guava:31.1-jre'
    implementation 'org.projectlombok:lombok:1.18.32'
    annotationProcessor 'org.projectlombok:lombok:1.18.32'
    }

application {
    mainClass = 'simple.gradle.App'
}

tasks.named('test') {
    useJUnitPlatform()
}
java.lang.IllegalArgumentException: path too long for directory
    at jdk.compiler/com.sun.tools.javac.file.Locations$BasicLocationHandler.checkSingletonDirectory(Locations.java:551)
    at jdk.compiler/com.sun.tools.javac.file.Locations$OutputLocationHandler.setPaths(Locations.java:616)
    at jdk.compiler/com.sun.tools.javac.file.Locations.setLocation(Locations.java:2163)
    at jdk.compiler/com.sun.tools.javac.file.JavacFileManager.setLocation(JavacFileManager.java:992)
    at org.eclipse.jdt.internal.javac.JavacUtils.configurePaths(JavacUtils.java:96)
    at org.eclipse.jdt.internal.javac.JavacUtils.configureJavacContext(JavacUtils.java:55)
    at org.eclipse.jdt.internal.javac.JavacUtils.configureJavacContext(JavacUtils.java:45)
    at org.eclipse.jdt.internal.javac.JavacCompiler.compile(JavacCompiler.java:65)
    at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:412)
    at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.compile(BatchImageBuilder.java:211)
    at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:343)
    at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:79)
    at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:286)
    at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:192)
    at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:1077)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:296)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:352)
    at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:441)
    at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47)
    at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:444)
    at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:555)
    at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:503)
    at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:585)
    at org.eclipse.core.internal.resources.Workspace.buildInternal(Workspace.java:594)
    at org.eclipse.core.internal.resources.Workspace.build(Workspace.java:483)
    at org.eclipse.jdt.ls.core.internal.handlers.BuildWorkspaceHandler.buildWorkspace(BuildWorkspaceHandler.java:63)
    at org.eclipse.jdt.ls.core.internal.handlers.JDTLanguageServer.lambda$28(JDTLanguageServer.java:1001)
    at org.eclipse.jdt.ls.core.internal.handlers.JDTLanguageServer.lambda$61(JDTLanguageServer.java:1236)
    at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
    at java.base/java.util.concurrent.CompletableFuture$Completion.exec(CompletableFuture.java:483)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1491)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:2073)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2035)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187)

The issue lies at the following line

https://github.com/eclipse-jdtls/eclipse-jdt-core-incubator/blob/fix-multi-source-output-dirs/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacUtils.java#L96

I'm not really sure if the default path is used or not since I assume that is something the build ship plugin provides as part of the eclipse project configuration.

These are the received values

HashMap$Node@211 "/Users/gayanperera/Projects/workspace/simple-gradle/bin/generated-sources/annotations":"/Users/gayanperera/Projects/workspace/simple-gradle/bin/default"

HashMap$Node@212 "/Users/gayanperera/Projects/workspace/simple-gradle/src/main/resources":"/Users/gayanperera/Projects/workspace/simple-gradle/bin/main"

HashMap$Node@213 "/Users/gayanperera/Projects/workspace/simple-gradle/src/main/java":"/Users/gayanperera/Projects/workspace/simple-gradle/bin/main"

I wonder if buildship will do anything specific in this scenario when running on Javac mode. So one option is to resolve the conflict by choosing the best path. In this case just ignore the source path which is part of the bin provided that we know bin in the build out in this place.

@mickaelistria WDYT ?

gayanper commented 4 months ago

If we can agree on a good strategy to handle this I can help on the implementation with a PR.

mickaelistria commented 4 months ago

Your analysis sounds good and it would be great if you can help here. There are 2 issues you may want to look at: #222 and #215 , I think you'll need to tackle them in this order.

Note that the current code tends to be a too low-level: setting the Options and Paths for instance would probably better be done as part of the JavacTask creation (which allows to pass those settings). So if you agree a refactoring here would help, feel free to proceed with it.