layout: post title: Gradle dependencies(compileTimeClasspath, runtimeClasspath) author: Bong5 categories: [Keywords, ProgramingLanguage/Java, WEB/Basic] —

Gradle dependencies(compile-time, runtime)


들어가며.

이번 학습을 통해 몇 가지 의미있는 것들을 배웠다.

  1. gradle에서 dependencies를 설정할 때 단순히 .jar만 가져오는게 아니다.
  2. pom 정보 등을 통해 third-party 의존성도 함께 가져온다.
  3. implementation, compile에 상관 없이 일단 third-party 라이브러리를 mavenRepository로부터 땡겨온다. 물론 compile classpath에 추가하냐 마냐는 옵션에 따라 다르다.
  4. compile classpaththird-party 라이브러리가 추가되는 것은 현재 모듈에서 implement, compile(api)로 설정하는 것과 상관 없다. 다시말해 현재 모듈이 아닌 dependency가 어떻게 설정했느냐에 따라 달렸다.
  5. main-module - submoduleA - submoduleB
  6. main-module(implement: submoduleA), submoduleA(compile:submoduleB)
  7. 위와 같이 의존성 설정이 되어있다면 main-module에서 submoduleB컴파일 타임에 접근 가능하다. 즉 compileClasspath에 추가된다.


gradle build, jar

.jar만 있다고 하여 원하는대로 depnedencies들을 얻을 수 없다.

jarsourceSet에 대한 class들만 모으기 때문에 third-party 의존성을 얻을 수 없다.

일반적으로 mavenRepository에서 dependencies들을 가져올 때 단순히 .jar만 가져오는게 아니다.!

publish 또는 uploadArchives를 통해서 build 결과물을 특정 repository에 배포해보면

  • 배포 모듈에 대한 메타데이터(.meta)
  • 배포 모듈 아카이브(.jar)
  • 배포 모듈의 third-party 의존성에 대한 정보(.pom)

와 같은 파일들이 생성된것을 알 수 있다.

따라서 배포된 모듈을 dependency로 가져오기 위해서는 해당 모듈의 third-party 정보를 참조해서 관련 의존성까지 모두 mavenRepository로부터 가져온다.


implementation, compile(api) - 주체는 “모듈”

현재 모듈을 의존성으로 가질(의존할) 외부 모듈에게 thrid-party 라이브러리에 대한 접근(컴파일 타임)을 설정한다.

즉, 의존하는 clientserver들이 의존한 대상들에 대한 접근을 설정하는게 아니라 serverclient에게 보여줄지 말지를 설정하는 것이다.

이게 바로 spring-starter-loggingimplementation으로 걸었는데 slf4j까지 접근 가능한 이유다. spring-starter-loggingslf4jcompile로 걸었기 때문에 클라이언트인 우리의 모듈에게도 slf4j가 노출되어 컴파일타임에 접근이 가능한 것


implementation, compile(api) - 의존성 접근 가능에 대한 관점

의존성 옵션이 implementation이냐 compile(api)냐에 따라서 clientthird-party 의존성에 접근할 수 있는 시점이 다르다.

  • main-modulesubmoduleAsubmoduleB

위와 같이 의존성을 가진다고 해보자.

위처럼 submoduleA자신에게 의존하는 클라이언트 모듈(main-module)에게 trhid-party 모듈(submoduleB)에 대한 정보를 (컴파일 타임에) 감추고 싶다면 implementation으로 설정한다.

이렇게 되면 main-modulecompileClasspath에서는 submoduleB가 감춰지기 때문에 컴파일 타임에 submoduleB에 대한 접근이 불가능하다.

물론 submoduleAmavenRepository로부터 가져올 때 submoduleA의 의존 정보인 pom을 확인하여 submoduleB도 함께 가져오지만, compileClasspath에는 추가하지 않고 runtimeClasspath에만 추가한다.

  • 만일 classpath에 submoduleB가 없다 하더라도 main-module을 빌드 하는데에는 아무런 문제가 없다.
  • (중요)물론 최종 build 후에는 ext-libsfat-jar 형태든 간에 submoduleB가 반드시 포함되어 있어야 한다.
  • (중요)이는 당연히 runtime classpathsubmoduleB가 포함이 되어있어야만 런타임에 정상 작동을 할 수 있기 때문.


위처럼 submoduleA자신에게 의존하는 클라이언트 모듈(main-module)에게 trhid-party 모듈(submoduleB)에 대한 정보를 (컴파일 타임에) 접근 가능하게 하려면 compile(api)으로 설정한다.

submoduleAcompile(api)로 의존성을 설정하게 되면 여기에 의존하는 main-modulecompileClasspathsubmoduleA가 의존하는 third-party 모듈(submoduleB)를 추가하기 때문에 main-module에서 submoduleB로의 접근이 컴파일 타임에도 가능하다.

즉, submoduleA가 의존하는 submoduleB에 대한 정보가 컴파일 타임에 main-module에게 노출된다.


참고