简体   繁体   中英

Is it possible to compile Java11 code to Java8 bytecode and run on 8?

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]

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

For idea use

在此处输入图片说明

It`s works for me

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM