@Slf4j 사용했는데도 cannot find symbol log 오류가 발생한다면?
새로 스프링부트 프로젝트를 생성한 후 아래 사진과 같은 오류를 겪었다.

구글링 10초만에 해결방법을 찾았으나 시원하지 않았다.
해결 방법은 아래처럼 직접 LoggerFactory.getLogger() 를 호출하여 log 변수를 직접 선언한것.
@Component
public class LoggingFilter implements WebFilter {
private static final Logger log = LoggerFactory.getLogger(LoggingFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
return chain.filter(exchange)
.doAfterTerminate(
() -> log.info("path : " + path + " | status : " + exchange.getResponse().getStatusCode()));
}
}
하지만 원래 @Slf4J 어노테이션을 사용하는 의도대로라면 LoggerFactory가 있는지, 뭐하는지도 모른채 로깅이 가능해야했다. 조금 더 찾아보니 gradle 의존성을 잘못 추가했을 때 이런 경우가 발생한다고 했다.
문제 상황은 lombok 어노테이션을 implementation 'org.projectlombok:lombok:1.18.28' 와 같이 작성했을 가능성이 높음,
정상적으로 lombok gradle 의존성을 추가하는 방법은 아래와 같다.
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
추가로 test code에서 비슷한 오류를 겪는 경우
testAnnotationProcessor 'org.projectlombok:lombok'
를 추가해주면 된다.
Q. 근데 왜 저렇게 하면 되는걸까?
A1. lombok은 컴파일타임에만 의존성이 필요하며, 런타임에는 필요하지 않다. 따라서 compileOnly로 lombok을 추가
A2. lombok이 컴파일타임에 코드를 생성하기위해서 Annotation Processor 의존성을 추가해야한다. annotationProcessor 의존성은 컴파일 타임에만 필요하며, 컴파일러에게 Lombok이 어노테이션 프로세싱을 수행해야한다고 알려준다.
Q. 그럼 왜 implementation은 안 될까?
어노테이션 프로세싱을 수행해야한다고 컴파일러가 알고있지 않기 떄문에 어노테이션 프로세싱이 수행되지 않아서
어노테이션 프로세싱은 Lombok 의존성을 추가한 후 @Getter, @Setter 등의 어노테이션을 붙였을 때, 각 필드명에 맞는 getter, setter 함수를 build시에 생성해주는 작업을 의미한다. 이미 수도없이 많은 어노테이션 프로세싱을 경험했으리라 생각함
그러면 @Slf4J 어노테이션을 붙여놓으면 무슨 프로세싱이 일어나길래?

빌드된 클래스를 확인해보면 @Slf4J 어노테이션을 사라지고, 오류 해결을 위해 직접 작성한 코드 한줄이 그대로 있었다. 이해 완료!
@Slf4j 사용했는데도 cannot find symbol log 오류가 발생한다면?
새로 스프링부트 프로젝트를 생성한 후 아래 사진과 같은 오류를 겪었다.

구글링 10초만에 해결방법을 찾았으나 시원하지 않았다.
해결 방법은 아래처럼 직접 LoggerFactory.getLogger() 를 호출하여 log 변수를 직접 선언한것.
@Component
public class LoggingFilter implements WebFilter {
private static final Logger log = LoggerFactory.getLogger(LoggingFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
return chain.filter(exchange)
.doAfterTerminate(
() -> log.info("path : " + path + " | status : " + exchange.getResponse().getStatusCode()));
}
}
하지만 원래 @Slf4J 어노테이션을 사용하는 의도대로라면 LoggerFactory가 있는지, 뭐하는지도 모른채 로깅이 가능해야했다. 조금 더 찾아보니 gradle 의존성을 잘못 추가했을 때 이런 경우가 발생한다고 했다.
문제 상황은 lombok 어노테이션을 implementation 'org.projectlombok:lombok:1.18.28' 와 같이 작성했을 가능성이 높음,
정상적으로 lombok gradle 의존성을 추가하는 방법은 아래와 같다.
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
추가로 test code에서 비슷한 오류를 겪는 경우
testAnnotationProcessor 'org.projectlombok:lombok'
를 추가해주면 된다.
Q. 근데 왜 저렇게 하면 되는걸까?
A1. lombok은 컴파일타임에만 의존성이 필요하며, 런타임에는 필요하지 않다. 따라서 compileOnly로 lombok을 추가
A2. lombok이 컴파일타임에 코드를 생성하기위해서 Annotation Processor 의존성을 추가해야한다. annotationProcessor 의존성은 컴파일 타임에만 필요하며, 컴파일러에게 Lombok이 어노테이션 프로세싱을 수행해야한다고 알려준다.
Q. 그럼 왜 implementation은 안 될까?
어노테이션 프로세싱을 수행해야한다고 컴파일러가 알고있지 않기 떄문에 어노테이션 프로세싱이 수행되지 않아서
어노테이션 프로세싱은 Lombok 의존성을 추가한 후 @Getter, @Setter 등의 어노테이션을 붙였을 때, 각 필드명에 맞는 getter, setter 함수를 build시에 생성해주는 작업을 의미한다. 이미 수도없이 많은 어노테이션 프로세싱을 경험했으리라 생각함
그러면 @Slf4J 어노테이션을 붙여놓으면 무슨 프로세싱이 일어나길래?

빌드된 클래스를 확인해보면 @Slf4J 어노테이션을 사라지고, 오류 해결을 위해 직접 작성한 코드 한줄이 그대로 있었다. 이해 완료!