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 를 구현하는 백엔드 개발자.
구성 아이디어
문제: violations-as-data fixture 와 testCompileOnly 충돌
원인 분석: JVM class loading vs ArchUnit bytecode parsing
해결: annotation-only 참조 패턴
추가 발견: jakarta.websocket-api server-only jar 이슈
패턴 정리표 (annotation / method return type / extends 별 testCompileOnly 안전성)
아직 확인해야 할 사실: 현재 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 전 재확인한다.