projectlombok / lombok

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

[BUG] Compiler Issue with OpenJDK 17 #3065

Open workmanw opened 2 years ago

workmanw commented 2 years ago

Describe the bug

When using lombok 1.18.22 we are running into a weird compiler issue with OpenJDK 17. I'm not sure if this is actually a lombok bug, but I cannot reproduce the issue if I take lombok out of the equation.

Here is the code:

package com.workmanw.java17.lombok.bug;

import lombok.Builder;

import java.util.List;

@Builder
class MyTestDto {
    @Builder.Default
    private List<@Length String> footer = List.of();
}

Here is the exception:

An exception has occurred in the compiler (17.0.1). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you.
java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
    at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writePosition(ClassWriter.java:672)
    at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeTypeAnnotation(ClassWriter.java:649)
    at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeTypeAnnotations(ClassWriter.java:553)
    at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeCode(ClassWriter.java:1120)
    at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeMethod(ClassWriter.java:988)
    at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeMethods(ClassWriter.java:1479)
    at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeClassFile(ClassWriter.java:1584)
    at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writeClass(ClassWriter.java:1505)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:738)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1617)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1585)
    at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:946)
    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.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess(JavaxToolsCompiler.java:126)
    at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile(JavacCompiler.java:174)
    at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:1134)
    at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:187)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:972)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:293)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:196)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)

Here are my versions:

mvn -version                                                                                                                                                                   ✔  16:23:21
Apache Maven 3.8.3 (ff8e977a158738155dc465c6a97ffaf31982d739)
Maven home: /usr/local/Cellar/maven/3.8.3/libexec
Java version: 17.0.1, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-17.0.1.jdk/Contents/Home
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "11.6", arch: "x86_64", family: "mac"

To Reproduce

Here is a simple reproduction: https://github.com/workmanw/java17-lombok-bug

Further information

This issue appears to happen with the Adoptium Temurin 17 JDK as well as the Oracle OpenJDK 17 which makes me this it is a lombok issue.

rspilker commented 2 years ago

Possibly we need to bump out ASM dependency.

hstaudacher commented 2 years ago

The same happens with gradle + Oracle 17.0.1 JDK. Also tested with Azul 17 and 17.0.1 JDK which fails as well. I think this defect prevents from using lombok with Java 17 right now.

workmanw commented 2 years ago

@hstaudacher Those are excellent data points, thank you! I think that pretty conclusively points to lombok as the issue.

hstaudacher commented 2 years ago

Here is more: yesterday I started a new project (spring boot + gradle + Java 17). I have added lombok via the spring initializer. Everything worked fine in the beginning (Intellij). I started to create some pojos using lombok including some @Builders with @Default. It worked. Today, for whatever reason, when running gradle clean build I ran into the described "compiler bug" with all mentioned JDK versions.

I hope this makes it more reproducible.

dforrest-es commented 2 years ago

Just ran into this myself using:

@Builder.Default
Set<@Length String> strs = new HashSet<>();

The above was tested with gradle 7.3.1 on both Temurin-17+35 (build 17+35) & Zulu17.30+15-CA (build 17.0.1+12-LTS).

The combination of @Builder.Default, an annotation on the generic type (<@Length String>), & a default value (Lists.of()) causes the compilation error. Removal of any number of those three prevents the compilation error.

workmanw commented 2 years ago

@dforrest-es Yea exactly! The best work around I've come up with is:

@Builder
class MyTestDto {
    // @Builder.Default
    private List<@Length String> footer = List.of();

    // See: https://github.com/projectlombok/lombok/issues/3065
    public static class MyTestDtoBuilder {
        private List<@Length String> footer = List.of();
    }
}

This works well if there is only a few cases in your code base, but it's definitely just a work around for a larger issue we need to get fixed.

rspilker commented 2 years ago

What I understand, the problem only occurs:

Please confirm.

workmanw commented 2 years ago

@rspilker Yes that is all correct.

I don't have a deep understanding of the actual issue, so it's conceivable if could manifest in other ways. But this it what we've whittled it down to in our application.

rzwitserloot commented 2 years ago

Link to the relevant line in OpenJDK source: https://github.com/openjdk/jdk/blob/master/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java#L672

edigu commented 2 years ago

I can confirm that annotations before the generic type used for validation leading to same compilation error if they combined with @Builder.Default. When I remove these my app also start compiling.

Does not compile:

    @Builder.Default
    protected Set<@Valid UUID> something = new HashSet<>();

It works:

    @Builder.Default
    protected Set<UUID> something = new HashSet<>();

Apache Maven 3.8.4 Java version: 17.0.1, vendor: Oracle Corporation

nikonovd commented 2 years ago

The problem does not seem to be limited to such annotations. For instance, the same error occurs while compiling with JDK17 when having static builder methods:

@Value
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Foobar {
    String foo;
    String bar;

    @Builder
    public static Foobar build(String foo, String bar) { 
        return new Foobar(foo, bar);
    }
}

Apache Maven 3.8.4 OpenJDK 17.0.2

edigu commented 2 years ago

@rspilker

Possibly we need to bump out ASM dependency.

Could you elaborate this a bit? Is there anything that others can help?

rzwitserloot commented 2 years ago

@edigu I'm not so sure its related to ASM at all. The fix involves first making this bug reliably occur, preferably in our testing framework, then delving in there - I think the problem occurs when we copy that type annotation around. see that link I mentioned earlier, linking to the exact line in javac that is crashing.

Rawi01 commented 2 years ago

This is a JDK bug (#2434) and fixed in the latest version. To fix this for Java 14-16 we can try to remove all type annotations for generated local variables but I'm not sure if this is worth the effort.

@rzwitserloot This can be reproduced in a unit test by also calling JavaCompiler::desugar and JavaCompiler::generate.

nikonovd commented 2 years ago

I can confirm that the issue is not present anymore when compiling with OpenJDK 17.0.2

jmax01 commented 2 years ago

This also happens on java 15.0.2 with @SIngular

@Data
@Builder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PUBLIC)
@Valid
public class CloseCaseRequest {

    @NotBlank(message = "caseResolution may by not be null or blank")
    private String caseResolution;

    @Singular(value = "insightToRemove")
    private List<UUID> insightsToRemove;

    @Singular(value = "insightToResolve")
    private Map<UUID, @Valid InsightResolutionRequest> insightsToResolve;

}
ribertojunior commented 9 months ago

Hi, sorry for jump in. is there a workaround? I'm kind of stuck for a while with jdk 17.0.1 for corporate reasons.

rspilker commented 9 months ago

@ribertojunior Can you compile using a different jdk compiler? Lombok is not a runtime dependency.

ribertojunior commented 9 months ago

Only locally, corporate controls the jdk version used on jenkins. It will take maybe a couple of weeks to change it (SLA and stuff). Thanks for answer, and sorry for take your time for some bureaucracy issue on my company.

bbecker-te commented 2 months ago

I am seeing this bug using OpenJDK 64-Bit Server VM Corretto-17.0.10.7.1 (build 17.0.10+7-LTS, mixed mode, sharing)

An exception has occurred in the compiler (17). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you.
java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
    at jdk.compiler/com.sun.tools.javac.jvm.ClassWriter.writePosition(ClassWriter.java:672)