Lombok: @Builderアノテーション付きのコードはJava9でコンパイルに失敗します(Java 8で動作します)

作成日 2018年08月07日  ·  3コメント  ·  ソース: projectlombok/lombok

Lombok1.18.2の使用。 次のクラスはJava8でコンパイルされますが、Java9ではコンパイルされません。

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.Optional;

import lombok.Builder;
import lombok.Value;

public class TestLombok {
    <strong i="6">@Value</strong>
    <strong i="7">@Builder</strong>
    static class MyClass {
        private final int dayOfWeek;

        static class MyClassBuilder {
            private Optional<LocalDate> date = Optional.empty();

            MyClassBuilder dayOfWeek(int date) {
                if (!this.date.isPresent()) {
                    this.date = Optional.of(LocalDate.parse(String.valueOf(date),
                                                                   DateTimeFormatter.ofPattern("yyyyMMdd") // doesn't compile
                                                                    // DateTimeFormatter.BASIC_ISO_DATE // compiles
                    ));
                }

                this.dayOfWeek = this.date.get().getDayOfWeek().getValue();
                return this;
            }
        }
    }

    public static void main(String[] args) {
        System.out.println(MyClass.builder().dayOfWeek(20181013).build());
    }
}

エラー出力は次のとおりです。

TestLombok.java:11: error: incompatible types: String cannot be converted to DateTimeFormatter
    <strong i="11">@Builder</strong>
    ^

DateTimeFormatter.ofPattern("yyyyMMdd")行がDateTimeFormatter.BASIC_ISO_DATEに変更された場合、コードは正常にコンパイルされます(両方のメソッドが同じ型を返す場合でも)。

このファイルだけをコンパイルする最小限のgradleプロジェクトを添付しています。 gradle buildを使用してエラーを確認します。

lombok-test.zip

最も参考になるコメント

コンストラクターで@JsonCreator@JsonProperty@Builderアノテーションと一緒に使用すると、同様の問題が発生し
@JsonPropertyアノテーションが付けられたコンストラクターのフィールド名の順序は、クラスで宣言されているものと同じである必要があります。問題が関連しているかどうかは

<strong i="11">@Getter</strong>
<strong i="12">@ToString</strong>
<strong i="13">@Builder</strong>
<strong i="14">@JsonDeserialize</strong>
<strong i="15">@EqualsAndHashCode</strong>
public class DataClass {

    private final long id;

    private final String name;

    private final String date;

// Order of this constructor parameters needs to be in the same order as declared in class, not sure why?
    <strong i="16">@JsonCreator</strong>
    public ClearingFlowCounts(@JsonProperty("name") String name,
                                   @JsonProperty("id") long id, @JsonProperty("date") String date) {

        this.id = id;
        this.name = name;
        this.date = date;
    }
}

全てのコメント3件

何がこの問題を引き起こしているのかわかりません。 再現できます。

私の提案は、コードを変更し、フォーマッターをローカル変数(または静的な最終フィールド)に割り当てることです。 これで、この問題のインスタンスが処理されます。

根本的な未知のバグがありますが、私はこの問題を閉じています。 同様のバグを追跡した経験に基づくと、これは見つけるのに数週間かかる場合があり、一般的な使用例ではありません。

この問題を解決した理由

コンストラクターで@JsonCreator@JsonProperty@Builderアノテーションと一緒に使用すると、同様の問題が発生し
@JsonPropertyアノテーションが付けられたコンストラクターのフィールド名の順序は、クラスで宣言されているものと同じである必要があります。問題が関連しているかどうかは

<strong i="11">@Getter</strong>
<strong i="12">@ToString</strong>
<strong i="13">@Builder</strong>
<strong i="14">@JsonDeserialize</strong>
<strong i="15">@EqualsAndHashCode</strong>
public class DataClass {

    private final long id;

    private final String name;

    private final String date;

// Order of this constructor parameters needs to be in the same order as declared in class, not sure why?
    <strong i="16">@JsonCreator</strong>
    public ClearingFlowCounts(@JsonProperty("name") String name,
                                   @JsonProperty("id") long id, @JsonProperty("date") String date) {

        this.id = id;
        this.name = name;
        this.date = date;
    }
}

@blackupriseの再現方法と回避策を確認できます。

このページは役に立ちましたか?
0 / 5 - 0 評価

関連する問題

manuel-hegner picture manuel-hegner  ·  4コメント

zenglian picture zenglian  ·  3コメント

x9nico picture x9nico  ·  3コメント

michaelkuechler picture michaelkuechler  ·  3コメント

Bryksin picture Bryksin  ·  3コメント