🧩 BE

멀티 모듈 의존성별 참조 범위

Date
2026/03/30
Category
Web
Tag
Spring
Detail

Issue Point

storage 모듈에서 jpa dependency를 implementation해서 사용중이고, api 모듈에서 repository를 가져다 쓰는 형식(api → storage (implementation))으로 의존 구조를 구성했는데, 다음과 같은 오류가 발생했다.
Cannot access 'org.springframework.data.jpa.repository.JpaRepository' which is a supertype of 'RefreshTokenRepository'. Check your module classpath for missing or conflicting dependencies.

Detail

implementation vs api

api를 사용하면 직접, 간접 의존하고 있는 모듈 모두가 rebuild(recompile)이 되어야 한다. 즉 C모듈을 수정하면 B, A 모듈까지 모두 rebuild 되어야한다.
반면 implementation은 직접 의존하고 있는 모듈만 rebuild하면 된다.
다음과 같이 Gradle에서 implementation은 해당 모듈 내부용이다. 즉, storage(B)가 빌드될 때만 JpaRepository(C)가 classpath에 있고, api(A)가 storage(B)를 가져다 쓸 때는 노출되지 않는다.
그래서 api에서 RefreshTokenRepository(JpaRepository를 상속)를 사용하려 하면,  JpaRepository 자체가 lp-api classpath에 없어서 에러가 난다.
때문에 storage → JPA에서 implementation이 아닌 api를 사용해서 참조하면 해결이 가능하다.
명칭
역할
특징
implementation
내부에서만 사용
내가 사용하는 라이브러리를 나를 의존하는 다른 모듈에게는 숨김. → 빌드 속도가 빠르고 캡슐화 좋음.
api
외부로 노출
내가 사용하는 라이브러리를 나를 의존하는 다른 모듈에게도 공개.
runtimeOnly
실행 시에만 필요
컴파일 시에는 필요 없지만, 실제 서버가 돌아갈 때 필요한 것들 위주로 구성.

Reference