projectlombok / lombok

Very spicy additions to the Java programming language.
https://projectlombok.org/
Other
12.83k stars 2.37k forks source link

[FEATURE] JDK 23 compatibility #3722

Open mmoayyed opened 1 month ago

mmoayyed commented 1 month ago

Describe the feature

Allow lombok to support building against JDK 23.

Describe the target audience

While JDK 23 is still in RC mode as of this writing, there are RC builds available nonetheless that one can use for experimentation and preparation against the next JDK release.

Additional context

Lombok today, 1.8.34, seems unable to build against JDK 23. To start with, there is the following error:

error: An unhandled exception was thrown by the Error Prone static analysis plugin.
     Please report this at https://github.com/google/error-prone/issues/new and include the following:

     error-prone version: 2.30.0
     BugPattern: (see stack trace)
     Stack Trace:
     java.lang.NoSuchFieldError: Class com.sun.tools.javac.parser.Tokens$Comment$CommentStyle does not have member field 'com.sun.tools.javac.parser.Tokens$Comment$CommentStyle JAVADOC'
        at lombok.javac.Javac$JavadocOps_8$1.getStyle(Javac.java:364)
        at jdk.compiler/com.sun.tools.javac.parser.DocCommentParser.getTextKind(DocCommentParser.java:171)
        at jdk.compiler/com.sun.tools.javac.parser.DocCommentParser.<init>(DocCommentParser.java:164)
        at jdk.compiler/com.sun.tools.javac.parser.DocCommentParser.<init>(DocCommentParser.java:139)
        at jdk.compiler/com.sun.tools.javac.api.JavacTrees.getDocCommentTree(JavacTrees.java:1129)
        at jdk.compiler/com.sun.tools.javac.parser.LazyDocCommentTable.getCommentTree(LazyDocCommentTable.java:101)
        at jdk.compiler/com.sun.tools.javac.api.JavacTrees.getDocCommentTree(JavacTrees.java:759)
        at com.google.errorprone.bugpatterns.javadoc.Utils.getDocCommentTree(Utils.java:132)
        at com.google.errorprone.bugpatterns.javadoc.Utils.getDocTreePath(Utils.java:124)
        at com.google.errorprone.bugpatterns.javadoc.EmptyBlockTag.checkForEmptyBlockTags(EmptyBlockTag.java:81)
        at com.google.errorprone.bugpatterns.javadoc.EmptyBlockTag.matchVariable(EmptyBlockTag.java:76)
        at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:449)
        at com.google.errorprone.scanner.ErrorProneScanner.visitVariable(ErrorProneScanner.java:884)
        at com.google.errorprone.scanner.ErrorProneScanner.visitVariable(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:1081)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:95)
        at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:110)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:118)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitClass(TreeScanner.java:202)
        at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:548)
        at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:896)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:110)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:118)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitCompilationUnit(TreeScanner.java:151)
        at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:560)
        at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:625)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:66)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:58)
        at com.google.errorprone.scanner.ErrorProneScannerTransformer.apply(ErrorProneScannerTransformer.java:43)
        at com.google.errorprone.ErrorProneAnalyzer.finished(ErrorProneAnalyzer.java:227)
        at jdk.compiler/com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:133)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1432)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1379)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:964)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
        at org.gradle.internal.compiler.java.IncrementalCompileTask.call(IncrementalCompileTask.java:92)
        at org.gradle.api.internal.tasks.compile.AnnotationProcessingCompileTask.call(AnnotationProcessingCompileTask.java:94)
        at org.gradle.api.internal.tasks.compile.ResourceCleaningCompilationTask.call(ResourceCleaningCompilationTask.java:57)
        at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:76)
        at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:46)
        at org.gradle.api.internal.tasks.compile.daemon.AbstractIsolatedCompilerWorkerExecutor$CompilerWorkAction.execute(AbstractIsolatedCompilerWorkerExecutor.java:78)
        at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
        at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:54)
        at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:48)
        at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
        at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:48)
        at org.gradle.workers.internal.FlatClassLoaderWorker.run(FlatClassLoaderWorker.java:32)
        at org.gradle.workers.internal.FlatClassLoaderWorker.run(FlatClassLoaderWorker.java:22)
        at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:103)
        at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:72)
        at org.gradle.process.internal.worker.request.WorkerAction$1.call(WorkerAction.java:152)
        at org.gradle.process.internal.worker.child.WorkerLogEventListener.withWorkerLoggingProtocol(WorkerLogEventListener.java:41)
        at org.gradle.process.internal.worker.request.WorkerAction.lambda$run$1(WorkerAction.java:149)
        at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:85)
        at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:141)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
        at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
        at java.base/java.lang.Thread.run(Thread.java:1575)
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

Originally reported here: https://github.com/google/error-prone/issues/4532

Judging by the trace, this line seems to suggest that this is more of a Lombok issue, rather than Gradle or Error Prone:

java.lang.NoSuchFieldError: Class com.sun.tools.javac.parser.Tokens$Comment$CommentStyle does not have member field 'com.sun.tools.javac.parser.Tokens$Comment$CommentStyle JAVADOC'
        at lombok.javac.Javac$JavadocOps_8$1.getStyle(Javac.java:364)

JDK:

openjdk version "23" 2024-09-17
OpenJDK Runtime Environment (build 23+36-2368)
OpenJDK 64-Bit Server VM (build 23+36-2368, mixed mode, sharing)

Gradle:

------------------------------------------------------------
Gradle 8.10-rc-1
------------------------------------------------------------

Build time:    2024-08-08 06:07:55 UTC
Revision:      4f143ee84909970e5148c38b3ac7db3ff826a022

Kotlin:        1.9.24
Groovy:        3.0.22
Ant:           Apache Ant(TM) version 1.10.14 compiled on August 16 2023
Launcher JVM:  23 (Oracle Corporation 23+36-2368)
Daemon JVM:    /Library/Java/JavaVirtualMachines/jdk-23.jdk/Contents/Home (no JDK specified, using current Java home)
OS:            Mac OS X 14.5 aarch64

Related: https://github.com/projectlombok/lombok.patcher/pull/15

mickaelistria commented 5 days ago

I can reproduce this error in some other context (also involving calling compilation task programatically): https://ci.eclipse.org/ls/job/jdt-ls-javac/lastCompletedBuild/testReport/org.eclipse.jdt.ls.core.internal.handlers/RenameHandlerTest/testLombokSingular/ I suspect the culprit line is https://github.com/projectlombok/lombok/blob/1ac3950a9e8d1c2da0ff0d6400386a9b345b23a2/src/utils/lombok/javac/Javac.java#L364 , which makes lombok add into the AST an incompatible node. Since Java 23, the possible values for CommentStyle are https://github.com/openjdk/jdk/blob/4b7906375b4bd11a480665110561180825c2dd9c/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java#L276...L281

mingchiuli commented 3 days ago

GraalVM compatibility:

> Task :micro-gateway:compileJava FAILED
error: Error during the transformation of 'org.chiu.micro.gateway.router.Router'; post-compiler 'lombok.bytecode.SneakyThrowsRemover' caused an exception: java.lang.IllegalArgumentException: Unsupported class file major version 67
    at org.lombokweb.asm.ClassReader.<init>(ClassReader.java:200)
    at org.lombokweb.asm.ClassReader.<init>(ClassReader.java:180)
    at org.lombokweb.asm.ClassReader.<init>(ClassReader.java:166)
    at lombok.bytecode.AsmUtil.fixJSRInlining(AsmUtil.java:37)
    at lombok.bytecode.SneakyThrowsRemover.applyTransformations(SneakyThrowsRemover.java:46)
    at lombok.core.PostCompiler.applyTransformations(PostCompiler.java:44)
    at lombok.core.PostCompiler$1.close(PostCompiler.java:87)
    at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeClass(ClassWriter.java:1548)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:771)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1700)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1668)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:977)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
    at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
    at org.gradle.internal.compiler.java.IncrementalCompileTask.call(IncrementalCompileTask.java:92)
    at org.gradle.api.internal.tasks.compile.AnnotationProcessingCompileTask.call(AnnotationProcessingCompileTask.java:94)
    at org.gradle.api.internal.tasks.compile.ResourceCleaningCompilationTask.call(ResourceCleaningCompilationTask.java:57)
    at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:76)
    at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:46)
    at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:98)
    at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:52)
    at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:38)
    at org.gradle.api.internal.tasks.compile.AnnotationProcessorDiscoveringCompiler.execute(AnnotationProcessorDiscoveringCompiler.java:52)
    at org.gradle.api.internal.tasks.compile.AnnotationProcessorDiscoveringCompiler.execute(AnnotationProcessorDiscoveringCompiler.java:38)
    at org.gradle.api.internal.tasks.compile.ModuleApplicationNameWritingCompiler.execute(ModuleApplicationNameWritingCompiler.java:46)
    at org.gradle.api.internal.tasks.compile.ModuleApplicationNameWritingCompiler.execute(ModuleApplicationNameWritingCompiler.java:[36](https://github.com/mingchiuli/megalith-micro/actions/runs/10904698290/job/30261760666#step:5:37))
    at org.gradle.jvm.toolchain.internal.DefaultToolchainJavaCompiler.execute(DefaultToolchainJavaCompiler.java:57)
    at org.gradle.api.tasks.compile.JavaCompile.lambda$createToolchainCompiler$3(JavaCompile.java:204)
    at org.gradle.api.internal.tasks.compile.CleaningJavaCompiler.execute(CleaningJavaCompiler.java:53)
    at org.gradle.api.internal.tasks.compile.incremental.IncrementalCompilerFactory.lambda$createRebuildAllCompiler$0(IncrementalCompilerFactory.java:52)
    at org.gradle.api.internal.tasks.compile.incremental.SelectiveCompiler.execute(SelectiveCompiler.java:70)
    at org.gradle.api.internal.tasks.compile.incremental.SelectiveCompiler.execute(SelectiveCompiler.java:44)
    at org.gradle.api.internal.tasks.compile.incremental.IncrementalResultStoringCompiler.execute(IncrementalResultStoringCompiler.java:66)
    at org.gradle.api.internal.tasks.compile.incremental.IncrementalResultStoringCompiler.execute(IncrementalResultStoringCompiler.java:52)
    at org.gradle.api.internal.tasks.compile.CompileJavaBuildOperationReportingCompiler$1.call(CompileJavaBuildOperationReportingCompiler.java:64)
    at org.gradle.api.internal.tasks.compile.CompileJavaBuildOperationReportingCompiler$1.call(CompileJavaBuildOperationReportingCompiler.java:[48](https://github.com/mingchiuli/megalith-micro/actions/runs/10904698290/job/30261760666#step:5:49))
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
0x3C50 commented 3 days ago

OpenJDK 23 also throws the above error. The ASM shadow can't handle version 23 bytecode.

mmoayyed commented 2 days ago

Aside from the Javadoc error, lombok-patcher needs to be released first: https://github.com/projectlombok/lombok.patcher/pull/15

and then lombok should be updated to use the new patcher.

HenrikPublic commented 2 days ago

It looks like SneakyThrowsRemover also needs some fiddling:

post-compiler 'lombok.bytecode.SneakyThrowsRemover' caused an exception: java.lang.IllegalArgumentException: Unsupported class file major version 67
        at org.lombokweb.asm.ClassReader.<init>(ClassReader.java:200)
        at org.lombokweb.asm.ClassReader.<init>(ClassReader.java:180)
        at org.lombokweb.asm.ClassReader.<init>(ClassReader.java:166)
        at lombok.bytecode.AsmUtil.fixJSRInlining(AsmUtil.java:37)
        at lombok.bytecode.SneakyThrowsRemover.applyTransformations(SneakyThrowsRemover.java:46)
        at lombok.core.PostCompiler.applyTransformations(PostCompiler.java:44)
        at lombok.core.PostCompiler$1.close(PostCompiler.java:87)