I'm playing with some dependencies and compilation to older releases using java 11. I migrated one dependency to Java 11 and works fine, but we still have to run it Tomcat 7 or 8 on Java8. Is it possible to use the --release
flag to compile code which uses var
, stream().dropwhile(...)
or Map.of(...)
and run on 8?
Release flag suggest that it should be possible:
--release release Compiles against the public, supported and documented API for a specific VM version. Supported release targets are 6, 7, 8, and 9.
This project is a dependency, stand-alone works fine with SprinBoot2.1 and Java11, but needs to be run in Java8.
My maven plugin compiler settings:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>8</release>
</configuration>
</plugin>
but this forbids compiling >jdk8 specific code. I'm using latest maven 3.6.0 and mvn compiler as above.
Attempt to compile:
return List.of("dsadas", "dasdadddds", "£dsada", "dasdas")
.stream()
.dropWhile(s -> s.contains("das"))
.collect(Collectors.toList());
throws error:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project api: Compilation failure: Compilation failure:
[ERROR] /home/agilob/Projects/.....java:[58,13] cannot find symbol
[ERROR] symbol: class var
[ERROR] location:
[ERROR] /home/agilob/Projects/....java:[43,20] cannot find symbol
[ERROR] symbol: method of(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
[ERROR] location: interface java.util.List
[ERROR] -> [Help 1]
The class files created by Java 8 are still executable in Java 11; however, there have been other changes in the Java runtime (library changes, etc.) that might require modification of the code. These modifications may be made in Java 8 and compiled with Java 8 making it compatible with the Java 11 runtime.
In general Java is extremely backward compatible. There have been a few minor breaking changes from JDK 8 to JDK 17, but the worst ones have had command-line options to disable them.
It is not possible. Only the API methods and classes of the targeted Java platform are allowed.
That is defined in JEP 247: Compile for Older Platform Versions
A new command-line option, --release, is defined, which automatically configures the compiler to produce class files that will link against an implementation of the given platform version.
The relevant part that says what can be used is:
For N < 9, the documented APIs consist of the public APIs that were on javac's default bootclasspath for JDK N.
For N >= 9, the documented APIs consist of (i) the APIs exported from those modules in the JDK image which are part of the documentation of JDK N; and (ii) the API exported from the jdk.unsupported module (documented in JEP 260).
It is possible now with https://github.com/bsideup/jabel
Jabel - javac 12 plugin that makes it emit Java 8 bytecode
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