Skip to content

Latest commit

 

History

History
58 lines (42 loc) · 5.17 KB

File metadata and controls

58 lines (42 loc) · 5.17 KB

01 — 모듈 지형도: 네 패키지, 두 개의 축

무엇을 / 왜

spring-core-test는 다른 모듈처럼 "런타임 기능"을 제공하지 않는다. 이 모듈의 산출물(JAR)은 테스트 컴파일 클래스패스와 -javaagent로만 쓰인다. 그래서 책임을 이해하려면 "AOT 처리 결과를 어떻게 검증하는가?"라는 질문에서 출발해야 한다. 이 챕터는 네 개 패키지가 어떤 역할로 나뉘는지, 그리고 그것이 어떻게 두 개의 큰 축으로 묶이는지를 먼저 조감한다.

두 개의 축

                    AOT(Ahead-Of-Time)가 만든 산출물을 검증한다
                                  │
        ┌─────────────────────────┴──────────────────────────┐
        │                                                     │
  [축 1] 생성된 코드가                              [축 2] 런타임 메타데이터(힌트)가
        컴파일·동작하는가?                                 누락되지 않았는가?
        │                                                     │
  core.test.tools                                       aot.agent
  (TestCompiler)                                        (RuntimeHintsAgent)
        │                                                     │
  aot.test.generate                                     aot.test.agent
  (AOT GeneratedFiles → TestCompiler 어댑터)            (RuntimeHintsRecorder + Assert)
  • 축 1 — 동적 컴파일: AOT 프로세서는 빈 등록 코드, 프록시, 리플렉션 등록 코드를 .java 소스로 생성한다. 테스트는 그 소스를 실제 javac로 컴파일해 "정말 빌드되는지", "로딩하면 의도대로 빈을 만드는지"를 확인해야 한다. TestCompiler가 이걸 디스크 없이 메모리 안에서 해낸다. → 02, 03장.
  • 축 2 — 힌트 검증: GraalVM 네이티브 이미지는 리플렉션·리소스·프록시를 RuntimeHints로 사전 등록해야만 동작한다. 등록을 빠뜨리면 네이티브에서만 터진다. Java Agent가 바이트코드를 계측해 "실행 중 실제로 쓰인 호출"을 기록하고, 설정한 힌트가 그걸 전부 덮는지 대조한다. → 05장.

두 축을 잇는 부속이 aot.test.generate(생성 파일을 컴파일러 입력으로 변환)와 보조 유틸 **MockSpringFactoriesLoader**다. → 04장.

패키지별 책임

패키지 핵심 타입 책임
core.test.tools TestCompiler, Compiled, SourceFile 자바 소스/리소스/클래스를 메모리에서 컴파일하고 결과를 클래스로 로딩
core.test.tools (격리) @CompileWithForkedClassLoader 컴파일된 클래스가 테스트 클래스로더를 오염시키지 않도록 포크된 로더에서 실행
aot.test.generate TestGenerationContext, CompilerFiles AOT GenerationContext/GeneratedFilesTestCompiler 입력으로 변환
core.test.io.support MockSpringFactoriesLoader spring.factories 로딩을 코드로 흉내내는 테스트용 목
aot.agent RuntimeHintsAgent, InstrumentedMethod 바이트코드 계측으로 리플렉션/리소스 호출 기록 (deprecated 7.0)
aot.test.agent RuntimeHintsRecorder, RuntimeHintsInvocationsAssert 기록된 호출을 RuntimeHints와 대조하는 테스트 API

"deprecated"의 의미 — 축 2는 사양길

aot.agentaot.test.agent의 공개 진입점들은 7.0에서 @Deprecated(since = "7.0", forRemoval = true)로 표시되었다. 권장 대체재는 GraalVM JVM 플래그다.

-XX:MissingRegistrationReportingMode=Warn   (누락 힌트를 경고)
-XX:MissingRegistrationReportingMode=Exit   (누락 시 종료)

RuntimeHintsAgent.java 클래스 주석에 그 의도가 명시되어 있다. 즉, 바이트코드를 계측해 우리가 직접 호출을 추적하던 방식은, GraalVM 런타임이 직접 누락을 보고해주는 방식으로 옮겨가는 중이다. 그래도 코드는 7.1에 그대로 남아 있고 설계가 흥미로워, 이 책에서는 동작 원리를 5장에서 다룬다.

설계 포인트

  • 메인 코드 / 테스트 코드의 분리를 깬다(의도적으로): 이 모듈은 src/main/java에 있지만 사실상 테스트 인프라다. 그래서 JUnit·AssertJ·qdox 의존을 optional/compileOnly로 둬, 이 모듈을 쓰는 쪽이 필요한 것만 끌어쓰게 한다(spring-core-test.gradle).
  • JAR 매니페스트가 곧 진입점: 빌드 스크립트가 Premain-Class: org.springframework.aot.agent.RuntimeHintsAgentCan-Redefine-Classes: true를 매니페스트에 박는다. 그래서 이 JAR 자체를 -javaagent로 붙일 수 있다.

정리

spring-core-test는 "AOT가 만든 것을 검증한다"는 한 가지 목표를, **생성 코드를 직접 컴파일해보는 축(TestCompiler)**과 **런타임 힌트 누락을 추적하는 축(RuntimeHintsAgent)**으로 나눠 푼다. 나머지 패키지는 이 두 축에 입력을 공급하는 어댑터와 목이다. 다음 장부터 각 축을 코드 레벨로 파고든다.