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
How to Implement Constants in Java
Does Use of Final Keyword in Java Improve the Performance
Javafx Fxml Controller - Constructor VS Initialize Method
"Program to an Interface". What Does It Mean
Java Array, Finding Duplicates
What Is the Garbage Collector in Java
How to Set the Classpath in Netbeans
How to Make an Image Move While Listening to a Keypress in Java
What Is @Modelattribute in Spring MVC
How to Tell If I'm Running in 64-Bit Jvm or 32-Bit Jvm (From Within a Program)
Java Class That Implements Map and Keeps Insertion Order
Scanner VS. Stringtokenizer VS. String.Split
Multiple Returns: Which One Sets the Final Return Value
Implements VS Extends: When to Use? What's the Difference
Java.Rmi.Serverexception: Remoteexception Occurred in Server Thread (Classnotfoundexception)