Доступ 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, это решит проблему сборки моего знаток
В интелджи:
шаг 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.