Java 프로젝트를 jar 파일로 패키징한 뒤 실행할 경우, 개발 중에는 문제없던 리소스 파일 경로에서 오류가 발생하는 경우가 많습니다. 특히 설정 파일, 쿼리 템플릿 등 리소스 파일을 다룰 때 자주 마주치는 문제입니다. 그 원인과 해결 방법을 단계적으로 정리해보았습니다.
1. 개발 중엔 되는데, 배포 후 오류?
개발 환경에서는 다음과 같은 코드로 파일을 불러와도 문제가 없습니다.
File file = new File("src/main/resources/config/config.json");
하지만 jar 파일로 패키징한 후 실행하면 FileNotFoundException이 발생합니다. 이는 jar 내부에 있는 리소스는 실제 파일이 아니라 classpath 내에 존재하기 때문입니다.
2. jar 내부 리소스는 ClassLoader로
jar 내부 파일은 File이 아니라 ClassLoader를 사용해 읽어야 합니다.
InputStream is = getClass().getClassLoader().getResourceAsStream("config/config.json");
또한 다음과 같이 내용을 문자열로 변환할 수 있습니다.
try (InputStream is = getClass().getClassLoader().getResourceAsStream("config/config.json")) {
if (is == null) throw new FileNotFoundException("리소스를 찾을 수 없습니다.");
String content = new String(is.readAllBytes(), StandardCharsets.UTF_8);
}
3. 쓰기 작업은 외부 경로 사용
로그, 업로드 파일처럼 쓰기 작업이 필요한 파일은 외부에 두고 접근해야 합니다.
Path path = Paths.get(System.getProperty("user.dir"), "config/config.json");
이 방식은 파일을 읽고 쓸 수 있으며, 실행 환경에 따라 경로 설정이 유연합니다.
4. 실무에서는 이렇게 나눠 씁니다
| 파일 용도 | 위치 | 접근 방식 |
|---|---|---|
| 읽기 전용 (설정, 쿼리 등) | resources 폴더 | ClassLoader |
| 읽고 쓰기 (로그, 업로드 등) | 외부 디렉토리 | File 또는 Path |
프로젝트의 성격과 리소스의 용도에 따라 위처럼 구분하면 운영 환경에서도 안정적인 동작을 기대할 수 있습니다.
5. 요약
jar 파일 실행 환경에서는 리소스를 불러오는 방식이 다릅니다.
- 내부 리소스:
ClassLoader사용 - 외부 파일:
File,Path사용
읽기와 쓰기 용도를 명확히 구분해 적용하는 것이 핵심입니다.
반응형