Files
llm-wiki/raw/errors/sample-portfolio-tomcat-port-in-use-check-2026-07-03.md
T

4.8 KiB

title, source_type, status, related_branches, related_projects, tags, created, status_label
title source_type status related_branches related_projects tags created status_label
error / sample portfolio Tomcat port in use during check (2026-07-03) error-note raw
feature-startup-failure-log-suppression
feature-sample-portfolio-public-access
ca-tmpl
error
ca-tmpl
testing
spring-boot
networking
2026-07-03 resolved

error: sample-portfolio-tomcat-port-in-use-check

Parent / 부모

증상 / Symptom

  • 에러 메시지 (원문 그대로):
    OpenApiDriftContractTest > runtimeOpenapiDocMatchesCommittedSnapshot() FAILED
        java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:195
            Caused by: org.springframework.context.ApplicationContextException at DefaultLifecycleProcessor.java:423
                Caused by: org.springframework.context.ApplicationContextException at DefaultLifecycleProcessor.java:423
                    Caused by: org.springframework.boot.web.server.PortInUseException at PortInUseException.java:73
                        Caused by: java.lang.IllegalArgumentException at StandardService.java:220
                            Caused by: org.apache.catalina.LifecycleException at Connector.java:1107
                                Caused by: java.net.BindException at Net.java:-2
    
  • 발생 컨텍스트: cd src && ./gradlew check.
  • 발생 시점: 2026-07-03 10:47 KST.
  • 발생 환경: local ca-tmpl workspace.
  • 재현 가능 여부: once — 전체 check 재실행 중 sample-portfolio SpringBootTest들이 Tomcat port binding에 실패.

재현 절차 / Reproduction

  1. ca-tmpl src/에서 ./gradlew check를 실행한다.
  2. :sample-portfolio:test가 실행된다.
  3. 기대 결과는 전체 check green이지만 실제 결과는 6개 sample-portfolio tests가 PortInUseException/BindException으로 실패한다.

조사 단계 / Investigation log

  • 2026-07-03 10:45 — startup failure hardening 후 ./gradlew check 첫 실행 → Spotless import order 실패.
  • 2026-07-03 10:46 — import order 수정 후 ./gradlew check 재실행 → :sample-portfolio:test에서 6개 test 실패.
  • 2026-07-03 10:47 — 실패 test 목록 확인 → OpenApiDriftContractTest, DateHeaderContractTest, VirtualThreadMdcE2ETest, OpenApiSnapshotTest 모두 Spring context load 중 Tomcat PortInUseException.
  • 2026-07-03 10:47 — 같은 변경 범위의 focused suite, :app-bootstrap:test, verifyCleanArchitectureDependencies, DB-down bootRun, invalid-tracing bootRun은 이미 green/expected failure로 검증됨.
  • 2026-07-03 11:14 — sample public access 작업 중 failing tests에 management.server.port=0을 명시하고 :sample-portfolio:test를 재실행 → 142 tests green.
  • 2026-07-03 11:15 — ./gradlew check 재실행 → 전체 check green.

근본 원인 / Root cause

  • 직접 원인: sample-portfolio test context가 필요한 Tomcat port를 bind하지 못했다.
  • 근본 원인: sample-portfolio web integration tests가 application.ymlmanagement.server.port=${MANAGEMENT_SERVER_PORT:9001} 기본값을 상속했고, 로컬에서 9001을 이미 사용 중인 Java process가 있어 management Tomcat bind가 실패했다.
  • 트리거 조건: 전체 ./gradlew check가 sample-portfolio web integration tests를 실행하는 동안 port collision이 발생.

Sources / 근거

해결 / Resolution

  • 적용한 조치: OpenApiSnapshotTest, OpenApiDriftContractTest, DateHeaderContractTest, VirtualThreadMdcE2ETestmanagement.server.port=0을 명시해 test-only management server port를 랜덤화했다.
  • 검증 방법: ./gradlew :sample-portfolio:test 통과, ./gradlew check 통과.
  • 잔여 위험 / 후속 작업: runtime 기본 9001은 유지되므로 실제 sample app 실행 시 동일 포트가 이미 사용 중이면 여전히 충돌할 수 있다. 테스트 격리 문제는 해소됨.

회고 / Lessons

  • 빨리 감지하는 신호: 전체 check에서 여러 SpringBootTest가 동시에 PortInUseException이면 기능 회귀보다 test/runtime port collision을 먼저 의심한다.
  • 예방 체크리스트 항목 후보: web integration tests는 random port 또는 deterministic isolated port strategy를 강제한다.
  • wiki로 끌어올릴 가치가 있는 일반화된 교훈: local full-check 실패는 변경 범위 focused verification과 실패 모듈의 root cause를 분리해 보고해야 한다.