Skip to content

design(runtime): GraalVM Native Image 採用 ADR(docs/adr/0008-...) + コーディング規約 §X Native Image 制約追記 #223

Description

@win2cot

Phase 1 Setup 2-4: GraalVM Native Image 採用 ADR + コーディング規約追記

概要

tasks-webapi の実行環境として GraalVM Native Image を採用する判断を ADR として記録し、コーディング規約に Native Image 実装制約セクションを追加する。

  • docs/adr/0008-graalvm-native-image.md 新規作成
  • docs/specs/コーディング規約.md に Native Image 実装制約セクション追記

採用方針は infrastructure-plan v5 §2 #5 / §3.4 で確定済(2026-05-23、Spring プロファイル不使用の理由として明示)。

詳細仕様: docs/architecture/infrastructure-plan.md v5 §3.4。

背景

infrastructure-plan v5 策定中の議論で、tasks-webapi を Fat JAR ではなく GraalVM Native Image で配信する方針を選定。

理由:

  • 起動時間短縮(ECS Fargate cold start に効く)
  • メモリ削減(Fargate task size 縮小、コスト削減)
  • Container image サイズ小
  • セキュリティ攻撃面縮小

ただし制約:

  • ビルド時間長期化
  • Reflection / Dynamic Class Loading は build-time hints が必要
  • Spring プロファイル不使用(Native Image build profile は別、ENV 変数注入で代替)
  • 一部の JVM-only ライブラリは Native build で動作しない

判断根拠 + 開発時の実装制約を ADR + コーディング規約で残す。

議論ポイント(ADR で記録)

  1. コスト: ビルド時間 vs ランタイム最適化
  2. Spring Boot Native サポート状況: Spring Boot 4 + AOT 機能の安定性
  3. 依存ライブラリ互換性: 現在使用中ライブラリの Native 対応(Hibernate / Flyway / Keycloak adapter / etc.)
  4. Reflection ヒント管理: @RegisterReflectionForBinding / META-INF/native-image/... の戦略
  5. CI/CD impact: Native build 時間が GHA runner で許容範囲か
  6. ローカル開発: Native build を毎回しない、Fat JAR / ./gradlew :webapi:bootRun で開発、CI で Native build 検証
  7. デプロイ: Fargate に Native binary を含む Docker image を push

ADR 内容(docs/adr/0008-graalvm-native-image.md)

下記セクションを含む:

  • Title / Status (Accepted)
  • Context(infrastructure-plan v5 策定議論、Fat JAR vs Native Image の trade-off)
  • Decision(Native Image 採用、Spring プロファイル不使用の伏線として位置付け)
  • Consequences(ビルド複雑化 / 起動高速 / メモリ削減 / Reflection 制約)
  • Alternatives Considered(Fat JAR + JIT、Layered JAR、CRaC 等)
  • Related: infrastructure-plan v5 §3.4、コーディング規約 §X(Native Image 実装制約)

コーディング規約追記内容(docs/specs/コーディング規約.md)

下記セクションを追加(章番号は既存に応じて):

§X. Native Image 実装制約

  • Reflection 禁止 / 明示登録: 動的に class を解決する API(Reflection / Proxy / SerializationProxy)は使用しない、または @RegisterReflectionForBinding で build-time hint を出す
  • Spring プロファイル不使用: @Profile annotation 使用禁止、環境差は @Value("${ENV_VAR}") + ECS Task Definition env vars で吸収
  • 動的 class loading 禁止: Class.forName(...) 等は使わない
  • Native build 設定: webapi/build.gradle に GraalVM Native plugin を追加(Sprint 0/1 で実施)
  • CI で Native build 検証: PR で :webapi:nativeBuild(Sprint 1 以降で workflow に追加)
  • ローカル開発: Native build を毎回しない、JVM で ./gradlew :webapi:bootRun + Native build は CI のみで OK

受入条件

  • docs/adr/0008-graalvm-native-image.md が存在し、accepted status
  • docs/specs/コーディング規約.md に Native Image 実装制約セクション(§X)が追加
  • 議論ポイント 1〜7 すべてに比較・根拠が記載
  • Reflection ヒント / Spring プロファイル不使用 / 動的 class loading 禁止 が明文化
  • Phase 1 Sprint 0 App / Sprint 2 Infra(deploy CI/CD)で参照可能
  • Spring プロファイル不使用の理由が Native Image 対応の伏線として記述されている(infrastructure-plan v5 §2 Github ActionsでCIを実行する #5 と整合)

関連

備考

  • task-type: task-type:design
  • 優先度: priority/p0(Sprint 0 App 着手前に確定したい)
  • area: area/backend + area/docs

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/backendJava / Spring バックエンド実装変更area/docsdocs/ 配下のドキュメント(設計書・規約・ADR 等)変更claude:ready実装着手 OK のサイン。人が付与すると実装 Claude が起動priority/p0Critical / Blocker。本番影響あり、または他作業がブロックされるtask-type:design規約・ADR・設計書の追加/変更タスク

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions