Skip to content
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

Merged
merged 6 commits into from Feb 28, 2023

Conversation

alllex
Copy link
Member

@alllex alllex commented Feb 23, 2023

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 via java 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

@alllex alllex self-assigned this Feb 23, 2023
@alllex alllex changed the title Support non-javac toolchain tools to be used as a Java compiler Restore an edge case of non-javac toolchain tools being used as a Java compiler Feb 23, 2023
@alllex alllex marked this pull request as ready for review February 24, 2023 10:07
@alllex alllex requested a review from a team as a code owner February 24, 2023 10:07
throw new InvalidUserDataException("The configured executable is a directory (" + executableFile.getAbsolutePath() + ")");
}
return executableFile;
return executableAbsoluteFile;
Copy link
Member Author

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.

Comment on lines +496 to +498
def customJavaLauncher = javaToolchains.launcherFor {
languageVersion.set(JavaLanguageVersion.of(${jdk.javaVersion.majorVersion}))
}.get()
Copy link
Contributor

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).

Copy link
Contributor

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.

Copy link
Member Author

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:

Provider<JavaCompiler> javaCompilerConvention = getProviderFactory()
.provider(() -> JavaCompileExecutableUtils.getExecutableOverrideToolchainSpec(this, objectFactory))
.flatMap(javaToolchainService::compilerFor)
.orElse(javaToolchainService.compilerFor(it -> {}));

I'll update the test to show this

@alllex alllex requested a review from wolfs February 27, 2023 11:40
@alllex
Copy link
Member Author

alllex commented Feb 27, 2023

@bot-gradle test this

@bot-gradle
Copy link
Collaborator

I've triggered the following builds for you:

Copy link
Member

@ljacomet ljacomet left a 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"
Copy link
Member

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?

Copy link
Member Author

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!

@wolfs wolfs added this to the 8.1 RC1 milestone Feb 28, 2023
@alllex
Copy link
Member Author

alllex commented Feb 28, 2023

@bot-gradle test and merge

@gradle gradle deleted a comment from alllex Feb 28, 2023
@bot-gradle
Copy link
Collaborator

Your PR is queued. See the queue page for details.

@bot-gradle
Copy link
Collaborator

I've triggered a build for you.

@bot-gradle bot-gradle merged commit e87ed79 into master Feb 28, 2023
@bot-gradle bot-gradle deleted the alllex/jvm/toolchain-relax-javac branch February 28, 2023 12:44
bot-gradle added a commit that referenced this pull request Feb 28, 2023
… 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Gradle 8.0.+ silently dropped support for custom compilers in JavaCompile
6 participants