엔지니어로 가는 길

Spring Boot 버전업(2.0.1 -> 2.7.6) 과정에서 만난 이슈들 본문

private note/한 일, 할 일, 하고싶은 일

Spring Boot 버전업(2.0.1 -> 2.7.6) 과정에서 만난 이슈들

탐p슨 2022. 12. 21. 19:33
728x90

 

 

Spring boot 버전을 올려보자

Spring boot 2.0을 사용 중인 프로젝트의 버전을 최신 버전으로 올려보려고 한다. 간단한 일은 아니겠지만 불가능한 일도 아니다. 수많은 문제를 끊임없이 만나게 될 텐데, 문제를 만나서 해결하거

live-everyday.tistory.com

 

담당하고 있는 프로젝트의 Spring Boot 버전을 2.0.1에서 2.7.6까지 올렸다. 위 글에서 Spring Boot 버전을 올려보고 싶다고 말하기는 했으나 이렇게 생각보다 빠르게 마무리될 줄은 몰랐다. 이 글에서는 Spring Boot 버전업 과정에서 만난 이슈를 정리하려고 한다. (버전을 올림에 따라 발생할 수 있는 모든 이슈가 아닌, 회사 프로젝트에서 발생한 이슈만 정리하였다.)

 

2.1.18 -> 2.2.13

API 응답에서 한글이 깨지는 이슈(인코딩이 ISO-8859-1로 되는 이슈)

2.2부터 Spring Web 버전이 5.2로 올라갔다. Spring Web 5.2부터 MediaType에서 아래와 같이 charset 정보를 함께 넘기는 상수가 deprecated 되었다.

APPLICATION_JSON_UTF8_VALUE

Deprecated 된 이유는 아래와 같다.

@deprecated as of 5.2 in favor of APPLICATION_JSON_VALUE since major browsers like Chrome now comply with the specification and interpret correctly UTF-8 special characters without requiring a charset=UTF-8 parameter.

 

해결하기는 `MappingJackson2HttpMessageConverter`의 디폴트 charset을 UTF-8로 설정하여 해결했는데, 원인에 대해서는 다시 확인이 필요하다. 해결하는 데 너무 급급했던 것 같다. 왜 일부 요청에 대해서만 인코딩이 깨졌을까? 

2.3.12 -> 2.4.13

로깅이 안되는 이슈

버전을 올리고 알파 서버에 배포해서 제대로 동작하는지 테스트를 해보려는데 로깅이 제대로 되지 않았다. 알고 보니 2.4 버전부터 `logging.file` 프로퍼티가 deprecated 되어 로깅할 파일의 이름이 제대로 설정되지 않았기 때문이었다.

logging:
    file: log-filename.log

`application.yml` 파일에서 위와 같이 설정하고 있었는데, 아래와 같이 수정하여 해결하였다.

logging:
    file:
        name: log-filename.log

 

특정 프로파일의 설정파일에서 다른 프로파일 활성화 불가능

2.4 버전의 변경사항 중 하나는 더이상 특정 프로파일 설정파일에서 다른 프로파일을 활성화하는 게 불가능하다는 것이다.

 

기존에는 설정파일(`application.yml`)에서 특정 프로파일을 활성화하고 싶은 경우 아래와 같이 활성화할 수 있었다.

// application.yml
spring:
    profiles:
        include: profile1, profile2

 

2.4 버전부터는 `application.yml`과 같이 프로파일에 종속적이지 않은 공통 설정파일에서는 위와 같은 설정이 가능하지만, `application-dev.yml`과 같이 특정 프로파일에 종속적인 설정파일에서는 다른 프로파일을 활성화하는 게 불가능하다.

// application-dev.yml
spring:
    profiles:
        include: file-logging # 불가능
So in Spring Boot 2.4 we’re planning to make two significant changes to the way the properties and YAML files are loaded:

1. Documents will be loaded in the order that they’re defined.
2. Profiles can no longer be activated from profile specific documents.

 

특정 프로파일에 종속적인 설정파일에서 다른 프로파일을 활성화하는 부분을 제거하고, 배포 시나리오에서 jar 파일을 실행할 때 프로파일을 설정하도록 수정하였다.

java -jar -Dspring.profiles.activate=file-logging

2.5.14 -> 2.6.14

suffix 패턴 매칭되지 않는 이슈

`/api/hello.json`과 같이 suffix를 붙여서 요청하는 경우 `/api/hello`로 해석했으나, 2.6 버전부터 suffix 패턴에 대해 매칭하는 설정이 디폴트 false로 바뀌었다. 하지만 우리 프로젝트의 API를 사용하는 측에서 `/api/hello.json`과 같이 suffix를 붙여서 요청하고 있었으므로 suffix 패턴 매칭이 가능하도록 설정해야 했다.

 

`WebMvcConfigurer`의 `configurePathMatch()` 메서드를 오버라이드하여 `PathMatchConfigurer`의 `setUseSuffixPatternMatch()` 메서드를 통해 suffix 패턴 매칭에 대해 허용할지 말지를 결정할 수 있다. 해당 값을 true로 설정하였는데도 suffix 패턴을 해석하지 못해서 확인해보니  docs에 아래와 같은 설명이 있었다.

 

This property is mutually exclusive with and ignored when setPatternParser(PathPatternParser) is set.

 

`PathMatchConfigurer`의 `setPatternParser()` 메서드를 통해 PatternParser를 null로 설정까지 해주고 나니 suffix 패턴에 대해 정상적으로 매칭이 이루어졌다.

 

 

빌드시 war(jar) 파일이 두 개 생성되는 이슈

spring-boot-gradle-plugin 2.5부터 war(jar) 태스크가 디폴트로 enabled 되었는데, war(jar) 태스크가 bootWar(bootJar) 태스크와 함께 존재하는 경우 war(jar) 태스크의 산출물에는 "plain"이라는 prefix가 컨벤션으로 붙는다고 한다.

 

By default, when the bootJar or bootWar tasks are configured, the jar or war tasks are configured to use plain as the convention for their archive classifier. This ensures that bootJar and jar or bootWar and war have different output locations, allowing both the executable archive and the plain archive to be built at the same time.

참고: https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/#packaging-executable.and-plain-archives

 

경우에 따라서는 문제가 안될 수도 있는 내용이다. 우리는 시나리오를 통해 배포를 자동화하고 있었고, 시나리오 중에는 이전 배포 파일을 삭제하는 과정이 있었는데 해당 과정에서 이번에 처음 등장한 plain이 붙은 war(jar) 태스크의 산출물을 삭제하지 않다 보니 두 번째 배포부터 이름이 충돌하여 배포에 실패했다.

 

build.gradle 파일에 아래와 같이 war(jar) 태스크를 사용하지 않겠다고 함으로써 해결하였다.

 

war {
    enabled = false
}
728x90
Comments