The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.
Follows the import procedure in README.md.
source/ the originating repository verbatim — 78 documents, 28 SVGs,
8 manifests, plus .source-revision recording the commit
final/ the SSOT
document.md 729 lines written from the 29 experiment documents, not
concatenated: what was predicted, what was measured, and
where the measurement itself was wrong
evidence/raw 125 outputs, flattened to <experiment>__<file> because
the originals collided (01-baseline.txt appeared three
times) and the audit only globs the top level
evidence/meta one per raw file; command and exitCode are null and the
README says why rather than inventing them
evidence/browser 22 captures
assets/ three diagrams through techviz
.techviz/ their VizSpecs
A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.
Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.
verify-pipeline.py passes. audit-records.py reports no issues.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
109 lines
4.8 KiB
Markdown
109 lines
4.8 KiB
Markdown
---
|
|
kind: CASE
|
|
slug: analysis-finding-a14-f016
|
|
title: 이 leaf의 리액티브 절반 29개 파일은 어떤 출하 배포에서도 활성화될 수 없다
|
|
topic: web-inbound-and-http-surface
|
|
project: clean-architecture-backend-template
|
|
status: 게시 전
|
|
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
|
rootTreeNode: case:analysis-finding-a14-f016
|
|
evidenceCapturedOn: 2026-09-01
|
|
body: case-analysis-finding-a14-f016.body.md
|
|
assets:
|
|
- key: analysis-finding-a14-f016
|
|
file: ../../../final/evidence/rendered/analysis-finding-a14-f016.svg
|
|
evidence:
|
|
- ../../../final/evidence/raw/analysis-finding-a14-f016.txt
|
|
source:
|
|
- 원본 분석 절은 analysis/14-adapter-inbound-web.md#L1378 이다.
|
|
---
|
|
|
|
# 이 leaf의 리액티브 절반 29개 파일은 어떤 출하 배포에서도 활성화될 수 없다
|
|
|
|
반응형 조건 애너테이션은 애플리케이션 형이 반응형일 때만 참이다. 클래스패스 추론은 서블릿 디스패처가 있으면 반응형 프레임워크가 함께 있어도 서블릿을 고른다. 이 저장소의 클래스패스가 서블릿을 고정한다.
|
|
|
|
## 관계
|
|
|
|
- **플랫폼 요청 컨텍스트가 서블릿에는 생산자가 없고 리액티브에는 익명 액터로 고정되어 있다**
|
|
이 사례가 그것을 완결한다.
|
|
- **리액티브 전송에는 속도 제한 경로가 하나도 없다**
|
|
같은 리프의 반응형 사례다.
|
|
- **조건은 참이 될 수 있어야 조건이다**
|
|
이 사례가 그 규칙의 형태다.
|
|
|
|
## 문제
|
|
|
|
이 리프의 반응형 절반은 조건 애너테이션으로 활성화된다.
|
|
|
|
그 조건이 이 저장소에서 참이 될 수 있는지 확인했다.
|
|
|
|
## 결론
|
|
|
|
될 수 없다.
|
|
|
|
조건은 애플리케이션 형이 반응형일 때만 참이다.
|
|
|
|
클래스패스 추론 메서드는 서블릿 디스패처와 컨테이너 초기화기가 있으면 반응형 프레임워크가 함께 있어도 서블릿을 고른다.
|
|
|
|
이 저장소의 클래스패스가 서블릿을 고정한다. 근거가 넷이다.
|
|
|
|
이 리프의 빌드 파일이 서블릿 스타터를 구현 의존성으로 선언하고, 반응형은 서버 없는 프레임워크와 반응 라이브러리만 가져온다. 그 선택의 근거도 적혀 있다. 두 번째 내장 서버를 실행 클래스패스에 올리게 된다는 것이다.
|
|
|
|
부트스트랩 잠금 파일에 서블릿 컨테이너와 서블릿 웹 항목이 있다.
|
|
|
|
표본 애플리케이션의 빌드 파일도 서블릿 스타터를 선언한다.
|
|
|
|
그리고 주 소스 어디에도 애플리케이션 형을 반응형으로 지정하는 코드가 없다. 테스트 하네스 세 곳에만 참조가 있고 전부 없음이나 서블릿이다.
|
|
|
|
따라서 애플리케이션 형은 항상 서블릿이고, 이 리프의 모든 반응형 조건은 영구히 거짓이다.
|
|
|
|
꺼진 채로 남는 것이 주 소스 스물아홉 파일이다.
|
|
|
|
반응형 자동 설정 둘과 문맥 둘, 오류와 예산과 가드와 멱등과 연산과 조절 여덟, 파일 서버 반응형 열, 고급 반응형 일곱이다.
|
|
|
|
그중 문맥 패키지가 결정적이다. 이 리프의 유일한 프로덕션 요청 컨텍스트 생산자가 거기 있다.
|
|
|
|
그래서 요청 컨텍스트 사례가 이것으로 완결된다.
|
|
|
|
서블릿에는 생산자가 없고 반응형에는 생산자가 있으나 그 절반이 켜지지 않는다.
|
|
|
|
판정은 P1 이다.
|
|
|
|
## 검증 환경
|
|
|
|
Spring Boot : 4.0.8
|
|
확인 방식 : 클래스패스 추론 규칙 확인과 빌드 파일, 잠금 파일 대조
|
|
소스 수정 : x
|
|
|
|
## 재현 조건
|
|
|
|
원문은 final/evidence/raw/176 계열에 있다.
|
|
|
|
1. 반응형 조건 애너테이션이 무엇을 요구하는지 확인한다.
|
|
2. 클래스패스 추론 메서드의 우선순위를 확인한다.
|
|
3. 리프의 빌드 파일에서 서블릿 스타터 선언을 확인한다.
|
|
4. 부트스트랩과 표본의 잠금 파일과 빌드 파일을 확인한다.
|
|
5. 주 소스에서 애플리케이션 형 지정 코드를 검색한다.
|
|
6. 반응형 조건이 붙은 파일을 센다.
|
|
|
|
## 본문
|
|
|
|
<!-- body:start -->
|
|
|
|
`@ConditionalOnWebApplication(type = REACTIVE)`는 Spring Boot의 `WebApplicationType`이 `REACTIVE`일 때만 참이다. `deduceFromClasspath()`는 `DispatcherServlet`과 `ServletContainerInitializer`가 있으면 WebFlux가 함께 있어도 `SERVLET`을 고른다.
|
|
|
|
## WebApplicationType 참조 위치
|
|
|
|
:::evidence key="analysis-finding-a14-f016" alt="코드베이스에서 WebApplicationType 를 검색한 출력 3줄. 이 기록이 세는 참조가 그 출력에 그대로 보인다." caption="WebApplicationType 코드베이스 검색 — 3줄 · exit 0" zoom="true"
|
|
:::
|
|
|
|
## 그래서 리액티브 절반 29개 파일이 활성화되지 않는다
|
|
|
|
어떤 출하 배포에서도 그렇다.
|
|
|
|
## 확인하지 못한 것
|
|
|
|
애플리케이션을 띄워 반응형 빈이 없는 것을 확인하지 않았다. 추론 규칙과 클래스패스상 그 결과가 나온다.
|
|
|
|
<!-- body:end -->
|