본문 바로가기

CS

[Spring boot] Gradle Toolchains (3/3)

설치 경로, 우선순위, 플러그인에서의 Tool Chain 활용


이 글은 Gradle Toolchains 공식 문서의 마지막 편으로, tool chain 설치 경로 구성, 우선순위 규칙, plugin 또는 커스텀 task에서의 활용, Alpine 환경 제한사항까지 포함합니다.

 

📁 Tool Chain 설치 경로 수동 지정

자동 감지가 부족하거나 비활성화된 경우, tool chain 경로를 명시적으로 Gradle에 알려줄 수 있습니다.

 

환경 변수 기반 지정

환경 변수 JDK8, JRE17이 유효한 Java 설치 경로를 가리킨다고 가정할 때:

org.gradle.java.installations.fromEnv=JDK8,JRE17

Gradle은 해당 환경 변수를 확인하여 설치된 Java로 간주합니다.

 

설치 경로 직접 지정

여러 설치 디렉터리를 쉼표로 나열하여 지정할 수도 있습니다:

org.gradle.java.installations.paths=/custom/path/jdk1.8,/shared/jre11
  • Gradle은 각 디렉터리를 설치 위치로 인식합니다.
  • 중첩 디렉터리는 탐색하지 않음

❗ 이 방식은 자동 감지 결과를 대체하는 것이 아니라 확장합니다. 즉, toolchain 선택 시 우선순위 기준에 따라 자동 감지된 항목과 함께 평가됩니다.

 

🥇 Tool Chain 설치 우선순위


Gradle은 다음과 같은 다단계 정렬 기준에 따라 일치하는 설치 목록을 평가하고 하나를 선택합니다:

  1. 현재 Gradle 실행 중인 설치가 가장 우선
  2. JDK > JRE
  3. 벤더 우선순위 (상위 → 하위)
    ADOPTIUM > ADOPTOPENJDK > AMAZON > APPLE > AZUL > BELLSOFT > GRAAL_VM > HEWLETT_PACKARD > IBM > JETBRAINS > MICROSOFT > ORACLE > SAP > TENCENT > 기타
  4. 메이저 버전 우선
  5. 마이너 버전 우선
  6. 설치 경로의 사전순 (동일한 vendor/version일 경우 최종 판단 기준)

 

예시

요청: Java 17
감지된 설치:

  • Oracle JRE 17.0.1
  • Oracle JDK 17.0.0
  • Microsoft JDK 17.0.0
  • Microsoft JRE 17.0.1
  • Microsoft JDK 17.0.1

선택 순위:

  1. Microsoft JDK 17.0.1
  2. Microsoft JDK 17.0.0
  3. Oracle JDK 17.0.0
  4. Microsoft JRE 17.0.1
  5. Oracle JRE 17.0.1

Gradle은 이 순서대로 평가하며, 첫 번째 항목인 Microsoft JDK 17.0.1을 선택합니다.

 

🧩 Plugin 또는 커스텀 Task에서의 Tool Chain 사용

plugin이나 task를 작성할 때 tool chain을 사용하는 방법:

 

기본 Tool Chain을 convention으로 사용

abstract class CustomTaskUsingToolchains extends DefaultTask {

  @Nested
  abstract Property<JavaLauncher> getLauncher()

  CustomTaskUsingToolchains() {
    def toolchain = project.extensions.getByType(JavaPluginExtension.class).toolchain
    Provider<JavaLauncher> defaultLauncher = getJavaToolchainService().launcherFor(toolchain)
    launcher.convention(defaultLauncher)
  }

  @TaskAction
  def showConfiguredToolchain() {
    println launcher.get().executablePath
    println launcher.get().metadata.installationPath
  }

  @Inject
  protected abstract JavaToolchainService getJavaToolchainService()
}
  • @Nested 속성은 tool chain 변경 시 task가 영향을 받도록 합니다.
  • launcher.convention(...)을 통해 기본값을 설정하면서, 사용자는 override 가능

 

실제 사용 예시

plugins {
  id 'java'
}

java {
  toolchain {
    languageVersion = JavaLanguageVersion.of(8)
  }
}

tasks.register('showDefaultToolchain', CustomTaskUsingToolchains)

tasks.register('showCustomToolchain', CustomTaskUsingToolchains) {
  launcher = javaToolchains.launcherFor {
    languageVersion = JavaLanguageVersion.of(17)
  }
}
  • showDefaultToolchain: 기본 Java 8 tool chain 사용
  • showCustomToolchain: Java 17로 override

 

plugin 없이 tool chain 직접 사용

java plugin이 적용되지 않은 경우에도 JavaToolchainService를 직접 사용해 tool chain을 사용할 수 있습니다:

javaToolchainService.launcherFor({})

※ 빈 사양은 현재 Gradle을 실행 중인 JVM을 기준으로 선택합니다.

 

⚠️ 제한사항: Alpine 및 musl 환경


Gradle이 musl 기반 JVM (예: Alpine Linux에서 사용)에서 실행될 경우:

  • LD_LIBRARY_PATH가 오버라이드되며
  • Gradle이 포크한 java 프로세스에서 예기치 않은 동작이 발생할 수 있습니다.

🔴 이로 인해 여러 tool chain을 사용하는 것이 비추천되며,
가능하다면 Ubuntu 등의 다른 배포판 사용을 고려해야 합니다.

단, Gradle 실행과 빌드 모두 동일한 JVM 하나만 사용하는 경우에는 해당 제한사항을 무시해도 됩니다.

 

✅ 정리


Gradle의 tool chain 기능은 다음과 같은 경우에 유용합니다:

  • 여러 JDK 버전 간의 빌드 재현성을 보장하고 싶을 때
  • 작업 단위로 JDK를 세분화해 관리하고 싶을 때
  • CI 환경에서 자동으로 필요한 JDK를 다운로드하고 설정하고 싶을 때
  • 플러그인/커스텀 task에서 일관된 JVM 도구를 사용하고 싶을 때

 

관련 문서


 

Toolchains for JVM projects

In case you want to tweak which toolchain is used for a specific task, you can specify the exact tool a task is using. For example, the Test task exposes a JavaLauncher property that defines which java executable to use for launching the tests. In the exam

docs.gradle.org

'CS' 카테고리의 다른 글

@PathVariable vs @RequestParam  (0) 2025.05.17
[Spring boot] Gradle Toolchains (2/3)  (0) 2025.05.05
[Spring boot] Gradle Toolchains (1/3)  (0) 2025.05.04
[CS] HTTP 상태 코드  (0) 2025.03.14
[JAVA] Exception & Error  (0) 2024.12.12