Gradle 플러그인
net.benelog.spidersilk 플러그인은 패키징 컨벤션을 담고 있으므로, 빌드는 애플리케이션 자신의 것만 명시한다: 메인 클래스, 이미지 이름, 네이티브 바이너리의 리소스다.
플러그인이 없으면 Jib으로 컨테이너화하고, 템플릿을 미리 컴파일하고, 경우에 따라 네이티브 바이너리로 컴파일하는 애플리케이션은 모든 빌드 파일에 같은 블록을 되풀이해 적어야 한다.
plugins {
id 'net.benelog.spidersilk' version '1.1.0'
}
spiderSilk {
jte() // precompiled templates; leave out for FreeMarker, Handlebars, or Thymeleaf
json() // generated JSON codecs for the types annotated @JsonBound
}
application {
mainClass = 'flashcard.FlashcardApp'
}
jib {
to {
image = 'ghcr.io/benelog/spider-silk-flashcard'
}
}
플러그인은 Gradle Plugin Portal이 아니라 jar와 함께 Maven Central에 발행(publication)된다.
Gradle은 기본적으로 플러그인 id를 Plugin Portal에서만 찾으므로, settings.gradle이 플러그인 저장소에 Central을 추가한다:
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
}
적용하면 일어나는 일
플러그인을 적용하면 application, Jib, GraalVM 네이티브 플러그인이 적용되고, 배포 장과 네이티브 이미지 장이 다루는 컨벤션이 설정된다:
-
Jib은
eclipse-temurin:25-jre위에 빌드하고 포트 8080을 노출하며, 배포가 설명하는 방식으로 레이어를 나눈다. -
targetCompatibility가options.release에서 도출되므로, Jib은 툴체인의 버전 대신 release를 읽고 JRE 베이스를 받아들인다. -
네이티브 바이너리는
--no-fallback으로 빌드하는데, 폴백 이미지란 프레임워크가 피하려는 리플렉션을 그대로 실은 JVM이기 때문이다. 또한 대부분 정적으로(--static-nolibc) 빌드하므로, 아래의distroless/base컨테이너는 glibc 외에는 아무것도 제공할 필요가 없다. H2 같은 라이브러리를 위해 GraalVM의 도달 가능성 메타데이터 저장소가 활성화된다. -
resolveDependencies태스크는 Dockerfile의 의존성 캐시 레이어를 위해 외부 런타임 jar만을 내려받는다. -
-Pnative는jib,jibBuildTar,jibDockerBuild의 목표를 GraalVM 바이너리로 돌린다: JRE 대신distroless/base이미지, JVM 이미지를 덮어쓰지 않도록 설정된 이미지 이름에 태그가 없을 때 덧붙는:native, 그리고nativeCompile에 대한 태스크 의존성 연결이다. 네이티브 이미지 장이 그 전환이 실제로 동작하는 모습을 보여준다.
베이스 이미지, 포트, 네이티브 빌드 인자는 빌드 스크립트 자신의 블록이 실행되기 전에 자리 잡으므로, 평소처럼 jib이나 graalvmNative를 설정해 재정의한다.
targetCompatibility 맞춤과 -Pnative 전환은 반대로 빌드 스크립트가 실행된 뒤에 적용되므로, 빌드 스크립트가 설정한 값보다 우선한다.
따라서 -Pnative에서는 jib 블록이 다른 이미지를 지정해도 베이스 이미지가 distroless/base가 된다.
다이어그램은 소스와 빌드가 만들 수 있는 두 이미지 사이에 플러그인이 무엇을 연결하는지 보여준다:
spiderSilk.json()
json()은 또 하나의 옵트인으로, 생성되는 JSON 코덱으로 타입을 바인딩하는 애플리케이션을 위한 것이다.
이 메서드는 플러그인 자신의 버전인 silk-json-processor를 javac의 annotationProcessor 경로에 올리고, jakarta.json.bind-api를 컴파일 클래스패스에 더하는데, 그 애너테이션은 거기서 읽히고 다시는 필요 없다.
런타임 클래스패스에는 아무것도 닿지 않는다.
플러그인이 고정하는 것
플러그인의 버전은 플러그인이 적용하는 도구의 버전을 고정한다: jte 3.2.4, Jib 3.5.4, GraalVM 빌드 도구 1.1.14, 그리고 json() 아래에서는 플러그인 자신의 버전인 프로세서와 jakarta.json.bind-api 3.0.4이다.
이 도구들의 버전 올림은 플러그인 릴리스로 이루어진다.
플러그인이 설정하는 각 컨벤션은 순수한 Gradle 몇 줄이며, 위에 링크된 장들은 컨벤션을 직접 소유하려는 빌드를 위해 펼친 형태를 보여준다.
Maven 빌드는 같은 컨벤션을 대신 부모 POM에서 상속받는다: Maven 부모 POM을 참고한다.