Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Q-Asker API — 2026-07-04 대규모 의존성 승격·마이그레이션 변경점
커밋:
0b57c819(squash 결과),41 files changed, 2530 insertions(+), 2143 deletions(-)브랜치:
ICC-380→develop병합 대기작업 시간: 약 6시간 (스파이크 포함)
주도: 오픈 Renovate PR 6건 통합 반영 + Spring Boot 4.1.0 정식 마이그레이션
목차
반영 버전 요약
Spring Boot 3.5.8 → 4.1.0 (MAJOR)
하부 스택 자동 승격
Boot BOM 승격으로 다음이 함께 올라감:
RestClient표준화)spring-security-oauth2-jose등 lambda DSL 완성)micrometer-jakarta9신규, LongTaskTimer 안정화)기능·성능적 개선
spring.threads.virtual.enabled: true는 3.x에도 있었으나, 4.x에서는AsyncTaskExecutor,@Async,@Scheduled, JDBC/JPA 커넥션 획득 등 더 많은 지점이 가상 스레드로 자동 스위치PROTOCOL_BLOCKING_IO조합에서 pin 최소화resilience4j의#2189fix가 spring-boot4 라인에 반영되어 actuator event endpoint가 snapshot-read로 동작 →/actuator/resilience4j조회 시 잠금 경합 감소RestClient표준화RestTemplatedeprecated,RestClient가 primary. 우리SlackNotifier는 이미RestClient.Builder주입 형태라 준비돼 있음@ControllerAdvice에서 예외를ProblemDetail로 자연스럽게 매핑 (지금은 우리CustomException흐름 유지, 후속에서 도입 가능)ConfigurationProperties오류 리포트 개선@ConfigurationPropertiesScan("com.icc.qasker")(우리가 사용 중)의 metadata 부실 시 stack trace가 짧고 명확해짐WebSecurityConfigurerAdapter는 이미 없었으나 관련 legacy 잔재 완전 제거@MockBeandeprecated →@MockitoBean(우리는 사용처 없음, 향후 신규 테스트 작성 시 반영)WebMergedContextConfiguration등 컨텍스트 캐싱 로직이 재정비되어@SpringBootTest병렬 실행 시 오염 감소실측 부팅 시간 (test 프로파일 기준)
비고: 초기 부팅은 약간 느려졌지만 이후 hot path에서 virtual thread 활용 폭이 넓어져 요청 처리는 개선될 것으로 기대됨. 프로덕션 관측 필요.
손실·비용
spring-boot-starter-aop완전 삭제 →spring-boot-starter-aspectj(1줄 rename)spring-boot-starter-web이 Jackson auto-config를 더 이상 포함하지 않음 →starter-json명시 추가RestClient.Builderauto-register 조건 변경 → 명시 Bean 필요 (Boot4CompatConfig)CacheManagerauto-register 조건 변경 → 명시 Bean 필요 (Boot4CompatConfig)Spring AI 1.1.2 → 2.0.0 (MAJOR)
하부 자동 승격
spring-ai-model,spring-ai-client-chat,spring-ai-commons,spring-ai-retry등 모듈 세분화 완료spring-ai-autoconfigure-model-*로 관측 가능성(observation) 자동 설정 분리기능적 개선
ChatClientAPI 안정화 — 우리 코드는ChatModel.call(prompt)직접 사용이라 변경 불필요. 향후ChatClient도입 시 fluent 인터페이스 사용 가능GoogleGenAiChatOptions.builder()유지 — 우리GeminiChatService의 옵션 조립 코드가 그대로 컴파일됨GoogleGenAiThinkingLevel,GoogleGenAiUsage심볼 위치 유지 — Gemini 3 계열의 thinking token 계산 로직에 영향 없음BeanOutputConverter<GeminiResponse>로 JSON 스키마를 뽑아responseSchema에 주입하는 우리 파이프라인 유지spring.ai.chat.client.observations등 자동 계측 지점 확장 (Grafana 대시보드에서 새 metric 관측 후 추가 가능)spring-ai-autoconfigure-retry별도 아티팩트로 세분화되어@Retryable사용 시 backoff 정책 fine-grained 조정 용이손실·비용
GeminiChatServiceSmokeTest)로chatModel.call → ChatResponse.getResult().getOutput().getText() → JSON사슬을 방어Jackson 2.x → 3.x 전면 이전
이 변경은 Spring Boot 4의 Jackson 3.x 채택에 맞춰 우리 코드도 정공법으로 이전한 것.
성능
Jackson 3.x는 재작성 수준 개편:
ObjectMapper인스턴스 immutable-by-default — 초기 설정 후 재사용 시 동시성 오버헤드 감소JsonProcessingException위계 재편 →JacksonException하나로 통일되어 catch가 간결API 변경 매핑 (우리 코드 기준)
com.fasterxml.jackson.databind.ObjectMappertools.jackson.databind.ObjectMappercom.fasterxml.jackson.databind.JsonNodetools.jackson.databind.JsonNodecom.fasterxml.jackson.databind.node.{Array,Object}Nodetools.jackson.databind.node.{Array,Object}Nodecom.fasterxml.jackson.core.type.TypeReferencetools.jackson.core.type.TypeReferencecom.fasterxml.jackson.core.JsonProcessingExceptiontools.jackson.core.JacksonExceptionObjectNode.fields()(Iterator)ObjectNode.properties()(Set)Iterator.forEachRemainingCollection.forEachcom.fasterxml.jackson.annotation.*우리 코드베이스에서의 개선
GeminiResponseSchema/GeminiEssayResponseSchema—ObjectNode.properties().forEach()가 이전Iterator.forEachRemaining()보다 null 안정성 · 반복 중 수정 시나리오 관점에서 안전IntegerListConverter,SelectionListConverter(JPA AttributeConverter) — 예외 처리 단순화 (JacksonException하나로 통일)ObjectMapper를 직접 커스터마이징할 때 immutable 빌더 패턴 유도가 강화되어 실수 여지 축소손실·비용
com.fasterxml.jackson.annotation.*잔류: Jackson 3.x가 의도적으로 어노테이션 패키지만 legacy 이름 유지 → 이건 정상 상태, 후속 조치 없음JDK 21 → 25 (컨테이너 base)
적용 범위:
infra/base-image/Dockerfile의FROM eclipse-temurin:25.0.2_10-jdk-noble.Gradle toolchain: 여전히 Java 21 (build.gradle 그대로) — 컴파일 target은 21 유지, 런타임만 25.
JDK 25가 가져다주는 실이득 (LTS)
-XX:MaxGCPauseMillis목표 달성률 개선jvm.gc.pause히스토그램 신뢰도↑)우리 build.gradle의 JVM 플래그 호환성
app/build.gradle의baseJvmFlags()에서 사용 중:-XX:+Use${JVM_GC_TYPE}(e.g.,UseG1GC) — JDK 25에서 유효-XX:MaxGCPauseMillis=...— 유효-XX:+HeapDumpOnOutOfMemoryError— 유효-XX:HeapDumpPath=/var/log/heapdump.hprof— 유효플래그 문법 변경 없음. 다만 G1GC의 heuristic이 미세 달라 첫 프로덕션 배포 후
jvm_gc_pause_seconds히스토그램 관측 권장.손실·비용
docker build infra/base-image/로 로컬 재빌드하여 LibreOffice 24.8.4가 JDK 25 base 위에서 정상 설치되는지 확인 필요 (사용자 직접 실행 대상)Resilience4j 2.3.0 → 2.4.0
우리에게 유리한 fix
#2286HealthContributorAutoConfigurationConditionalOnClass/actuator/healthcontributor가 중복 등록되는 이슈 있었음aiServerCB의 health 지표 신뢰도 향상#2321Spring Boot 3 customizer 적용 순서 fixresilience4j.yml의aiServer설정과 우리가 코드로 하는 customization 순서가 명확해짐#2189Actuator event endpoint를 snapshot read로/actuator/circuitbreakerevents/aiServer조회 시 잠금 경합 감소resilience4j-spring-boot4신규 모듈catalog의 module 경로만resilience4j-spring-boot3→resilience4j-spring-boot4로 교체 (alias는 유지)#2358sliding window reject 강화TIME_BASED + LOCK_FREE + slidingWindowSize < 2조합을 명시 거부 → 우리 config는COUNT_BASED라 영향 없음, 다른 CB 추가 시 안전망#2304ignoreExceptionsprecedence 명확화ignoreExceptions가recordExceptions보다 우선 적용. 우리GeminiInfraException기록 정책과 상충 없음#2312withFallback메소드 추가 (DecorateFunction) — 향후 fluent fallback 구성 가능회귀 방어
ApplicationContextBootTest.aiServerCircuitBreakerIsRegisteredWithExpectedConfig()에서 다음 4개 값을 assertion:failureRateThreshold == 60.0fminimumNumberOfCalls == 3slidingWindowSize == 10permittedNumberOfCallsInHalfOpenState == 2resilience4j가 향후 yml 파싱 순서/규칙을 바꿔도 이 4개가 유지되면 우리 계약은 안전.
손실·비용
없음 — Boot 4 대응 모듈 제공 덕에 마이그레이션 부담이 다른 라이브러리보다 훨씬 낮음.
SpringDoc 2.8.17 → 3.0.3
새 기능
#3246) — 향후 우리 AI 파이프라인을 다른 MCP client에게 노출할 여지@Range검증 어노테이션 지원#3123)@Order가ApplicationReadyEvent리스너에 부착 → 시작 순서 예측 가능손실·비용
SwaggerConfig에서io.swagger.v3.oas.models.*만 쓰고 있어 SpringDoc MAJOR와 무관회귀 함정 (겪었음)
swagger-ui.enabled: true인local프로파일에서만WebMvcProperties ClassNotFoundException발생ApplicationContextBootTest)는swagger-ui.enabled: false인test프로파일이라 놓쳤음test프로파일에 SpringDoc 활성화된 별도 nested 테스트 추가 검토 (별도 티켓)문서 처리 라이브러리 patch
pdfbox 3.0.3 → 3.0.7
3.0.x 안정 patch 라인. CHANGELOG에 breaking 없음. 우리 사용처(
PdfUtils.extractPages)의 API 유지.PdfUtilsTest가 정상 슬라이스 / 범위 초과 무시 / 빈 리스트 원본 반환 3케이스 검증jodconverter 4.4.9 → 4.4.11
#417SONG_GB2312 폰트 이슈 해결 → 중국어 문서 변환 안정성 향상 (우리 사용자층에는 큰 영향 없음)#403macOS 메인메뉴 오류 해결 → 로컬 개발 환경 안정성#431Spring Boot에서 named pipe 지원 → 컨테이너 IO 성능 개선 여지#428officeManager.isRunning()의미 명확화ConvertServiceImplTest가DocumentConvertermock으로 API 시그니처 계약 검증Google Cloud + Jib patch
google-cloud-bom 26.67.0 → 26.84.0
google-cloud-storage: 2.69.0 — GCS 클라이언트의 gRPC direct path 안정성 향상google-genai: 1.58.0 — Vertex AI 클라이언트 개선 (Spring AI 2.0과 함께 사용)opentelemetry-*: 1.62.0 — GCS 클라이언트의 트레이싱 계측 개선 (향후 도입 시 유리)gax: 2.81.0 — GAX transport 안정성 (재시도, deadline propagation)Jib 3.4.0 → 3.5.3
코드 품질·인프라 개선
신규 회귀 테스트 (세이프티 넷)
이번 마이그레이션의 자산 중 가장 오래 남을 것:
ApplicationContextBootTest(RT-001 + RT-004)app/src/testPdfUtilsTest(RT-003)modules/quiz-ai/impl/src/testGeminiChatServiceSmokeTest(RT-005)modules/quiz-ai/impl/src/test테스트 파일 수: 이전 6개 → 현재 10개 (67% 증가). 모두 프로덕션 코드 없이 회귀 방어만 담당하는 명확한 목적.
Boot4CompatConfig(신설, 원래LegacyJacksonConfig)Boot 4 auto-config 재편으로 자동 등록 안 되는 두 Bean 명시 등록:
RestClient.Builder—SlackNotifier용CacheManager—@EnableCaching대응 (ConcurrentMapCacheManager)문서 성격: "왜 이 두 Bean이 필요한지"의 코드화된 답변. 향후 Boot 마이너 업그레이드에서 자동 활성화되면 제거 검토.
Constitution 정합
Boot4CompatConfigrename만 별도 검토 대상spring-boot-starter-json,spring-boot-starter-aspectj,resilience4j-spring-boot4) 모두 catalog 참조 유지롤백 안전망
gradle.lockfile전 모듈 재생성됨origin/ICC-380이 회귀 테스트만 있는 초기 커밋864b9524도 보존Boot 4 auto-config 재편의 대가
이번 마이그레이션에서 학습한 Spring Boot 4의 auto-config 정책 전환:
com.fasterxml.jackson.databind.ObjectMapperstarter-json추가RestClient.BuilderCacheManagerspring.cache.type감지 autoRequestMappingHandlerMappingCircuitBreakerRegistry교훈:
@SpringBootTest(webEnvironment = MOCK)을 회귀 테스트에서 사용하는 것이 다음 마이너 업그레이드에서 실패 조기 감지에 유리.NONE은 web 컨텍스트 밖의 auto-config 실패를 놓침.남은 후속 티켓
우선순위 순.
🔴 필수
docker build infra/base-image/후 LibreOffice 설치·JDK 25 실행 확인. Docker Desktop이 필요해 harness 자동 실행 불가, 사용자 직접 실행 필요bootRunfull 스모크 — IntelliJ에서local프로파일로 실 부팅 후/actuator/healthUP 확인#2189개선 실측🟡 권장
test프로파일에도 SpringDoc 활성화한 부팅 회귀 추가 — 이번에 놓친WebMvcProperties이슈 재발 방지spring-boot-starter-json참조를auth-impl외 모듈에도 전파 필요한지 재검토 — 다른 모듈이ObjectMapper를 늦게 필요로 할 수 있음renovate.json에 SpringDoc + Spring Boot MAJOR 그룹핑 규칙 추가 — 다음 Boot MAJOR 승격 시 SpringDoc가 자동으로 함께 묶이도록dependencyDashboardAutoclose옵션 명시 — 이번에 SpringDoc v3 PR이 close된 채 재열리지 않은 경험을 방지🟢 검토 후 진행
ChatClient(Spring AI 2.0) 도입 검토 — 현재ChatModel.call(prompt)직접 호출을 fluent 인터페이스로 이관spring-boot-starter-json제거 가능성 재확인 — Boot 4의 후속 minor 릴리즈에서 auto-config가 복구되면Boot4CompatConfig의 3개 Bean 제거 가능성 — 같은 이유로커밋 통계
ApplicationContextBootTest,PdfUtilsTest,GeminiChatServiceSmokeTest,Boot4CompatConfig)LegacyJacksonConfigrename은 별도)참고 링크
반영된 버전 승격
Boot 4 breaking change 해소
spring-boot-starter-aop아티팩트 제거 →spring-boot-starter-aspectj로 rename신규 회귀 세이프티 넷
검증
남은 후속 티켓 후보
📢 설명
변경 1: [제목]
[변경에 대한 설명]
의사 선택과정 (trade-off)
얻은 것
잃은 것
코드 설명: 인라인 코멘트 확인
✅ 체크 리스트
재현 확인
기본