--- title: testCompileOnly 타입을 ArchUnit fixture 에서 안전하게 참조하기 — annotation-only 패턴 source_type: blog-topic status: raw related_branches: [feature-streaming-response-contract] related_projects: [ca-tmpl] tags: [blog-topic, ca-tmpl, archunit, gradle, testcompileonly, fixture] created: 2026-06-02 status_label: ready-for-canonical target_audience: backend-engineer inspiration_url: archive_url: --- # testCompileOnly 타입을 ArchUnit fixture 에서 안전하게 참조하기 ## Parent - [[raw/branch-notes/feature-streaming-response-contract]] ## 글감 요약 ArchUnit violations-as-data 패턴에서 금지 타입을 `testCompileOnly` 로만 선언할 때 발생하는 `NoClassDefFoundError` 와, **annotation-only 참조** 로 해결하는 패턴. ### 핵심 발견 - `testCompileOnly` jar 는 compile-time 에만 존재 → JUnit 이 class 로드 시 superclass resolve 불가 → `NoClassDefFoundError`. - ArchUnit 의 `ClassFileImporter` 는 바이트코드 직접 파싱 → class loading 불필요. 문제는 JUnit 스캐닝. - **annotation 참조** 는 JVM 이 class load 시 즉시 resolve 하지 않으므로 안전. - `@EnableWebSocket` (spring-websocket) 을 annotation 으로만 달면: (1) ArchUnit 이 `org.springframework.web.socket..` 의존 탐지 성공, (2) runtime classpath 에 jar 없어도 class 로드 성공. ### 독자 Spring Boot + Gradle 멀티모듈 + ArchUnit 조합에서 architecture enforcement 를 구현하는 백엔드 개발자. ### 구성 아이디어 1. 문제: violations-as-data fixture 와 `testCompileOnly` 충돌 2. 원인 분석: JVM class loading vs ArchUnit bytecode parsing 3. 해결: annotation-only 참조 패턴 4. 추가 발견: `jakarta.websocket-api` server-only jar 이슈 5. 패턴 정리표 (annotation / method return type / extends 별 `testCompileOnly` 안전성) ## 트리거 / Trigger - 트리거 유형: `branch-work` - 트리거 날짜: 2026-06-02 - 트리거 연결 노트: [[raw/branch-notes/feature-streaming-response-contract]] ## 글감 / Topic seed - 한 문장 요지: `testCompileOnly` 금지 타입을 ArchUnit fixture에서 검출하려면 class loading을 유발하지 않는 annotation-only 참조가 안전하다. - 예상 제목 후보: - ArchUnit fixture에서 testCompileOnly 타입을 안전하게 참조하기 - JVM class loading과 ArchUnit bytecode parsing의 차이 ## 핵심 주장 후보 / Claim candidates - 사실 후보: - `testCompileOnly` jar는 JUnit class loading 시점에는 없을 수 있다. - ArchUnit importer는 bytecode를 직접 읽으므로 annotation 참조만으로 dependency detection이 가능하다. - 의견/해석 후보: - violations-as-data fixture는 runtime classpath 안정성까지 고려해야 한다. ## Outline seed 1. `testCompileOnly` fixture가 `NoClassDefFoundError`를 만드는 경로를 설명한다. 2. annotation-only 참조가 왜 class loading을 덜 유발하는지 정리한다. 3. streaming/WebSocket ban rule fixture에 적용할 때의 한계를 적는다. ## Canonical 전환 후보 / Canonical extraction candidates - `wiki/projects/ca-tmpl/streaming-response-support.md` 후보: - streaming/WebSocket ban ArchUnit fixture 안정화 글감. - `wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard.md` 후보: - ArchUnit fixture/testing pattern 글감. - 필요한 추가 검증: - 현재 fixture가 annotation-only 패턴으로 유지되는지. ## Sources / 근거 후보 - [[raw/branch-notes/feature-streaming-response-contract]] ## 미해결 / Unknown - 아직 확인해야 할 사실: 현재 test runtime classpath와 fixture 참조 방식. - 과장하면 안 되는 부분: annotation-only가 모든 `testCompileOnly` 참조를 안전하게 만든다고 일반화하지 않는다. ## Decision / 처리 결정 - 액션: `promote-to-canonical` - 이유: `wiki/projects/ca-tmpl/streaming-response-support.md` 와 `wiki/projects/ca-tmpl/skeleton-governance-registry-verification-test-scorecard.md` 에 ArchUnit fixture 안정화 글감으로 반영한다. - 다음 단계: streaming canonical은 verified지만, fixture classpath 세부는 blogify 전 재확인한다. ## Related / 관련 - 관련 branch: [[raw/branch-notes/feature-streaming-response-contract]]