본문 바로가기
공부/프로그래밍

[springboot] jar파일과 json 파일을 각각 폴더에 위치하는 이유

by demonic_ 2025. 2. 21.
반응형

프로젝트 하다보면 라이브러리와 외부연동을 위한 리소스 파일을 추가해야 하는 경우가 있는데, 예전에는 이 두개를 감각적(?)으로 분리해서 넣어놨다. 그런데 이번 프로젝트를 진행하면서 jar와 json을 각각 관리하는게 좋다고 생각했고 찾아봤더니 역시나 그게 더 좋은 방법이긴 하다.

 

그 과정을 여기에 정리하려 한다.

 

1) jar 파일

외부연동중에 종종 결제회사 등에서 사용하는 고유 라이브러리(JAR)파일이 있어 추가해야 할 때가 있다.

그래서 이런것들은 maven이나 gradle 에다가 등록해서 쓰는데, 이떄 파일은 어디에다 둘까 고민이 되었다.

 

2) json 파일

서버에서 푸시를 보내려면 파이어베이스에서 설정json 파일을 다운받고, 받은 파일의 정보를 이용해 푸시를 전송하는데, 그래서 json파일을 프로젝트 내에 넣어둬야 한다.

 

처음에는 둘다 외부파일이기 때문에 어디 한곳에 넣어두면 좋겠다고 생각했다. 알아보니 둘의 쓰임이 다르고, 그래서 넣어야 하는 위치가 다르다는 점을 이해하게 되었다.

 

일단 결과적으로 생각하면 실행하기 위해 bootJar 파일을 만들면 그 안에 관련 리소스들이 전부 들어가게 되는데 프로젝트루트/libs/ 의 폴더는 jar 파일에 포함되지 않는다. 그렇기 때문에 앱이 실행될 곳에 직접 파일을 놓거나 해야한다.

 

 

 

그래서 결론을 먼저 말하자면

 

JAR 파일 => 프로젝트 루트/libs + gradle 에 등록

Json 파일 => resources/libs

 

이렇게 두는걸 권장한다.

 

 

그 이유는 아래와 같다.

 

JAR 파일: 외부 의존성 라이브러리로, Gradle에서 dependencies로 추가해서 클래스패스에 포함시켜야 실행 시 코드에서 사용할 수 있다. 그래서 프로젝트루트/libs 에 넣고 gradle로 직접 관리하는게 적합하다.

 

JSON 파일: 외부 설정 파일로, 리소스로 취급돼 클래스패스에서 읽히면 되니까 resources/libs가 자연스럽다.

 

즉 둘의 차이는 '라이브러리'와 '리소스' 라는 점이다. json은 자체적으로 어떤 기능을 하는게 아니라 단순 정보를 참조하는 참조용 파일이란 점이다.

 

 

 

리소스 파일을 resources 에 두는건 자연스럽다

resources/libs 에 두면 빌드시 자동으로 클래스패스에 포함된다. 그렇기 때문에 bootJar 를 만들어도 해당 위치에 파일이 포함하여 생성된다. 그래서 이런 접근이 자연스럽다.

ClassPathResource resource = new ClassPathResource("libs/test.json");
 

리소스파일이야 그렇다 치더라도 Jar는 Gradle에 등록할 수 있으니까 resources/libs 에 넣으면 되지 않을까? 라는 궁금증이 생겼다. 결론은 '권장하지 않는다' 이다.

 

 

 

JAR 파일을 resources (예: resources/libs)에 넣는 걸 권장하지 않는 이유

Spring Boot와 Gradle의 동작 방식, 그리고 JAR 파일의 용도와 관련이 있다. 구체적으로 살펴보면:

 

 

(1) JAR 파일의 용도와 클래스패스 처리

JAR 파일: 일반적으로 JAR 파일(예: test.jar)은 라이브러리 의존성으로, 안에 포함된 .class 파일이나 리소스를 애플리케이션에서 실행 시 로드해야 한다. Gradle은 dependencies에 추가된 JAR을 BOOT-INF/lib에 넣고, Spring Boot가 이를 클래스패스로 인식해서 자동으로 사용할 수 있게 해준다.

 

그런데 만약 resources에 넣으면?

resources/libs/test.jar처럼 배치하면, 빌드 시 JAR 파일이 단순한 리소스로 클래스패스(BOOT-INF/classes/libs/)에 포함된다. 하지만 Spring Boot는 이걸 의존성 JAR로 인식하지 않는다. 즉, 안에 있는 클래스나 기능을 로드하려면 커스텀 클래스 로더 같은 복잡한 작업이 필요해진다.

 

 

(2) 비효율성과 혼란

resources에 넣으면: JAR 파일을 "파일"로만 취급하게 된다.

 

예를 들어 ClassPathResource로 읽을 수는 있지만, 그 안의 코드를 실행하거나 의존성처럼 활용하려면 추가 작업이 필요하다. 이건 JAR 파일의 본래 목적(라이브러리 제공)과 맞지 않다.

 

루트 libs에 넣으면 Gradle을 설정했을때 의존성으로 인식해서 BOOT-INF/lib에 포함시키고, Spring Boot가 자동으로 클래스패스에 추가한다. 별도의 코드 수정 없이 바로 사용이 가능하다.

 

 

(3) Spring Boot의 표준 구조와의 불일치

Spring Boot는 BOOT-INF/lib에 의존성 JAR을 두고, BOOT-INF/classes에 리소스와 컴파일된 클래스를 두는 구조를 따른다. JAR 파일을 resources에 넣으면 이 구조를 깨뜨리게 돼서, 예상치 못한 동작(예: 클래스 로딩 실패)이 발생할 수 있다.

 

 

결론

위에서 정리한것처럼 Jar와 같은 라이브러리는 는 root/libs 에 Json과 같은 리소스는 resources/libs 에 넣는게 좋다. 단순파일로 취급할 것인지, 실행가능한 라이브러리로 취급해야할지에 따라 각각 위치를 달리 두는게 좋다는 것이다.

 

 

 

끝.

 

 

반응형

댓글