일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- FCM
- 테크쇼
- 소프티어
- Coputer Science
- proxyFactory
- 일상
- mapstruct
- ExceptionResolver
- Test code
- JPQL
- 자바
- OS
- ObjectMapper
- Java
- MySQL
- Spring
- 공룡책
- 인프콘2023
- enumSet
- backend
- JPA
- RequestBody
- Server
- db
- Test
- Junit 5
- modelmapper
- softeer
- Test Doulbe
- Service 계층 테스트
- Today
- Total
공부내용공유
getFile 사용시 주의점 (feat: FileNotFoundException) 본문
서론
FCM 기능을 완성하고 로컬에서 프론트 담담 팀원과 함께 테스트까지 완료하여 deploy 브랜치에 올렸다.
그런데 도커 컨테이너가 꺼져버렸다…….
컨테이너의 상태를 보니 exited(1) 이 떠있었고 log를 통해 확인해 보니 FCM을 사용하기 위한 key를 읽을 수 없다는 log가 찍혀있었다.
어떤 것이 문제였고 어떻게 해결했는지를 정리하고 공유하기 위해 이 글을 작성하였다.
본론
문제가 발생한 부분
FCM 기능을 사용하기 위해서 FCM Service Key가 resources 파일에 있고 @Value 를 통해 resource로 가져와 FirebaseMessaging Bean을 만드는 구조였다.
@PostConstruct를 사용한 Bean 생성 코드 일부
로컬에서 돌릴 때는 아무런 문제가 없어서 그냥 배포를 하였는데 배포 서버에서 컨테이너가 바로 꺼져 버렸다.
log를 확인해보니 FCM 관련 fileNotFound 관련 log가 있어서 해당 문제를 검색해 보았더니 다른 사람들도 해당 문제를 많이 겪었던거 같다.
왜 로컬에서는 잘만 찾던 file을 못찾았을까?
문제
문제는 여기에 있었다.
IDE에서 application run으로 돌릴 경우 실제 resource의 파일위치를 file:// 프로토콜을 사용하기 때문에 getFile() 및 FileInputStream 사용이 가능하다.
하지만 jar에서는 컴파일된 class file, resouce, nested jar로 구성되어져 있고 해당 resource들은 위 사진과 같이 jar: 와 같은 주소를 갖게된다.
즉 IDE에서는 파일 시스템 기준 경로를 따르므로 에러가 발생하지 않지만 jar 파일 내에서는 jar:file 이런식으로 경로가 바뀌기 때문에 getFile을 수행할 때 오류가 발생한 것이다.
Resource 구현체 종류에 따른 차이
@Value 어노테이션은 url을 통해 resource를 갖고올 때 log를 찍어보니 Resource 구현체중 ClassPathResource임을 확인하였다.
그리고 ClassPathResource에 getFile을 따라가다 보면 file: 로 시작하는 프로토콜(URL_PROTOCOL_FILE)이 아닐경우 FileNotFoundException을 던짐을 확인하였다.
즉 결론은 jar로 실행할 것이라면 classPathResource일 경우 getFile을 사용하면 안된다.
해결
해결책은 간단했다. @Value 로 가져온 resource를 File 인스턴스로 변환하지 않고 바로 InputStream으로 바꿔서 Firebase Builder에 넣어주면 됐다.
결론
사소하지만 심각한 문제를 야기하는 오류였고 이번 기회에 잘 기억하여 다시는 하지 말아야 할 오류였다.
이번 과정을 통해 Resouce에 관련된 지식들을 좀 더 알게되고 File 객체를 다룰 때 신중하게 다루자는 생각을 하게되었다.
참고 블로그
'Spring > Spring' 카테고리의 다른 글
Mongo @CreateDate, @LastModifiedDate 오류 (feat: Spring Data Auditing) (1) | 2024.11.08 |
---|---|
spring validation (service, presentation 어디서 검증할까?) (2) | 2024.02.18 |
FCM 기능 구현 및 리팩토링을 하면서의 고민들 (0) | 2023.09.08 |
Spring Proxy Factory 뜯어보기 (0) | 2023.09.05 |
Test Code H2 DB 사용시 주의사항 (0) | 2023.07.28 |