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

Verify that Java language level isn't higher than runtime version #18340

Closed
wants to merge 1 commit into from

Conversation

fmeum
Copy link
Collaborator

@fmeum fmeum commented May 7, 2023

The value of --(tool_)java_language_version results in a matching
-target argument passed to javac and thus in the generation of class
files that only run on runtimes of the same or higher versions.

This commit introduces a check that fails if the language version is
strictly higher than the version of the current runtime. In the exec
configuration, this covers two situations at once:

  • Compilation of a Java tool, where the runtime version is determined
    by --tool_java_runtime_version.
  • Compilation with a java_plugin, where the runtime version is
    determined by the java_runtime_version_alias target specified as the
    Java toolchain's java_runtime.

The latter situation led to especially confusing error messages when
the --tool_java_language_level was higher than the version of the
runtime used for Java compilation.

Work towards #17281

@fmeum fmeum force-pushed the 17281-warnings branch 12 times, most recently from dea1f3c to 26b39ce Compare May 8, 2023 09:23
The value of `--(tool_)java_language_version` results in a matching
`-target` argument passed to javac and thus in the generation of class
files that only run on runtimes of the same or higher versions.

This commit introduces a check that fails if the language version is
strictly higher than the version of the current runtime. In the exec
configuration, this covers two situations at once:
* Compilation of a Java tool, where the runtime version is determined
  by `--tool_java_runtime_version`.
* Compilation with a `java_plugin`, where the runtime version is
  determined by the `java_runtime_version_alias` target specified as the
  Java toolchain's `java_runtime`.

The latter situation led to especially confusing error messages when
the `--tool_java_language_level` was higher than the version of the
runtime used for Java compilation.
@fmeum fmeum closed this May 8, 2023
@fmeum fmeum reopened this May 8, 2023
@fmeum fmeum changed the title WIP: Check for invalid Java toolchain configurations Verify that Java language level isn't higher than runtime version May 8, 2023
@fmeum
Copy link
Collaborator Author

fmeum commented May 8, 2023

@cushon Could you take a look? This implements your suggestion from #17281 (comment).

I wonder whether having a new --java_compilation_runtime_version flag would help make the default setup more reusable: If not set, everything would remain as is, if set, the java_runtime of any Java toolchain would pick up the version indicated by the flag.

@fmeum fmeum marked this pull request as ready for review May 8, 2023 10:09
@fmeum fmeum requested a review from lberki as a code owner May 8, 2023 10:09
@fmeum fmeum requested a review from cushon May 8, 2023 10:09
@github-actions github-actions bot added awaiting-review PR is awaiting review from an assigned reviewer team-Rules-Java Issues for Java rules labels May 8, 2023
@cushon cushon requested a review from hvadehra May 12, 2023 23:58
Copy link
Contributor

@cushon cushon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking this up, it would be nice to make the interaction between these flags less bug-prone

I wonder if this is going to have compatibility impact for existing builds that are getting away with configurations that are now rejected. @hvadehra WDYT? Maybe we could get a sense by running it through the downstream projects pipeline?

runtimeVersion = Integer.parseUnsignedInt(rawRuntimeVersionLastPart);
} catch (NumberFormatException ignored) {
// Could be e.g. the "jdk" part of "local_jdk" without a version number, which we can't
// check at this point.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems slightly dicey to figure out the Java features version from the string name of the runtime version. That convention doesn't hold for all of the Java runtimes we define at google, for example.

Is there somewhere we could do this validation when we have the JavaRuntimeInfo, in order to check the java_runtime.version instead of the value of --java_runtime_version=?

rawLanguageVersion, rawRuntimeVersion));
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we go with the logic in this class, it would be nice to have some unit test coverage for the parsing logic in JavaConfigurationTest

@fmeum
Copy link
Collaborator Author

fmeum commented May 13, 2023

Parsing the runtime name isn't the greatest, I agree. It is also possible for users to manually specify a -target N that is lower than the one configured by java_language_version.

Maybe it would suffice to perform this check in the exec configuration? The situation where an annotation processor isn't compatible with the Java runtime running javac is definitely the most confusing situation improved by this PR.

It could also be sufficient to catch an exception in the right place in JavaBuilder and direct users to --(tool_)java_language_version as the relevant knob. What do you think?

@cushon
Copy link
Contributor

cushon commented May 15, 2023

Maybe it would suffice to perform this check in the exec configuration? The situation where an annotation processor isn't compatible with the Java runtime running javac is definitely the most confusing situation improved by this PR.

I think that's a possibility, but would that still be parsing the runtime name?

WDYT about the other option I mentioned of doing the validation later during analysis when we have the JavaRuntimeInfo, in order to check the java_runtime.version instead of the value of --java_runtime_version=?

It could also be sufficient to catch an exception in the right place in JavaBuilder and direct users to --(tool_)java_language_version as the relevant knob. What do you think?

That also seems like a possibility. I was thinking about doing the validation in JavaBuilder, but it would be nice to avoid extra logic that inspected the bootclasspath before starting compilation. Just adding additional context to the error that would be reported anyways addresses that.

@fmeum
Copy link
Collaborator Author

fmeum commented Oct 6, 2023

Superseded by changes to JavaBuilder.

@fmeum fmeum closed this Oct 6, 2023
@fmeum fmeum deleted the 17281-warnings branch October 6, 2023 09:37
@github-actions github-actions bot removed the awaiting-review PR is awaiting review from an assigned reviewer label Oct 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-Rules-Java Issues for Java rules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants