Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
233 views
in Technique[技术] by (71.8m points)

"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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...