티스토리 뷰

Java

lombok 1.16.20 브레이킹 체인지

LichKing 2018. 3. 2. 14:05

아직 Java9을 사용해본적은 없지만 Java9이 나오고 초창기에 롬복을 사용할 수 없다는 이슈를 들은적이 있다. Java9을 할일이 없어서 크게 신경은 쓰지않고 있었는데 얼마전 롬복의 버전업을 할일이 있었다. 기존사용버전은 1.16.14였고, 1.16.20까지 나와있길래 최신버전으로 업데이트를 했다. 그리고나서 테스트를 실행하니 여기저기서 테스트가 깨지는 문제가 발생했다.


주로(전부다) jackson을 이용해 json을 deserialize 하는 코드에서 테스트를 실패했는데 롬복이 만들어주는 생성자가 기존코드와는 다르게 변경됐다.


@AllArgsConstructor
public class Person {
private int age = 30;
private String name;
}


이 코드를 롬복 버전별로 어떻게 생성자를 만들어주는지 확인해보자.


* 1.16.14

public class Person {
private int age = 30;
private String name;

@ConstructorProperties({"age", "name"})
public Person(int age, String name) {
this.age = age;
this.name = name;
}
}


* 1.16.20

public class Person {
private int age = 30;
private String name;

public Person(int age, String name) {
this.age = age;
this.name = name;
}
}


애노테이션 하나가 사라진걸 볼 수있다. @ConstructorProperties 애노테이션은 생성자의 속성의 명칭을 지정해주는 애노테이션인데 사실 직접 생성자를 작성할때 쓸일이 거의 없을것이다. 나도 롬복이 만들어주는 코드를 통해 처음 본 애노테이션이다.


여튼 롬복의 이런 변화가 왜 jackson에 영향을 줬는지를 생각해봐야하는데 jackson은 json을 deserialize 할때 인자를 받는 생성자에 @ConstructorProperties가 달려있으면 인자를 받는 생성자를 사용해서 deserialize를 하고, 애노테이션이 없으면 기본생성자를 사용하게된다.


그래서 예제의 Person 클래스의 경우 여태 @ConstructorProperties를 참고해 deserialize를 하다가 롬복 버전이 올라가면서 애노테이션이 사라지니까 기본생성자를 이용하게끔 작동했고, 그런데 기본생성자가 없으니 deserialize를 못해 테스트가 깨지게된셈이다.


하위호환을 깨는 1.16.20의 업데이트는 jdk9 때문이라고 lombok change log에 밝혀놨는데 구체적으로 어떤 이유인지는 적혀있지않다.


그래서 1.16.20에 대응하기위해선 기본생성자를 만들어주면 간단히 해결할 수 있다. 하지만 실제 프로젝트라면 수많은 클래스를 수정해야할것이다. 이런경우 설정파일 추가로 해결할 수 있다. lombok.config 파일에 lombok.anyConstructor.addConstructorProperties 속성을 추가하고 true로 값을 주면 된다.


lombok.anyConstructor.addConstructorProperties=true

(이 설정을 기본 true로 했다고 가정하고 업데이트했으면 문제가 없을것 같은데...음... 이유좀 자세하게 써주지)


lombok change log : https://projectlombok.org/changelog


문제 부분 로그

BREAKING CHANGE: lombok config key lombok.anyConstructor.suppressConstructorProperties is now deprecated and defaults to true, that is, by default lombok no longer automatically generates @ConstructorProperties annotations. New config key lombok.anyConstructor.addConstructorProperties now exists; set it to true if you want the old behavior. Oracle more or less broke this annotation with the release of JDK9, necessitating this breaking change.

공유하기 링크
TAG
댓글
댓글쓰기 폼