84

Simply upgrading one of my projects from Java-15 to 16 (using the latest build here). On compiling the project which uses lombok such as:

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

I am kind of stuck with the stack trace

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)

Now, at least as I thought I knew a hack to get this resolved, but even on trying the following configuration on 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>

Has anyone been able to resolve or get away with this?

Edit: The link, provided by Jorn in comments, does relate to the same problem on GitHub, but the solutions proposed still doesn't really work. Such that I have added the following args as well:

<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>
Naman
  • 27,789
  • 26
  • 218
  • 353
  • 2
    Looks like there's an open issue on this as well: https://github.com/rzwitserloot/lombok/issues/2681 There's more than 1 add-opens that is needed it seems. – Jorn Vernee Dec 20 '20 at 13:38
  • @JornVernee thank you for that link, simply using `-add-opens` for all those packages weren't working either for me. – Naman Dec 20 '20 at 14:05
  • 2
    Looking at the maven `-X` output, it is not adding the needed flags to the command line when running the annotation processor. (note that you also need `-J` in front of the flag, so that it is passed to the javac process itself). If I take mavens command, and add the missing `-J--add-opens` to it manually, it works. – Jorn Vernee Dec 20 '20 at 14:08
  • I really am not sure, what is the focus supposed to be. But I have edited the question with all the hopes of reopening instead of opening a new one. – Naman Dec 20 '20 at 14:08
  • 3
    Well, since the question is now closed I'll post this here: Was able to make it work after adding `true` to the compiler plugin config and adding one more missing `-J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED`. – Jorn Vernee Dec 20 '20 at 14:30
  • @JornVernee Surely, it does work. Once, the question reopens(hopefully it does) please post that as an answer. I would have never imagined using the additional process(`fork`) for passing on the parameters and additionally the failure without `com.sun.tools.javac.jvm` is silent such that even debug logs just point "Compilation failure" and nothing additional there for the cause. Thank you(glad you have made a comment on GitHub for project owners as well). – Naman Dec 20 '20 at 14:55
  • 4
    I think the logs not containing the exact error is a consequence of using fork=true. I saw a clearer exception when manually running javac. The maven docs were a hint as to needing fork=true: https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html#compilerArgs "`` Sets the arguments to be passed to the compiler if `fork` is set to `true`". I'll post the config I used here as well if the question gets reopened. – Jorn Vernee Dec 20 '20 at 14:58
  • reopened. pls post the answer, too. – eis Dec 20 '20 at 15:47
  • 1
    @JornVernee question reopened – Fenio Dec 20 '20 at 15:51

12 Answers12

100

Update:

Lombok v1.18.20 supports JDK 16 out of the box.

In the same thread, one of the maintainers also writes:

We have some less well known loopholes we can use to bridge a few gaps. We'll start work on gradle and maven plugins in the mean time, which will be a long-term fix.


Original:

The exception you are seeing with the latest JDK-16 build is because of JEP 396: Strongly Encapsulate JDK Internals by Default. Lombok is accessing an internal JDK API with reflection, and where in previous Java versions this would result in a warning message, it now results in a hard error.

In general, it is possible to explicitly open internal JDK packages for reflection when running java by passing --add-opens=<module>/<package>=<accessing module> directives as VM arguments when running java. In this case these directives would need to be passed to the java process that runs when invoking javac. This can be done by prefixing the option passed to javac with -J, which will instead pass it to the underlying JVM.

Using Maven, I was able to make it work with the following compiler plugin config:

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

Where the needed options are passed using <compilerArgs> elements in the configuration.

Note that I added -J in front of the options in order to pass them to the JVM running javac, instead of javac options.

On top of the --add-opens directives listed in the question, an additional:

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

was also needed.

<fork>true</fork> was also needed since otherwise the -J options were being ignored (judging from the output of mvn clean install -X). Looking at the Maven docs, setting fork to true seems to be needed any time when using <compilerArgs>:

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

<compilerArgs> Sets the arguments to be passed to the compiler if fork is set to true.

kevinarpe
  • 20,319
  • 26
  • 127
  • 154
Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
  • 1
    Would add a bounty soon. But maybe with a lead towards how Lombok should be able to move ahead towards the permanent fix. – Naman Dec 20 '20 at 17:59
  • 1
    it would be rather complicated to explain to everyone on my team why so many things are added into the maven config so that lombok would work. There are `record`s that make somehow lombok obsolete, the only thing I would miss would be `@Accessor(chain=true)` that I use a lot – Eugene Dec 20 '20 at 20:07
  • 1
    @Eugene true, you are still in a better state, imagine while performing a proof of concepts for migration, you tell people, that one of their BOM dependency is incompatible with the upgrade! more crucially, handling noise from those who have been using the library for any random annotation without even being concerned of its _necessity_. then pitching all of this to architects is another chain of struggle in itself. one that I think was helping me clean up a lot of code was `@RequiredArgsConstructor(onConstructor = @__(@Inject))`. fingers crossed, yet to try out injection on Java-16. – Naman Dec 21 '20 at 02:26
  • 35
    It’s funny, how it always escalates the same way. *JDK issues a warning* → “but it still works”, some years later: *JDK produces an error* → “but I can make it work with an option”, yet another years later *hack stops working completely* → “why are they suddenly break compatibility?” – Holger Dec 21 '20 at 11:20
  • 3
    Yeah, we definitely reached warning fatigue for illegal access warnings. I blame both sides - library authors by continuing to use that, and OpenJDK by not looking for why people requires it. I still don't know of a supported replacement for `java.io.Console.cs`. But the same thing is exposed as shared secret - because some other part of OpenJDK depends on it. – Johannes Kuhn Dec 22 '20 at 01:13
  • 2
    FWIW, a `Console::charset()` method is added in JDK 17: https://github.com/openjdk/jdk/pull/3419 – Jorn Vernee Sep 01 '21 at 14:12
33

Upgrading lombok version to 1.18.20 fixed it for me. So, if you can upgrade lombok, I'd recommend doing so.

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
</dependency>
praty
  • 914
  • 9
  • 11
17

For those of you using Java 11 or any different one from the newest versions, keep in mind that IntelliJ can use its own Maven version hooked to JDK 16/17, thereby causing the error above when doing mvn clean install from the IntelliJ terminal.

To check the actual JDK used, type mvn --version in the terminal, and you might get a surprise like I did (I didn't even know I had 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"

At the same time, I get Java 11 when checking java --version.

The solution here was to execute mvn clean install via the Maven Goal button in the Maven tab to the right:

enter image description here

It correctly used the JDK 11, which can also be verified via mvn --version.

Petar Bivolarski
  • 1,599
  • 10
  • 19
6

To help Gradle users that perhaps get in this topic.

For those using Gradle, to configure Lombok properly, use compileOnly and annotationProcessor in the build.gradle file.

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

The same for test dependencies if you are using Lombok there too:

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

Also, if you would like to explicitly generate your bytecodes targeting JDK 16, use:

sourceCompatibility = '16'
targetCompatibility = '16'

Source:
Set up Lombok and Gradle
Gradle sourceCompatibility and targetCompatibility

Juliano Macedo
  • 668
  • 8
  • 21
  • 2
    If you're looking for a version that is compatible with JDK 17, go for 1.18.22. Source: https://projectlombok.org/changelog – Rangana Udara May 26 '22 at 07:28
5

if you use macos with jenv, The reason for this problem is that the environment variable JAVA_HOME is not active, Simply do the following:

jenv enable-plugin export

then reopen a terminal session and type echo $JAVA_HOME

Brook
  • 109
  • 1
  • 7
1

You need to change your sdk version.

If you use IntelliJ IDEA File>Project Structure and select 'project' tab from the left side. Project SDK should be 1.8 or whatever you use in the project. Java version 16.0.1 doesnt support for access this version of lombok

A. Berk
  • 127
  • 1
  • 3
1

As Petar Bivolarski

I've found the JDK version for maven was referring to JDK 18, while my application should run on JDK 11, so I've changed the JAVA_HOME on my machine to refer the correct version of JDK, this will resolve the build problem of my maven.

Hany Sakr
  • 2,591
  • 28
  • 27
1

For Those if none of the above works

For me the issue was java version used by maven. while installing maven, it automatically install its compatible jdk version and uses it by default. which can be checked by 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"

but the java version which is on the machine and project using may be different like:

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)

so the issue is with the maven java version; which can be resolved by running the command

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

which will change the java version which maven is using and same can be verified by

`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"`

Hope this helps.

1

This solved my issue with windows and intellij. My project was using java 1.8 but my maven was defaulting to java 17 because I have both java 1.8 and 17 on my machine. I updated the java version for my maven by simply adding set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_211\jre into my mvn.bat file which you should find in the location where your maven software is located.

To verify, you can run mvn --version and it should display the java version 1.8 in response.

0

What I found was to set my JAVA_HOME variable. If you don't know what that is you can run this command to find it.

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

And set the value in your RC file to JAVA_HOME.

reka18
  • 7,440
  • 5
  • 16
  • 37
0

In intellji:

step 1: right click your project -> Open Module Settings

step 2: in tab Dependencies setting all your project jdk matches jdk you have.

step 3: click button apply.

enter image description here

enter image description here

0

I need to delete this from pom.xml in order the project to build and start succesfully and use only lombok dependency.

            <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>
troger19
  • 1,159
  • 2
  • 12
  • 29