Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"maven.compiler.release" as an replacement for source and target?

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?

like image 658
nimo23 Avatar asked Nov 26 '19 11:11

nimo23


People also ask

What does Maven compiler release do?

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.

Which tag is used to include compiler source and target version details?

compiler. target>1.8</maven. compiler.

How do I change my default 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.

Does Maven work with Java 11?

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.


1 Answers

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.

like image 101
Garret Wilson Avatar answered Sep 24 '22 12:09

Garret Wilson