Description
Hello,
When maven-compiler-plugin
is configured to fork or use a toolchains, Plexus JavacCompiler
fails to determine correctly the Java version if there is a JAVA_TOOL_OPTIONS
set prior, which is done automatically by Jenkins (I can't remove it): problem is that if affect the encoding
as well as other parts (mostly in buildCompilerArguments) because it badly interpret the Java version to 1.3 (in my case).
The method getOutOfProcessJavacVersion use javac -version
to determine compiler version, then it use use a regexp \d+(\.\d+)?
on the stdout but when JAVA_TOOL_OPTIONS
, there is an (annoying) warning and if the warning contains something that match the regexp, such as ... as version, it fails to return the proper JDK version:
Picked up JAVA_TOOL_OPTIONS: -Dmaven.ext.class.path="/some/path/with/name-1.3.x/foobar.jar" -Dorg.jenkinsci.plugins.pipeline.maven.reportsFolder="/some/path/with/name-1.3.x/"
javac 1.8.0_432
The regex can be tested here: https://regex101.com/r/EboVGM/1
As we can see, we have more than one result:
- 1.3 <-- selected
- 1.3
- 1.8
- 0
- 432
If you are lucky, and like most Linux, javac
will use UTF-8 while compiling: you won't notice anything.
If you are unlucky (like me), javac will not use UTF-8 while compiling, but ANSI_X3.4-1968 and it fails at the first mappable character it found (like ©).
One fix to this issue would be to resolve version from the javac
line only:
String prefix = "javac ";
int prefixLength = prefix.length();
// grab the "javac " part
Optional<String> javacPrefix = Arrays.stream(text.split("\\R"))
.filter(line -> line.startsWith(prefix))
.map(line -> line.substring(prefixLength))
.findFirst();
return javacPrefix.map(line -> JAVA_MAJOR_AND_MINOR_VERSION_PATTERN.matcher(line))
.filter(Matcher::find)
.map(Matcher::group)
.orElseThrow(() -> "Could not extract version from \"" + text + "\"");
Or we could assume that javac
is always last and process only last line:
String[] lines = text.split("\\R");
String lastLine = lines.length == 0 ? "":lines[lines.length-1];
Note: JAVA_TOOL_OPTIONS
is set by Jenkins withMaven
for various reasons and the docs indicate it is not possible to avoid this warning: https://github.com/jenkinsci/pipeline-maven-plugin/blob/master/FAQ.adoc#why-do-i-see-messages-warning-picked-up-java_tool_options-in-the-build-logs
When using the JAVA_TOOL_OPTIONS, the JVM outputs a message during its initialization.