Можно ли скомпилировать код Java11 в байт-код Java8 и запустить на 8?

Я играю с некоторыми зависимостями и компиляцией в более старые выпуски с использованием java 11. Я перенес одну зависимость на Java 11 и работает нормально, но нам все еще нужно запустить Tomcat 7 или 8 на Java8. Можно ли использовать флаг --release для компиляции кода, который использует var, stream().dropwhile(...) или Map.of(...) и работает на 8?

Флаг выпуска предполагает, что это должно быть возможно:

--release release Компилируется с общедоступным, поддерживаемым и документированным API для конкретной версии виртуальной машины. Поддерживаемые цели выпуска: 6, 7, 8 и 9.

Этот проект является зависимым, автономно работает нормально с SprinBoot2.1 и Java11, но должен быть запущен в Java8.

Мои настройки компилятора плагина maven:

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

но это запрещает компилировать> специфический код jdk8. Я использую последний Maven 3.6.0 и компилятор MVN, как указано выше.

Попытка скомпилировать:

return List.of("dsadas", "dasdadddds", "£dsada", "dasdas")
        .stream()
        .dropWhile(s -> s.contains("das"))
        .collect(Collectors.toList());

выдает ошибку:

[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]

Ответы

Ответ 1

Это невозможно. Разрешены только методы и классы API целевой платформы Java.

Это определено в JEP 247: Компиляция для более старых версий платформы

Определен новый параметр командной строки, --release, который автоматически настраивает компилятор для создания файлов классов, которые будут связаны с реализацией данной версии платформы.

Соответствующая часть, которая говорит, что может быть использовано:

Для N <9 документированные API состоят из общедоступных API, которые были по умолчанию в javac bootclasspath для JDK N.

Для N> = 9 документированные API состоят из (i) API, экспортированных из тех модулей в образе JDK, которые являются частью документации JDK N; и (ii) API, экспортированный из модуля jdk.unsupported (задокументировано в JEP 260).

Ответ 2

Теперь это возможно с https://github.com/bsideup/jabel

Jabel - плагин javac 12, который заставляет его испускать байт-код Java 8