Доступ Lombok к внутренним пакетам jdk.compiler несовместим с Java-16

Просто обновление одного из моих проектов с Java-15 до 16 лет (используя последнюю версию здесь ). При компиляции проекта, в котором используется ломбок, например:

      <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.16</version>
</dependency>

Я как бы застрял с трассировкой стека

      Caused by: java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor (in unnamed module @0x4e670245) cannot access class com.sun.tools.javac.processing.JavacProcessingEnvironment (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.processing to unnamed module @0x4e670245
    at lombok.javac.apt.LombokProcessor.getJavacProcessingEnvironment (LombokProcessor.java:433)
    at lombok.javac.apt.LombokProcessor.init (LombokProcessor.java:92)
    at lombok.core.AnnotationProcessor$JavacDescriptor.want (AnnotationProcessor.java:160)
    at lombok.core.AnnotationProcessor.init (AnnotationProcessor.java:213)
    at lombok.launch.AnnotationProcessorHider$AnnotationProcessor.init (AnnotationProcessor.java:64)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.<init> (JavacProcessingEnvironment.java:702)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next (JavacProcessingEnvironment.java:829)

Теперь, по крайней мере, как я думал, я знал, как решить эту проблему, но даже попробовав следующую конфигурацию на maven-compiler-plugin

      <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <source>16</source>
        <target>16</target>
        <!--                    <release>16</release>-->
        <compilerArgs>
            <arg>--enable-preview</arg>
            <arg>-Xlint:all</arg>
            <arg>--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
        </compilerArgs>
        <!--for unmappable characters in classes-->
        <encoding>UTF-8</encoding>
        <showDeprecation>true</showDeprecation>
        <showWarnings>true</showWarnings>
        <!--for lombok annotations to resolve-->
        <!--contradictory to maven, intelliJ fails with this-->
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.16</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

Кто-нибудь смог решить эту проблему или уйти от нее?

Изменить : ссылка, предоставленнаяЙорном в комментариях , действительно относится к той же проблеме на GitHub, но предложенные решения по-прежнему не работают. Таким образом, я также добавил следующие аргументы:

      <arg>--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
<arg>--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>

13 ответов

Решение

Обновление:

Lombok v1.18.20 поддерживает JDK 16 из коробки .


Исключение, которое вы видите в последней сборке JDK-16, связано с JEP 396: Strongly Encapsulate JDK Internals по умолчанию . Lombok обращается к внутреннему API JDK с отражением, и если в предыдущих версиях Java это приводило к предупреждающему сообщению, теперь это приводит к серьезной ошибке.

В общем, можно явно открыть внутренние пакеты JDK для отражения при запуске java, передав --add-opens=<module>/<package>=<accessing module>директивы в качестве аргументов виртуальной машины при запуске. В этом случае эти директивы необходимо передать в javaпроцесс, который запускается при вызове. Это можно сделать, поставив перед параметром префикс, который вместо этого передаст его в базовую JVM.

Используя Maven, я смог заставить его работать со следующей конфигурацией плагина компилятора:

      <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <source>16</source>
        <target>16</target>
        <!--                    <release>16</release>-->
        <fork>true</fork>
        <compilerArgs>
            <arg>--enable-preview</arg>
            <arg>-Xlint:all</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
            <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED</arg>
        </compilerArgs>
        <!--for unmappable characters in classes-->
        <encoding>UTF-8</encoding>
        <showDeprecation>true</showDeprecation>
        <showWarnings>true</showWarnings>
        <!--for lombok annotations to resolve-->
        <!--contradictory to maven, intelliJ fails with this-->
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.16</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

Где необходимые параметры передаются с помощью элементов конфигурации.

Обратите внимание, что я добавил перед параметрами, чтобы передать их запущенной JVM, а не javac параметры.

Сверху --add-opens директивы, перечисленные в вопросе, дополнительно:

      -J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED

тоже был нужен.

<fork>true</fork> также было необходимо, поскольку в противном случае -J варианты игнорировались (судя по выводам mvn clean install -X). Глядя на документацию Maven, кажется, что установка необходима в любое время при использовании:

https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#compilerArgs

<compilerArgs> Устанавливает аргументы, передаваемые компилятору, если fork установлен на true.

Обновление версии lombok до 1.18.20исправил это для меня. Итак, если вы можете обновить ломбок, я бы порекомендовал это сделать.

      <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
</dependency>

Для тех из вас, кто использует Java 11 или любую версию, отличную от новейших версий, имейте в виду, что IntelliJ может использовать свою собственную версию Maven, подключенную к JDK 16/17, что вызывает указанную выше ошибку при выполнении из терминала IntelliJ.

Чтобы проверить фактический используемый JDK, введите терминал, и вы можете получить такой же сюрприз, как и я (я даже не знал, что у меня JDK 17):

      Maven home: /usr/local/Cellar/maven/3.8.4/libexec
Java version: 17.0.1, vendor: Homebrew, runtime: /usr/local/Cellar/openjdk/17.0.1_1/libexec/openjdk.jdk/Contents/Home
Default locale: en_BG, platform encoding: UTF-8
OS name: "mac os x", version: "11.3.1", arch: "x86_64", family: "mac"

При этом при проверке получаю Java 11 java --version.

Решение здесь состояло в том, чтобы выполнить mvn clean installс помощью кнопки Maven Goal на вкладке Maven справа:

Он правильно использовал JDK 11, что также можно проверить через mvn --version.

Чтобы помочь пользователям Gradle, которые, возможно, попали в эту тему.

Для тех, кто использует Gradle, чтобы правильно настроить Lombok, используйте compileOnly а также annotationProcessor в build.gradle файл.

      // Lombok
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'

То же самое для test dependencies если вы тоже используете Lombok:

      testCompileOnly 'org.projectlombok:lombok:1.18.20'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'

Кроме того, если вы хотите явно сгенерировать свои байт-коды с таргетингом JDK 16, использовать:

      sourceCompatibility = '16'
targetCompatibility = '16'

Источник:
настройка Lombok и Gradle
Gradle sourceCompatibility и targetCompatibility

если вы используете macos с jenv, причина этой проблемы в том, что переменная среды JAVA_HOME не активна, просто сделайте следующее:

      jenv enable-plugin export

затем снова откройте сеанс терминала и введите echo $JAVA_HOME

Вам нужно изменить версию SDK.

Если вы используете IntelliJ IDEA File>Project Structure и выбираете вкладку «Project» слева. Project SDK должен быть 1.8 или любой другой, что вы используете в проекте. Версия Java 16.0.1 не поддерживает доступ к этой версии ломбока

Для тех, если ничего из вышеперечисленного не работает

Для меня проблема заключалась в версии Java, используемой maven. при установке maven он автоматически устанавливает совместимую версию jdk и использует ее по умолчанию. что можно проверить по mvn -version

      Apache Maven 3.8.6 (someGUID)
Maven home: /opt/homebrew/Cellar/maven/3.8.6/libexec
Java version: 18.0.2.1, vendor: Homebrew, runtime: /opt/homebrew/Cellar/openjdk/18.0.2.1/libexec/openjdk.jdk/Contents/Home
Default locale: en_IN, platform encoding: UTF-8
OS name: "mac os x", version: "12.5.1", arch: "aarch64", family: "mac"

но версия java, которая используется на машине и в проекте, может отличаться, например:

      java -version
java version "11.0.16.1" 2022-08-18 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.16.1+1-LTS-1)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.16.1+1-LTS-1, mixed mode)

поэтому проблема связана с версией maven java; который можно решить, выполнив команду

      `export JAVA_HOME=~{pathToLibrary}/Library/Java/JavaVirtualMachines/jdk-11.0.16.1.jdk/Contents/Home/`

который изменит версию Java, которую использует maven, и то же самое можно проверить с помощью

      `mvn -version
Apache Maven 3.8.6 (someGUID)
Maven home: /opt/homebrew/Cellar/maven/3.8.6/libexec
Java version: 11.0.16.1, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-11.0.16.1.jdk/Contents/Home
Default locale: en_IN, platform encoding: UTF-8
OS name: "mac os x", version: "12.5.1", arch: "aarch64", family: "mac"`

Надеюсь это поможет.

Это решило мою проблему с Windows и Intellij. Мой проект использовалjava 1.8но мой maven по умолчанию не использовалjava 17потому что на моей машине установлены как Java 1.8, так и 17. Я обновил версию Java для своего maven, просто добавивset JAVA_HOME=C:\Program Files\Java\jdk1.8.0_211\jreв мойmvn.batфайл, который вы должны найти в том месте, где находится ваше программное обеспечение maven.

Для проверки вы можете запуститьmvn --versionи в ответ он должен отобразить версию Java 1.8.

В роли Петара Биволарски

Я обнаружил, что версия JDK для maven относится к JDK 18, в то время как мое приложение должно работать на JDK 11, поэтому я изменил JAVA_HOME на своем компьютере, чтобы указать правильную версию JDK, это решит проблему сборки моего знаток

Обновите зависимость lombok до 1.18.20

В интелджи:

шаг 1: щелкните правой кнопкой мыши свой проект -> Открыть настройки модуля

шаг 2: на вкладке «Зависимости» все настройки вашего проекта jdk соответствуют jdk, которые у вас есть.

шаг 3: нажмите кнопку применить.

введите описание изображения здесь

введите описание изображения здесь

Мне нужно удалить это из pom.xml, чтобы проект мог быть успешно собран и запущен и использовать только зависимость lombok.

                  <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <encoding>${project.build.sourceEncoding}</encoding>
                <generatedSourcesDirectory>${project.build.directory}/generated-sources/</generatedSourcesDirectory>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${version.mapstruct}</version>
                    </path>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>${version.lombok}</version>
                    </path>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok-mapstruct-binding</artifactId>
                        <version>${version.mapstruct-lombok}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>

Что я нашел, так это установить переменную JAVA_HOME. Если вы не знаете, что это такое, вы можете запустить эту команду, чтобы найти его.

      java -XshowSettings:properties -version 2>&1 > /dev/null | grep 'java.home'

И установите значение в вашем файле RC на JAVA_HOME.

Другие вопросы по тегам