이전 포스팅에서 Issue를 중심으로 한 오픈소스 읽기 훈련에 대해 말하였습니다.

 

우당탕탕 개발 인생 첫 오픈소스 Contribution

누구나 할 수 있는 오픈소스 Contribution이전 포스팅에서 SIPE 합격 후기를 올렸었습니다.이번엔 SIPE에서 진행하는 미션의 일부인 오픈소스를 활용한 읽기 훈련에 대해 말해보려 합니다.저는 현재

masiljangajji-coding.tistory.com


이번에 선택한 오픈소스는 lombok인데요 자바진영에서 매우 높은 인기를 가지며 보일러 플레이트 코드를 줄여주는 귀인이라 생각됩니다.
항상 사용해왔던 것인데 막상 실제 코드레벨에서 어떻게 구현됐는지를 찾아본 적은 없었기 때문에 이번 기회를 통해 읽어봤습니다. 

흥미로운 Issue

Missed null checks in record constructor when non-Lombok annotations are used

 

 

[BUG] Missed null checks in record constructor when non-Lombok annotations are used · Issue #3743 · projectlombok/lombok

Describe the bug Lombok does not generate record constructor with nullability checks for a record with annotated fields - if non-Lombok annotations are used for. The following annotations are affec...

github.com

 

record에서 non-Lombok annotations 사용시 null 체크가 안되는 문제가 있다 합니다.
또 찾아보니 이와같은 이슈를 겪는 사람들이 많은 것 같습니다.

테스트 코드를 실행해보니..

실제로 null 체킹이 안되는 문제를 발견했습니다.

비슷한 Issue를 조금 더 찾아보니

record의 경우에는 Compact Constructor를 기본으로 생성하기 때문에
이런 문제가 발생한다고 합니다

근데 lombok은 record에 대해서도 null 체킹을 하니까...
lombok의 NonNull은 record에 대해서 별도 처리를 한다는 가설을 새울 수 있습니다.

 

lombok의 NonNull은 record에 대해서 추가적인 처리를 하는가?

lombok의 프로젝트 구조입니다.
core안에 익숙해 보이는 이름의 파일이 존재합니다.

우리가 사용하는 lombok 어노테이션은 src/core 아래에 있는것으로 보입니다.

lombok은 기본적으로 컴파일 타임때 AST(Abstract Syntax Tree)를 순회하면서 어노테인션을 인지하고 코드를 주입합니다.

그래서 컴파일과 관련있어 보이는 javac패키지를 확인했고
javacAST , javacASTAdatprer , javacASTVisitor 등을 확인했습니다.

 

구조를 보니 Visitor는 스펙을 명시해놓은 인터페이스고 Adapter가 Visitor를 상속받아 실질적인 동작을 하는 것 처럼 보였습니다.
이름과 visitField , visitAnnotationOnField 등의 메서드 이름으로 추측하건데
AST를 순회하는 역할을 맡고있구나! 라고 생각했습니다.

JavacAST도 확인해보니

 

 

LombokNode -> AST -> JavacAST로 이어집니다.
따라서 JavacAST가 실질적으로 SyntaxTree를 구성하며 그 Tree를 이루는것은 각각의 Node겠구나 생각했습니다.

여기까지 읽은 후 나머지 키지를 클릭해보던 중 익숙한 이름을 발견합니다.

 

어라? 이거 클래스네? -> 그럼 실질적으로 동작이 일어나나보다 그리고...

이름으로 추측하건데 JavacAST를 Adapter가 순회하면서 어노테이션 확인하면 그에 맞는
Handler가 동작해 어노테이션을 처리하는 것 같다


또한 private 메서드는 안읽고 그냥 넘겼습니다
어차피 private이면 밖으로 오픈 안한다는 소리기 때문에 public으로 열려있는 메서드만 읽으면 충분하다 생각해요

그렇게 모든 private메서드를 넘기고 처음 나오는 public는 handle메서드 입니다.

근데 이거... @override 돼있습니다 그말은 표준화된 스펙을 구현한 메서드란 소리며
이는 곧 handle메서드에서 실질적인 처리가 일어남을 의미합니다. 그렇게 쭉 읽다보면...

record에 대해서 추가적인 처리를 하는것을 볼 수 있습니다.

아마 record인 경우에는 lombok이 Modify할 수 있도록 record에 의해 생성되는 compact constructor를 사용하지 않고
따로 만들어 넣어주는 것 같습니다.

따라서 우리는 lombok의 NonNull은 record에 대해서 추가적인 처리를 해주며 다른 벤더에서 제공하는 어노테이션들은
record에 대한 추가적인 처리가 없기 때문에 이런 Issue가 발생한다는 결론을 내릴 수 있습니다.

이전 글과 마찬가지로 단서를 통해 추측하고 읽어내야 할 부분을 최소화 하여 빠르게 결론에 다달하는 읽기 연습을 하는 중입니다.

같이 보시면 좋은 발표 영상입니다.

 

'오픈소스' 카테고리의 다른 글

우당탕탕 개발 인생 첫 오픈소스 Contribution  (4) 2024.11.20

+ Recent posts