Files
llm-wiki/raw/official-docs/scoped-value-jep-446-506-openjdk.md
T

91 lines
8.0 KiB
Markdown

---
title: "official-doc / OpenJDK JEP 446 → 506 — Scoped Values (Preview → Finalized Java 25)"
source_type: official-doc
url: https://openjdk.org/jeps/506
archive_url:
related_branches: [feature-runtime-context-propagation-contract]
related_projects: [ca-skeleton, ca-tmpl]
tags: [official-doc, java-21, java-25, scoped-value, virtual-threads, structured-concurrency, context-propagation]
created: 2026-06-09
last_reviewed: 2026-06-09
status: raw
confidence: high
---
# OpenJDK JEP 446 → 506 — Scoped Values
> Layer: `raw/official-docs/` — OpenJDK JEP 의 원문 발췌.
> JEP 446 (Java 21 Preview) → JEP 464 (Java 22 Second Preview) → JEP 481 (Java 23 Third Preview) → JEP 487 (Java 24 Fourth Preview) → **JEP 506 (Java 25 Finalized)**.
> 직접 fetch 시 openjdk.org 403 반환. 아래 인용은 WebSearch 결과에서 복수의 독립 소스가 동일하게 인용한 JEP 506 본문 fragment 및 공신력 있는 secondary 소스(happycoders.eu, softwaremill.com, belief-driven-design.com) 의 verbatim 재인용으로 보강.
> **신뢰 등급**: openjdk.org 직접 fetch 불가이므로 Claims Strength = `official-standard` (JEP 는 공식 명세) + `unverified-direct-access` 주석. wiki 추출 전 openjdk.org 직접 열람 또는 archive.org 스냅샷 확인 권고.
## Parent / 활용 branch
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-runtime-context-propagation-contract]] | Alt-1 (ScopedValue) 의 공식 명세 — immutability / bounded lifetime / StructuredTaskScope inheritance 속성 근거 |
## 출처 / Source
- 원본 URL: https://openjdk.org/jeps/506 (JEP 506 — Finalized)
- 관련 JEP: https://openjdk.org/jeps/446 (Java 21 Preview), https://openjdk.org/jeps/464 (Java 22 Second Preview)
- 저자 / 조직: OpenJDK (Oracle + community)
- 발행일: JEP 506 targeted to JDK 25 — 2025-06-02 (inside.java announcement); Java 25 GA 2025-09-16
- 마지막 확인일: 2026-06-09
- 접근 상태: openjdk.org WebFetch → HTTP 403. 아래 인용은 secondary 소스를 통해 교차 검증.
## 핵심 인용 / Key quotes
> [JEP 506 Goals — per multiple secondary sources] "Ease of use — It should be easy to reason about dataflow. Comprehensibility — The lifetime of shared data should be apparent from the syntactic structure of code. Robustness — Data shared by a caller should be retrievable only by legitimate callees. Performance — Data should be efficiently sharable across a large number of threads."
> [JEP 446/506 Description — widely quoted] "A scoped value is a container object that allows a data value to be safely and efficiently shared by a method with its direct and indirect callees within the same thread, and with child threads, without resorting to method parameters."
> [JEP 446/506 — Unlike ThreadLocal] "Unlike a thread-local variable, a scoped value is written once, and is available only for a bounded period during execution of the thread."
> [JEP 506 — StructuredTaskScope inheritance] "Subtasks forked in a scope inherit ScopedValue bindings." (per WebSearch corroboration from JEP 446 description section)
> [JEP 506 finalization note] "JEP 506 was finalized in JDK 25 after five rounds of preview and incubation beginning with JDK 20, with one small change: The ScopedValue.orElse method no longer accepts null as its argument." (inside.java / Hacker News corroboration)
> [Java 21 status — JEP 446 Preview] "Scoped values incubated in JDK 20 via JEP 429 and became a preview API in JDK 21 via JEP 446." (InfoQ / WebSearch)
## Self-Grep 검증
> openjdk.org 직접 접근 불가로 자체 파일 기반 grep 불가.
> 아래 인용은 WebSearch 결과에서 동일 fragment 가 복수 소스에서 반복 등장함을 확인 (교차검증):
> - "scoped value is written once" — JEP 본문 fragment, InfoQ / happycoders.eu / softwaremill 에서 동일 표현 재인용
> - "Subtasks forked in a scope inherit ScopedValue bindings" — JEP 446 description, happycoders.eu + WebSearch snippet 에서 동일
> - Goals (Ease of use / Comprehensibility / Robustness / Performance) — WebSearch snippet 에서 JEP 506 Goals 로 직접 인용
검증한 인용 V: 4 / 교차검증 PASS P: 4 / openjdk.org 직접 grep 불가 (U=4 UNVERIFIED_DIRECT)
## Claims Extracted
| Claim ID | Claim | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| SV-C1 | ScopedValue 는 immutable — 한 번 bind 되면 값을 set() 으로 변경할 수 없다 | "a scoped value is written once, and is available only for a bounded period during execution of the thread" | `official-standard` (JEP 506, unverified-direct) | Java 21+ (preview) / Java 25+ (finalized) 코드 | 동일 ScopedValue 인스턴스에 다른 scope 에서 rebind (ScopedValue.where(...).run()) 는 허용됨 — 그 scope 안에서만 새 값이 보임 |
| SV-C2 | ScopedValue binding 은 StructuredTaskScope.fork() 로 생성된 child task 에 자동 상속된다 | "Subtasks forked in a scope inherit ScopedValue bindings" | `official-standard` (JEP 446/506, unverified-direct) | StructuredTaskScope 를 사용하는 모든 Java 21+ 코드 | StructuredTaskScope 없이 일반 Thread.start() 로 생성된 thread 에는 상속되지 않음 |
| SV-C3 | ScopedValue 의 설계 목표는 Ease of use / Comprehensibility / Robustness / Performance 4항목 | "Ease of use — It should be easy to reason about dataflow. Comprehensibility — The lifetime of shared data should be apparent from the syntactic structure of code. Robustness — Data shared by a caller should be retrievable only by legitimate callees. Performance — Data should be efficiently sharable across a large number of threads." | `official-standard` (JEP 506 Goals, unverified-direct) | Java 25+ 공식 API 설계 철학 | 이 목표가 ThreadLocal 과 비교해 benchmarked 성능을 보장하지는 않음 |
| SV-C4 | Java 21 에서는 JEP 446 으로 Preview, Java 25 에서 JEP 506 으로 Finalized | "Scoped values incubated in JDK 20 via JEP 429 and became a preview API in JDK 21 via JEP 446." + "JEP 506 was finalized in JDK 25" | `official-standard` (JEP 446 / JEP 506, unverified-direct) | Java 21 LTS 에서 ScopedValue 를 쓰는 경우 — `--enable-preview` 컴파일 플래그 필요 | Java 21 LTS 에서 production 사용 시 preview feature = ABI 비안정 |
| SV-C5 | ScopedValue.where(VALUE, data).run(task) API 패턴으로 binding scope 를 만든다 | happycoders.eu code example: `ScopedValue.where(API_KEY, apiKey).call(() -> ...)` | `official-standard` (JEP 446 API shape, secondary-corroborated) | ScopedValue 사용 코드 | `.call()` vs `.run()` 차이 (Callable vs Runnable) — 동일 semantics, return type 차이만 |
## Usage Boundaries
- 이 자료가 증명하는 것:
- `SV-C1`: immutability (set() 없음, bounded lifetime)
- `SV-C2`: StructuredTaskScope.fork() 에서 자동 상속
- `SV-C3`: 설계 목표 4항목
- `SV-C4`: Java 21 = preview (`--enable-preview` 필요), Java 25 = finalized
- `SV-C5`: API 패턴 (where + run/call)
- 이 자료가 증명하지 않는 것:
- ThreadLocal 과의 정량적 성능 차이 (JEP 에 benchmark 없음)
- Spring Boot 3.x 에서 ScopedValue 를 직접 통합하는 auto-configuration 존재 여부
- Java 21 LTS 환경에서 `--enable-preview` 없이 ScopedValue 를 사용하는 방법
- Micrometer ContextRegistry 와 ScopedValue 의 공식 통합 여부
## 메모 / Notes
- Java 21 LTS 에서 ScopedValue 는 **Preview API** — production code 에 `--enable-preview` 컴파일러 플래그 필요. Spring Boot 3.5.x 는 Java 21 LTS 기반이므로 ScopedValue 를 production 사용 시 preview flag 를 수용해야 함.
- Java 25 (2025-09-16 GA) 에서 Finalized → non-preview. Spring Boot 4.x 대상이면 Java 25 baseline 시 preview flag 불필요.
- ca-tmpl 이 Java 21 LTS 를 stack constraint 로 고정한 상태이므로 ScopedValue 는 현재 **preview 상태**로 사용 가능 — 단, `--enable-preview` flag 수용 결정 필요.
- `InheritableThreadLocal` 금지 ArchUnit rule 이 있는 환경이므로 ScopedValue 는 자연스러운 대안.