🚩배경
CI 연습을 하는 중에 build 를 할 때 @SpringBootTest 어노테이션이 yml 의 설정 정보를 읽어오지 못하는 문제가 발생했다.( 아래의 build 에러 로그와 동일한 contextLoads() Failed 에러 발생)
클래스를 직접 명시해줌으로써 해결은 되었지만( @SpringBootTest(classes=[ToDoListApplicationsTest::class]) )
실제로 실행될 때 잘 읽어올 수 있는게 맞는지 의문과 불안감이 들었다.
그래서 다른 분이 동일한 오류를 겪고 .env 로 설정 정보를 관리한다길래 나도 똑같이 .env 를 활용하여 CI 를 해보기 앞서 잘 적용이 되는지 ec2 배포를 테스트해보았다.
스프링 부트 3.2.2
aws ec2 ubuntu
jdk17
🚩문제상황
.gradlew build
빌드를 하고
java -jar 프로젝트-0.0.1-SNAPSHOT.jar
실행을 했더니 다음과 같이 에러가 났다.
⭐실행 에러 로그
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'jwtAuthenticationFilter' defined in URL
[jar:file:/home/ubuntu/ToDoList/build/libs/ToDoList-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/org/example/todolist/infra/security/jwt/JwtAuthenticationFilter.class]:
Unsatisfied dependency expressed through constructor parameter 0:
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'jwtPlugin' defined in URL
[jar:file:/home/ubuntu/ToDoList/build/libs/ToDoList-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/org/example/todolist/infra/security/jwt/JwtPlugin.class]:
Unexpected exception during bean creation
Caused by: java.lang.IllegalArgumentException:
Could not resolve placeholder 'AUTH_JWT_ISSUER' in value "${AUTH_JWT_ISSUER}"
설정을 못 가져오고 있다.
clean build 하고 다시 build 를 하니 다음과 같이 CI 할 때 마주쳤던 동일한 contextLoads() Failed 에러가 다시 나왔다.
⭐ build 에러 로그
org.example.todolist.domain.post.PostControllerTest > UnsatisfiedDependencyException FAILED
org.springframework.beans.factory.NoSuchBeanDefinitionException at DefaultListableBeanFactory.java:1824
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
> Task :test
org.example.todolist.domain.post.PostControllerTest > executionError FAILED
org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:797
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException at DefaultListableBeanFactory.java:1824
ToDoListApplicationTests > contextLoads() FAILED
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:143
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException at ConfigurationClassParser.java:178
Caused by: java.io.FileNotFoundException at ClassPathResource.java:211
env 작성을 잘못했나 싶어서 붙여넣는게 아니라
❗env 파일을 직접 적어넣어보거나 삭제했다가 다시 생성 build
➡️ 동일한 build 에러가 나왔다.
❓로컬에서는 정상적으로 실행 가능한데 왜 저 변수를 못 가져와서 이렇게 발생하는걸까??
❗로컬에서 env 의존성을 없애고 실행
➡️ 위의 실행 에러가 동일하게 발생했다.
❗로컬에서 마찬가지로 서버와 같은 환경을 맞추고 터미널에서 ./gradlew build
➡️ 서버에서 build 할 때 발생했던 동일한 build 에러가 나왔다.
❗서버에서 bootRun 으로 실행
여태 jar 파일로 실행 실패를 했었는데 bootRun 으로 실행하니 잘 된다.
=> jar 실행과 bootRun 실행의 차이점이 문제의 원인이지 않을까?
🔅java -jar vs bootRun 🔅
bootRun
-gradle 이나 maven 과 같은 build 툴을 통해 직접 실행
-애플리케이션의 클래스패스가 프로젝트의 루트 디렉토리를 기준으로 설정
java -jar
-build 프로세스로 생성된 jar 파일을 실행한다.
-jar 파일은 src/main/java(kotlin) 과 src/main/recourses 디렉토리에 있는 소스 코드가 컴파일되어 포함된다.
-jar 파일 외부의 파일들을 읽거나 쓰고 싶은 경우 따로 처리해주어야 한다.
./gradlew build
-Gradls 은 프로젝트를 컴파일하고 패키징하기 위해 정의된 빌드 스크립트와 설정을 사용한다.
-이 과정에서 .env 파일이 자동으로 참조되거나 환경 변수로 로드되지 않는다.
-스프링 애플리케이션이 resources 디렉토리에 있는 파일을 클래스 패스 리소스로 인식하고 자동으로 로드한다.
로컬에서 build 패키지 하위 파일들을 확인해보았다.
env 파일을 확인할 수 없다. resources/main 하위에 application.yml 은 있다.
➡️.env 파일을 resources 에 넣으면 되는 걸까?
🚩해결
.env 파일을 루트 디렉토리가 아닌 src/main/resources 하위에 넣어보았다.
그리고 로컬에서 빌드 했을 때 정상적으로 된다.
마찬가지로 서버에서도 같은 경로에 env 파일을 다시 생성했다.
그리고 빌드하고 java -jar 프로젝트-0.0.1-SNAPSHOT.jar 로 실행했다.
실행이 잘 된다.
처음 .env 를 이용할 때 이 파일을 어디에 넣어야 하는지 모르겠어서 .env 위치 이런 식으로 서치를 해보았었다. 이 때 express 를 이용하는 예시에서 루트 디렉토리에 넣길래 아무 생각없이 따라 넣었는데 이렇게 몇 시간째 붙잡고 있는 문제로 발전할 줄은 몰랐다.
하루종일 붙잡고 있었던 이 에러를 다른 분의 도움을 받아 해결했다.
내가 무엇을 어떻게 실행시키고 있는지 넓게, 구조적으로 바라봐야지 해결책이 보이는 것이었다.
무작정 env 파일만 계속 수정하고 반복했는데
여러 실행방법들을 다 테스트해보고 로컬과 서버를 비교하고 어떤 부분에서 나오는 문제일지 추측하고 실제로 실행해보는 것이 말로 하는 것보다 행동으로 하는게 참 어렵게 느껴진다. 메타인지 🐛🐛🐛
jar 가 아닌 다른 실행 방식이 있다는 것도 몰랐을 뿐더러 인텔리제이의 터미널에서도 실행시키는 방법도 몰랐다.
최종 프로젝트에서 CI/CD 업무에 자원하면서 내가 이걸 못하면 어떡하지? 하는 불안감도 너무 큰 것 같다.
무작정 하면 잘 되는게 아니다...크게 크게 보자 🥲
'왕초보일지' 카테고리의 다른 글
TMDB 영화 Open API 구현 (0) | 2024.04.03 |
---|---|
240315 TIL | 3주차 마무리 전체 테스트 (0) | 2024.03.15 |
240227 TIL | ERD 설계 고민 (2) | 2024.02.29 |
240223 TIL | (0) | 2024.02.23 |
240221 TIL | 직렬화 역직렬화? (0) | 2024.02.21 |