8.4 KiB
title, source_type, url, archive_url, related_branches, related_projects, tags, created
| title | source_type | url | archive_url | related_branches | related_projects | tags | created | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Spring Boot Exit Code Mechanism — ExitCodeGenerator, ExitCodeExceptionMapper, startup failure path | official-doc | https://docs.spring.io/spring-boot/reference/features/spring-application.html#features.spring-application.application-exit |
|
|
|
2026-06-09 |
Spring Boot Exit Code Mechanism — ExitCodeGenerator, ExitCodeExceptionMapper, startup failure path
Layer:
raw/official-docs/— Spring Boot 공식 참조 문서 + spring-boot-3.4.0-sources.jar 직독.
Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| raw/branch-notes/feature-migration-startup-contract | D7: startup exit code 표준(78/70/71/72)의 Spring Boot 측 메커니즘 — ExitCodeExceptionMapper가 context refresh 실패 시 실제로 호출되는지, 기본 exit code가 무엇인지 |
출처 / Source
- 원본 URL: https://docs.spring.io/spring-boot/reference/features/spring-application.html#features.spring-application.application-exit
- ExitCodeExceptionMapper javadoc: https://docs.spring.io/spring-boot/api/java/org/springframework/boot/ExitCodeExceptionMapper.html
- 소스코드 직독: spring-boot-3.4.0-sources.jar,
org/springframework/boot/SpringApplication.java(로컬 Gradle 캐시:/home/donghyeon/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot/3.4.0/) - 저자 / 조직: Phillip Webb, Dave Syer (Spring Boot 핵심 기여자)
- 마지막 확인일: 2026-06-09
왜 저장했는지 / Why archived
D7 결정(startup exit code = 78/70/71/72)을 구현할 때 Spring Boot가 제공하는 exit code 메커니즘이 실제로 startup failure 시 작동하는지 확인하기 위해 수집. ExitCodeExceptionMapper가 context refresh 실패 시점에 호출 가능한지가 핵심 질문.
핵심 인용 / Key quotes (verbatim)
[§Application Exit] "In addition, beans may implement the
ExitCodeGeneratorinterface if they wish to return a specific exit code whenSpringApplication.exit()is called. This exit code can then be passed toSystem.exit()to return it as a status code."
[§Application Exit] "Also, the
ExitCodeGeneratorinterface may be implemented by exceptions. When such an exception is encountered, Spring Boot returns the exit code provided by the implementedgetExitCode()method."
[§Application Exit] "If there is more than one
ExitCodeGenerator, the first non-zero exit code that is generated is used. To control the order in which the generators are called, additionally implement theOrderedinterface or use the@Orderannotation."
[SpringApplication.java:896-899, source]
private int getExitCodeFromMappedException(ConfigurableApplicationContext context, Throwable exception) { if (context == null || !context.isActive()) { return 0; } ... }
[SpringApplication.java:1412, source]
exitCode = (exitCode != 0) ? exitCode : 1;
Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| SB-EXIT-C1 | ExitCodeGenerator interface를 implements한 bean은 SpringApplication.exit() 호출 시 지정한 exit code를 반환한다 |
[§Application Exit] "beans may implement the ExitCodeGenerator interface if they wish to return a specific exit code when SpringApplication.exit() is called" |
official-vendor-doc |
Spring Boot 1.0+ 모든 버전 | SpringApplication.exit()가 호출되어야 작동함. main()에서 System.exit(SpringApplication.exit(...)) 패턴이 없으면 이 경로가 실행되지 않는다 |
| SB-EXIT-C2 | 예외 클래스 자체가 ExitCodeGenerator를 구현하면, 그 예외가 발생할 때 해당 exit code가 반환된다 | [§Application Exit] "the ExitCodeGenerator interface may be implemented by exceptions. When such an exception is encountered, Spring Boot returns the exit code provided by the implemented getExitCode() method" |
official-vendor-doc |
Spring Boot 3.x startup exception chain 내 어떤 위치에서든 작동 (context 의존 없음) | ExitCodeExceptionMapper와 달리 context active 상태 불필요 — 단, 예외 클래스를 직접 수정 가능해야 함 |
| SB-EXIT-C3 | ExitCodeExceptionMapper는 context == null 또는 !context.isActive() 이면 조회되지 않는다 (exit code 0 반환) |
[SpringApplication.java:896-899] if (context == null || !context.isActive()) { return 0; } |
official-vendor-doc (소스코드 직독) |
Spring Boot 3.4.0. context refresh 실패(BeanCreationException 등)는 isActive()=false에 해당함 | ExitCodeExceptionMapper bean이 등록된 경우라도, env 누락처럼 context 생성 이전 실패에는 해당 bean이 조회되지 않음을 증명 |
| SB-EXIT-C4 | startup 실패 시 exit code 결정 순서: (1) ExitCodeExceptionMapper (context active 필요), (2) 예외의 ExitCodeGenerator 구현, (3) 둘 다 0이면 최종 fallback = 1 | [SpringApplication.java:888-893, 1412] getExitCodeFromMappedException → getExitCodeFromExitCodeGeneratorException → exitCode = (exitCode != 0) ? exitCode : 1 |
official-vendor-doc (소스코드 직독) |
Spring Boot 3.4.0 startup failure path (handleRunFailure → handleExitCode → getExitCodeFromException) | 이 순서는 Spring Boot 버전마다 다를 수 있음. 3.4.0 소스 직독 기준. |
| SB-EXIT-C5 | SpringBootExceptionHandler가 UncaughtExceptionHandler로 등록되어 있어, 커스텀 exit code가 실제로 JVM System.exit()로 전파된다 | [SpringBootExceptionHandler.java:49,63] void registerExitCode(int exitCode) { this.exitCode = exitCode; } + if (this.exitCode != 0) { System.exit(this.exitCode); } |
official-vendor-doc (소스코드 직독) |
Spring Boot 3.4.0 main thread uncaughtException path | 커스텀 exit code가 등록되어야 이 경로가 실행됨. 등록이 0이면 System.exit()가 호출되지 않고 예외가 전파됨 |
| SB-EXIT-C6 | Spring Boot 공식 문서는 특정 숫자 exit code (78, 70, 71, 72)를 권장하거나 정의하지 않는다 | [§Application Exit] 예시 코드: return () -> 42; — 숫자 선택은 애플리케이션 구현자의 책임 |
official-vendor-doc |
모든 Spring Boot 버전 | 어떤 숫자를 exit code로 사용해야 하는지는 공식이 규정하지 않음 — sysexits(3) 같은 외부 컨벤션을 따르는 것은 구현자 결정 |
Usage Boundaries / 적용 경계
- 이 자료가 직접 증명하는 것:
SB-EXIT-C3: ExitCodeExceptionMapper bean은 context refresh 실패 시 호출되지 않음 (context.isActive() = false 조건)SB-EXIT-C2: 예외 클래스 자체가 ExitCodeGenerator를 구현하면 context 상태 무관하게 exit code 적용됨SB-EXIT-C4: 커스텀 exit code 없을 때 기본 fallback = 1SB-EXIT-C5: SpringBootExceptionHandler를 통해 JVM 실제 exit code로 전파됨
- 이 자료가 증명하지 않는 것:
- 어떤 숫자를 exit code로 사용해야 하는지 (78, 70, 71, 72 등) — Spring Boot는 숫자 규약을 정의하지 않음 (SB-EXIT-C6)
- Kubernetes가 이 exit code를 어떻게 처리하는지
- ExitCodeExceptionMapper bean이 migration failure처럼 context active 상태에서 발생하는 실패에 작동하는지 — 소스 분석에 따르면 작동하지만 ca-tmpl integration test 검증 필요
- 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
- env 누락 실패가 실제로 context == null 또는 !isActive() 경로를 타는지 ca-tmpl에서 직접 확인
- migration failure(Flyway ApplicationRunner)에서 ExitCodeExceptionMapper vs ExitCodeGenerator 중 어느 것이 더 신뢰할 수 있는지 테스트
메모 / Notes
- ExitCodeExceptionMapper는 graceful shutdown (
SpringApplication.exit()호출)과 ApplicationRunner 실패 시 잘 작동하지만, env 누락처럼 context 생성 이전 실패에는 ExitCodeGenerator 구현이 유일한 방법. - Spring Boot가 exit code 숫자 규약을 정의하지 않으므로, 78/70/71/72는 sysexits(3) BSD 컨벤션을 따르는 ca-tmpl 내부 결정임.
Related / 관련
- raw/official-docs/sysexits-bsd-exit-code-convention — BSD sysexits(3) 컨벤션 (EX_CONFIG=78, EX_SOFTWARE=70 등)
- raw/branch-notes/feature-migration-startup-contract — D7 결정 (UNSUPPORTED_DECISION 라벨 해소 대상)