How to Compile Simple Java 10/Java 11 Project with Maven

Unable to compile simple Java 10 / Java 11 project with Maven

As of 30Jul, 2018 to fix the above issue, one can configure the java version used within maven to any up to JDK/11 and make use of the maven-compiler-plugin:3.8.0 to specify a release of either 9,10,11 without any explicit dependencies.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release> <!--or <release>10</release>-->
</configuration>
</plugin>

Note:- The default value for source/target has been lifted from 1.5 to 1.6 with this version. -- release notes.


Edit [30.12.2018]

In fact, you can make use of the same version of maven-compiler-plugin while compiling the code against JDK/12 as well.

More details and a sample configuration in how to Compile and execute a JDK preview feature with Maven.

Compiling Java 11 code with maven-compiler-pugin 2.2

By setting <maven.compiler.source>1.8</maven.compiler.source> you are essentially passing -source 1.8 to the javac compiler.

That is telling the compiler that you want to explicitly limit the input source code to Java 1.8 syntax and language. As you are using language constructs not defined in Java 8 (e.g. var), it is going to fail.

As you are specifying release as well, it appears that the value for source is taking precedence.

Setting the Java Version in Maven with system Java version as 11.0

Setting java.version in the POM <properties> section does not change the Java version used to compile with the maven-compiler-plugin. It is instead used by Spring Boot (see Specifying java version in maven - differences between properties and compiler plugin for a related discussion).

Your build is still using the JDK 11 installed on your machine (this is reflected by the manifest attribute Build-Jdk: 11.0.2), however, your code is actually compiled with source and target of Java 8. JDK 11 knows how to compile against earlier versions like JDK 8, so your build is working fine as expected.

Is it possible to build a maven project on one java version and run it on another java versions?

Yes. Newer JDKs can run older bytecode, so if you compile for Java 8, you can, usually, run it on Java 11. Sometimes changes in the Java API or support for the newer Java runtime in your dependencies may necessitate changes in your code though.

Conversely, you can also use Maven to configure the compiler to output Java 8 bytecode while using a Java 11 JDK yourself in the <plugins> section of your Maven build:

      <plugin>
<!-- Configure the compiler. -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!-- Note that this 'release' parameter was introduced in JDK 9. -->
<release>8</release>
</configuration>
</plugin>

What you cannot do though, is compile Java 11 bytecode using JDK 8. If you want to generate Java 11 bytecode and use newer Java features introduced after Java 8, just install a JDK 11 release on your development machine.

As noted by meaningqo in the comments above, you are generally better of developing and building on the same major Java version as your target environment unless you need to target multiple (major) Java versions. Java is backwards compatible, but there are always quirks that can trip you up, and if you have any dependencies in your project you may find that these do not always work in a newer Java version even if they run fine on Java 8, or that you need a newer version of that dependency for Java 11 that won't work with Java 8.

How to specify Java version in Spring/Spring Boot pom.xml?

Short Answer:

The correct way is to use the followings values in <java.version> for different Java versions:

  • Java 8 : 1.8 or 8
  • Java 9 : 9
  • Java 10 : 10
  • Java 11 : 11
  • Java 12 : 12
  • .....
  • .....
  • Java 16 : 16
  • Java 17 : 17

So for Java 11 , it should be:

<properties>
<java.version>11</java.version>
</properties>

However I'm not sure if Java 11 would be "1.11" (seems unlikely), and
I've seen it specified as just "11" when using maven-compiler-plugin,
however I'm not using the compiler plugin.

Actually , at the end it still uses maven-compiler-plugin to compile. Springboot just configures a <java.version> property such that by changing this value , you are implicitly changing maven-compiler-plugin 's <source/> and <target/> to the same value as what specified in the <java.version> :

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>11</source> <!-- same as <java.version> -->
<target>11</target> <!-- same as <java.version> -->
</configuration>
</plugin>

Detailed Answer:

Seem like you want details to convince you.

It is because every spring boot project will extend the parent pom spring-boot-starter-parent which defines <java.version> as follows:

<properties>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>

From the maven-compiler-plugin docs, maven.compiler.source and maven.compiler.target are the user property for the <source> and <target> config parameters. Due to the behaviour of the user property, setting these two properties to 11 means to set the following :

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>11</source> <!-- maven.compiler.source -->
<target>11</target> <!-- maven.compiler.target -->
</configuration>
</plugin>

From the maven-compiler-plugin docs again, <source> and <target> are the -source and -target argument for the Java compiler (javac). Then, from javac docs, we can see that these two arguments are allowed to have the following values:

  • 1.6 : No language changes were introduced in Java SE 6. However, encoding errors in source files are now reported as errors instead of
    warnings as was done in earlier releases of Java Platform, Standard Edition.
  • 6 : Synonym for 1.6.
  • 1.7 : The compiler accepts code with features introduced in Java SE 7.
  • 7 : Synonym for 1.7.
  • 1.8 : The compiler accepts code with features introduced in Java SE 8.
  • 8 : Synonym for 1.8.
  • 9 : The compiler accepts code with features introduced in Java SE 9.
  • 10 : The compiler accepts code with features introduced in Java SE 10.
  • 11 : The compiler accepts code with features introduced in Java SE 11.
  • 12 : The compiler accepts code with features introduced in Java SE 12.

Hence, <java.version> should be set to 11 for Java 11.

Adding local jars to Java projects with Java 10

I think this might be related to this question.

Basically, I don't think your problem is related to the local jar - If you've installed it in your local maven repository ($USER_HOME/.m2) using the maven install plugin, it has a pom.xml and to maven shouldn't be distinguishable from any other maven dependency.

The only thing I see "wrong" is the version of the maven compiler plugin - the current version is 3.8.0, which I'm using with Java 11 without any issues so far.
Also, note that the mechanism to set the source and target java releases changed, as in the following snippet:

    <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>10</release>
</configuration>
</plugin>
</plugins>
</build>

Maven is not using Java 11: error message Fatal error compiling: invalid target release: 11

It seems like you're having the JAVA_HOME set in your mvn.bat. It could be pointing to the older version of Java (i.e., 8 in your case).

set JAVA_HOME=C:\path\to\jdk11. Try using it on the first line, before calling Maven.



Related Topics



Leave a reply



Submit