94 lines
11 KiB
Markdown
94 lines
11 KiB
Markdown
---
|
||
title: official-doc / Reproducible Builds — JVM Guide (reproducible-builds.org)
|
||
source_type: official-doc
|
||
url: https://reproducible-builds.org/docs/jvm/
|
||
archive_url:
|
||
related_branches: [feature-build-release-supply-chain-contract]
|
||
related_projects: [ca-skeleton]
|
||
tags: [official-doc, ca-skeleton, ci-cd, gradle, reproducible-builds, supply-chain]
|
||
created: 2026-06-15
|
||
vendor: reproducible-builds.org
|
||
---
|
||
|
||
# official-doc / Reproducible Builds — JVM Guide (reproducible-builds.org)
|
||
|
||
> Layer: `raw/` — 외부 자료(공식 문서)의 원문 발췌·출처 기록.
|
||
> 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 `source-summary-template` 형식으로 별도 작성. 원본은 raw에 영구 보관.
|
||
|
||
## Parent / 활용 branch
|
||
|
||
| Branch | 이 자료가 정당화하는 결정 |
|
||
|---|---|
|
||
| [[raw/branch-notes/feature-build-release-supply-chain-contract]] | Decision D10 — reproducible builds 의 cross-ecosystem 정의 + JVM nondeterminism 원인(timestamps, file ordering, locale, umask)이 Gradle 두 설정(`preserveFileTimestamps=false`, `reproducibleFileOrder=true`)으로 일부 해결됨을 공식 근거로 뒷받침 |
|
||
|
||
## 출처 / Source
|
||
|
||
- 원본 URL: https://reproducible-builds.org/docs/jvm/
|
||
- 아카이브 URL: (미등록)
|
||
- 저자 / 조직: reproducible-builds.org (community initiative)
|
||
- 발행일: 미표기 (지속 갱신)
|
||
- 마지막 확인일: 2026-06-15
|
||
|
||
보조 정의 출처: https://reproducible-builds.org/docs/definition/
|
||
|
||
## 왜 저장했는지 / Why archived
|
||
|
||
branch-note `feature-build-release-supply-chain-contract` 의 D10(`build reproducibility = preserveFileTimestamps=false, reproducibleFileOrder=true, JDK pin`)이 `UNSUPPORTED_DECISION` 라벨을 갖고 있었고, 공식 외부 source 등록이 권고된 상태였다. 본 문서는 재현가능 빌드의 공식 정의와 JVM 비결정성 원인 목록(timestamps, file ordering, locale, umask) 및 Gradle 설정 방법을 원문으로 제공하여 D10 결정을 `official-reference` 강도로 뒷받침한다.
|
||
|
||
## 핵심 인용 / Key quotes (verbatim, 5문장)
|
||
|
||
> [§definition] "A build is reproducible if given the same source code, build environment and build instructions, any party can recreate bit-by-bit identical copies of all specified artifacts."
|
||
|
||
> [§JVM intro] "The `javac` compiler generates reproducible bytecode `.class` output as do most language-specific compilers, but JVM packaging (in `.jar` files) is not reproducible-friendly – particularly timestamp of files in the archive –, each build tool requires some work mostly at packaging step to provide Reproducible Builds."
|
||
|
||
> [§Gradle] "Tasks which generate archives, such as ZIPs, JARs or Tarballs, can enforce preserved file timestamps and reproducible file order which fix two of the main sources of non-determinism in JVM artifacts. Consider setting `dirPermissions` and `filePermissions` to adjust environment specific `umask` settings."
|
||
|
||
> [§Properties files] "All properties files generated using `java.util.Properties.store()` contain a comment line with the generation timestamp. The Java system property `java.properties.date` can be used to set a fixed value used instead of the generation timestamp."
|
||
|
||
> [§Character set + locales] "When building with Java 17 or older, consider setting `file.encoding=UTF-8`. UTF-8 is the default since Java 18. Other system properties to consider depending on your build requirements are `user.language`, `user.country`, `user.variant`."
|
||
|
||
## Claims Extracted / 추출된 주장
|
||
|
||
> 이 자료가 **직접 말하는 것만** claim 으로 분리한다.
|
||
|
||
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
||
|---|---|---|---|---|---|
|
||
| RB-JVM-C1 | Reproducible build 의 공식 정의: 동일 소스코드 + 빌드환경 + 빌드지침이 주어지면 누구든 모든 지정 아티팩트를 비트 단위로 동일하게 재현할 수 있어야 함 | [§definition] "A build is reproducible if given the same source code, build environment and build instructions, any party can recreate bit-by-bit identical copies of all specified artifacts." | `official-reference` | reproducible-builds.org 가 cross-ecosystem 정의로 채택한 기준 | 이 정의가 특정 도구(Gradle 등)에서 자동 달성됨을 의미하지 않음; 달성 여부는 설정과 환경에 따라 다름 |
|
||
| RB-JVM-C2 | JVM 아티팩트 패키징(`.jar`)은 기본적으로 재현가능하지 않음 — 주요 원인은 아카이브 내 파일 타임스탬프 | [§JVM intro] "JVM packaging (in `.jar` files) is not reproducible-friendly – particularly timestamp of files in the archive –, each build tool requires some work mostly at packaging step to provide Reproducible Builds." | `official-reference` | Gradle/Maven/sbt 로 `.jar` 를 생성하는 모든 JVM 프로젝트 | Java `.class` 바이트코드 자체는 재현가능(`javac`); 비재현성은 패키징(아카이브 생성) 단계에서 발생함을 한정 |
|
||
| RB-JVM-C3 | Gradle 의 `isPreserveFileTimestamps=false` + `isReproducibleFileOrder=true` 두 설정이 JVM 아티팩트의 두 가지 주요 비결정성 원인을 제거함 | [§Gradle] "Tasks which generate archives, such as ZIPs, JARs or Tarballs, can enforce preserved file timestamps and reproducible file order which fix two of the main sources of non-determinism in JVM artifacts." | `official-reference` | Gradle v3.4 이상, `AbstractArchiveTask` 를 상속하는 모든 아카이브 태스크 (Jar, Zip, Tar) | `dirPermissions`/`filePermissions` 을 별도 설정하지 않으면 umask 차이로 인한 비결정성이 잔존함; 또한 locale/encoding 비결정성은 별도 설정 필요 |
|
||
| RB-JVM-C4 | Gradle 에서 `dirPermissions`, `filePermissions` 설정으로 umask 기인 비결정성을 추가로 제거 가능 | [§Gradle] "Consider setting `dirPermissions` and `filePermissions` to adjust environment specific `umask` settings." | `official-reference` | Gradle 로 아카이브를 생성하는 환경이 다른 CI/로컬 빌더 간 umask 가 다를 때 | umask 통일만으로 전체 재현가능성이 보장되지 않음 (locale/타임스탬프도 별도 처리 필요) |
|
||
| RB-JVM-C5 | `java.util.Properties.store()` 로 생성되는 `.properties` 파일에는 생성 타임스탬프 주석이 포함되며, `java.properties.date` 시스템 프로퍼티로 고정값으로 대체 가능 | [§Properties files] "All properties files generated using `java.util.Properties.store()` contain a comment line with the generation timestamp. The Java system property `java.properties.date` can be used to set a fixed value used instead of the generation timestamp." | `official-reference` | `java.util.Properties.store()` 를 직접 호출하거나 간접 호출하는 라이브러리(예: Spring `application.properties` 등)를 사용하는 모든 JVM 빌드 | Spring Boot 같은 프레임워크가 이 메서드를 호출하지 않으면 영향 없음; 주석 제거 여부는 도구 버전에 따라 다를 수 있음 |
|
||
| RB-JVM-C6 | Java 17 이하에서 `file.encoding=UTF-8` 설정 권고 (Java 18+ 기본값); `user.language`, `user.country`, `user.variant` 도 빌드 요건에 따라 고정 권고 | [§Character set + locales] "When building with Java 17 or older, consider setting `file.encoding=UTF-8`. UTF-8 is the default since Java 18. Other system properties to consider depending on your build requirements are `user.language`, `user.country`, `user.variant`." | `official-reference` | Java 17 이하 JVM 환경의 다국어 빌드, 또는 locale 에 따라 출력이 달라지는 플러그인/라이브러리 사용 시 | Java 18+ 에서는 `file.encoding` 기본값이 UTF-8 이므로 해당 설정 불필요; `user.language` 등의 고정 필요성은 빌드 내용에 따라 다름 |
|
||
|
||
## Usage Boundaries / 적용 경계
|
||
|
||
- 이 자료가 직접 증명하는 것:
|
||
- `RB-JVM-C1`: reproducible-builds.org 의 교차-에코시스템 공식 정의 (bit-for-bit 동일 복제 가능)
|
||
- `RB-JVM-C2`: JVM `.jar` 패키징이 기본 비재현적임 (원인: 아카이브 타임스탬프)
|
||
- `RB-JVM-C3`: Gradle `isPreserveFileTimestamps=false` + `isReproducibleFileOrder=true` 가 두 가지 주요 비결정성 원인을 제거함 (Gradle v3.4+)
|
||
- `RB-JVM-C4`: `dirPermissions`/`filePermissions` 설정으로 umask 기인 비결정성 추가 제거 가능
|
||
- `RB-JVM-C5`: Properties 타임스탬프 문제 + `java.properties.date` 로 고정 가능
|
||
- `RB-JVM-C6`: `file.encoding=UTF-8` + `user.language`/`user.country`/`user.variant` locale 고정 권고
|
||
- 이 자료가 증명하지 않는 것:
|
||
- 위 설정들만 적용하면 100% 재현가능 빌드가 보장된다는 주장 (잔존 비결정성 원인 가능)
|
||
- JDK 버전 고정(`tool-versions`)이 재현가능성에 기여함 (본 문서에 JDK 버전 고정 명시 없음 — 별도 근거 필요)
|
||
- Maven, sbt 의 재현가능 설정 방법론 (본 문서는 overview 수준만 제공, 상세는 각 도구 공식 문서 필요)
|
||
- Gradle 설정 적용 후 실제로 두 환경에서 동일 hash 가 나온다는 검증 (별도 실험으로 확인 필요)
|
||
- 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
|
||
- ca-tmpl 에서 Gradle `AbstractArchiveTask` 설정 실제 적용 후 동일 commit 2회 빌드 → SHA-256 비교 (`needs-confirmation`)
|
||
- Spring Boot 의 `bootJar` task 가 `AbstractArchiveTask` 를 상속하므로 동일 설정 적용 가능한지 확인
|
||
- `java.properties.date` 시스템 프로퍼티가 Gradle 빌드 스크립트에서 어떻게 전달되는지 확인
|
||
|
||
## 메모 / Notes
|
||
|
||
- 인용 `RB-JVM-C3` 는 "two of the main sources" 라고 표현 — '주요 두 원인 *중 하나*를 제거한다'는 뜻이 아니라 '타임스탬프와 파일 순서라는 두 원인을 제거한다'는 뜻. "of the main" 이 축소 표현이 아님.
|
||
- branch-note D10 은 `JDK version pin via .tool-versions` 도 기술하는데, 본 문서(reproducible-builds.org)에는 JDK 버전 고정에 대한 직접 진술이 없음 — JDK 고정 근거는 별도 Gradle Wrapper 또는 Toolchain 공식 문서 source 필요.
|
||
- Gradle example 코드블록은 Kotlin DSL 기준 (`isPreserveFileTimestamps`, `isReproducibleFileOrder` — Groovy DSL 에서는 `preserveFileTimestamps`, `reproducibleFileOrder` 로 표현됨). ca-tmpl 이 어느 DSL 쓰는지 확인 후 적용.
|
||
- 추가로 봐야 할 동일 출처 페이지: `https://reproducible-builds.org/docs/` (index), Maven guide to configuring reproducible builds.
|
||
|
||
## Related / 관련
|
||
|
||
- 본 자료를 인용한 branch-note: [[raw/branch-notes/feature-build-release-supply-chain-contract]]
|
||
- 같은 주제 다른 official-doc: [[raw/official-docs/supply-chain-slsa-provenance-framework]], [[raw/official-docs/supply-chain-cosign-keyless-sigstore]]
|
||
- 이 자료를 인용한 wiki 요약: (생성 시 추가)
|