I have two questions about maven.compiler.release
-tag
I want to replace
<properties>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
</properties>
to
<properties>
<maven.compiler.release>12</maven.compiler.release>
</properties>
If I use <maven.compiler.release>
-property, do I have to set the release tag also in the plugin?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<!-- do I need that ? -->
<release>12</release>
</configuration>
</plugin>
According to https://www.baeldung.com/maven-java-version, it is set to both.
If I use maven.compiler.release
instead of maven.compiler.source
and maven.compiler.target
, then -bootclasspath
is also set and will do a cross-compile. What does this mean? Will the compilation file sizes with set -bootclasspath
be bigger or will the compilation need more time?
The --release option ensures that the code is compiled following the rules of the programming language of the specified release, and that generated classes target the release as well as the public API of that release.
compiler. target>1.8</maven. compiler.
Create a pom-only ( <packaging>pom</packaging> ) project that has the compiler settings (and any other default settings) you want. You give treat it like any other project (release it; deploy it to your Maven repo, etc.). It doesn't help much if all you want to set is compiler settings.
Chances are that it just runs fine with Java 11. Hint: You can speed up multi-module Maven projects by using parallel builds, e.g. mvn -T 4 compile compiles all modules in parallel on 4 CPU cores.
The "simple suggestion" in the other answer won't work correctly because unfortunately the situation is not simple. The compiler options mean slightly different things. The maven.compiler.source
and maven.compiler.target
options refer to the source code format and the format of the generated class files, respectively. But they do not take into account API changes as maven.compiler.release
does.
So if you blindly just use <maven.compiler.source>8</maven.compiler.source>
and <maven.compiler.target>8</maven.compiler.target>
, if you build using Java 11 for example the generated class files will support Java 8 but the API may still rely on Java 11 changes and break when run on Java 8. See How should javac 11 link methods overridden in later versions with a Java 8 target? for more discussion.
The solution is not so simple if you want to designate Java 8 but build on Java 9+. You'll need to specify the source and target as you are doing, using compiler options supported by Java 8:
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
Then you'll need to set up a separate profile in the <profiles>
section that is only activated in Java 9+ to turn on the maven.compiler.release
option:
<profile>
<id>java-8-api</id>
<activation>
<jdk>[9,)</jdk>
</activation>
<properties>
<maven.compiler.release>8</maven.compiler.release>
</properties>
</profile>
That way if you build on Java 9+, maven.compiler.release
will come into effect and restrict the API to be compatible with Java 8. If you build on Java 8, the other two options will set the source code and class file format to Java 8, and the API will be Java 8 compatible by definition.
The better option for everyone involved of course is just to move to Java 11 as soon as possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With