New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restore an edge case of non-javac toolchain tools being used as a Java compiler #24014
Conversation
throw new InvalidUserDataException("The configured executable is a directory (" + executableFile.getAbsolutePath() + ")"); | ||
} | ||
return executableFile; | ||
return executableAbsoluteFile; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We recently deprecated the usage of relative paths, but we still need to support it until removed.
This path ends up going to the command line executor and breaks it if it's still a relative path. So the options were to either do the absolute path conversion right before execution or here. I think here is better, because we already do a number of checks on the absolute path.
It worked before only because we always used the toolchain paths, relying on exact match between toolchain tool path and forkOptions.executable
. But we relax this contraint in this PR.
def customJavaLauncher = javaToolchains.launcherFor { | ||
languageVersion.set(JavaLanguageVersion.of(${jdk.javaVersion.majorVersion})) | ||
}.get() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that this would still fail if a different default toolchain is configured at project level. javaCompiler
would use javac
from the default toolchain and the selected toolchain here might not necessarily match. It would probably be a good idea to also test that situation (which I think should still be supported too).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this could be worked around by retrieving the launcher for the toolchain of the configured JavaCompiler
somehow but I believe that getting the toolchain for a tool is not currently possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that this would still fail if a different default toolchain is configured at project level.
It should not fail. Since we are configuring forkOptions.executable
for this JavaCompile
task, it will take priority over any toolchain configured on the project level. Here is how the override is selected:
gradle/subprojects/language-java/src/main/java/org/gradle/api/tasks/compile/JavaCompile.java
Lines 105 to 108 in c11d14a
Provider<JavaCompiler> javaCompilerConvention = getProviderFactory() | |
.provider(() -> JavaCompileExecutableUtils.getExecutableOverrideToolchainSpec(this, objectFactory)) | |
.flatMap(javaToolchainService::compilerFor) | |
.orElse(javaToolchainService.compilerFor(it -> {})); |
I'll update the test to show this
...src/integTest/groovy/org/gradle/api/tasks/compile/JavaCompileToolchainIntegrationTest.groovy
Outdated
Show resolved
Hide resolved
@bot-gradle test this |
I've triggered the following builds for you: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all makes sense, though I would investigate a fix in the upcoming 8.0.2
@@ -97,7 +97,7 @@ trait JavaToolchainFixture { | |||
* Returns the Java version from the compiled class bytecode. | |||
*/ | |||
JavaVersion classJavaVersion(File classFile) { | |||
assert classFile.exists() | |||
assert classFile.exists(), "Class file ${classFile} does not exist" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't assertions typically written with a :
instead of comma, at least in Java? Does the comma mean something different here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct. The comma syntax also works, but I completely forgot that Spock, in case of an error, provides all the info for expressions anyway. So this message here is redundant. Thanks for noticing!
@bot-gradle test and merge |
Your PR is queued. See the queue page for details. |
I've triggered a build for you. |
… tools being used as a Java compiler (Gradle 8.0.x) Backporting of a fix from #24014 Co-authored-by: Alex Semin <asemin@gradle.com>
Gradle 8 introduced unconditional usage of Java toolchains for Java compilation. However, providing custom tool paths (custom Java home or a compiler executable path) was still supported.
In addition to that, Gradle 8 protect users from doubly-configuring the toolchain via the tool property and a Java home/executable. Validations were added to make sure that toolchain from a custom path agrees with the final resolved toolchain property. In particular, the path to the executable is checked to exactly match the path to
javac
within the toolchain. This, however, made it impossible to use custom Java compilers that rely on being started as a JVM viajava
launcher tool.This PR relaxes the checks to only validate that a custom executable path leads to a tool within the same toolchain without checking which exact tool it is. In particular, a path to the
java
tool can be specified.Fixes: #23990