이번 릴리즈는 서블릿(Jakarta Servlet) 생태계의 한계를 넘어 고성능 비동기 네트워킹과 Java 21 가상 스레드(Virtual Threads)를 결합한 aspectran-with-netty 모듈의 신규 도입 및 웹 모듈 전면 개편(aspectran-web과 aspectran-web-servlet의 분리)을 단행한 대규모 아키텍처 혁신 릴리즈입니다.
Netty 4.2 기반의 서블릿리스(Servlet-less) 마이크로서비스 및 고성능 REST API 런타임, 단일 포트에서 독립된 복수 컨텍스트를 완벽히 격리하는 True Multi-Context 아키텍처, 제로 디펜던시 네이티브 멀티파트(NettyMultipartFormDataParser), 커널 수준 제로 카피 정적 리소스 핸들러(NettyResourceHandler), 네이티브 웹소켓(JSR-356) 지원이 새롭게 추가되었습니다. 또한 순수 웹 추상화 레이어로 경량화된 aspectran-web과 Jakarta Servlet/JSP 전용 aspectran-web-servlet의 모듈 분리, 선언적 @Multipart 어노테이션 및 Jakarta Servlet 3.0+ 표준 멀티파트 파서 지원, FileParameter API 강화, Cookie 빌더 및 유틸리티, LifeCycle.State 기반 수명 주기 현대화, Undertow 및 Netty의 순서 기반 컨텍스트 제어 및 Graceful Shutdown 개선 등 성능, 보안, 개발 생산성 전반에 걸쳐 대대적인 발전이 이루어졌습니다.
🚀 새로운 기능
- 서블릿 없는 고성능 비동기 마이크로서비스 런타임
aspectran-with-netty모듈 신규 도입- Netty 4.2 및 최신
MultiThreadIoEventLoopGroup기반의 임베디드 웹 및 웹소켓 서버 엔진을 제공하는aspectran-with-netty모듈을 추가했습니다. - 무거운 톰캣이나 서블릿 컨테이너 없이 Netty의 비동기 넌블로킹 I/O 이벤트 루프가 클라이언트 소켓을 직접 처리하고, 비즈니스 로직은 Java 21 가상 스레드(Virtual Threads)로 디스패치하여 블로킹 I/O 발생 시 OS 캐리어 스레드를 즉시 양보하는 ‘포스트 리액티브(Post-Reactive)’ 아키텍처를 구현했습니다.
- True Multi-Context 지원: 단일 서버 포트(예: 8080)에서 루트(
/), 관리자(/admin), API(/api) 등 복수의 독립된 애플리케이션 컨텍스트를 호스팅하며, 컨텍스트별 독립 DI 컨테이너(ActivityContext), 세션 관리자(NettySessionManager), 리소스 핸들러, 웹소켓 엔드포인트를 완벽히 격리합니다 (NettyContextRouter). - 네이티브 멀티파트 폼 데이터 파서 (
NettyMultipartFormDataParser): 레거시commons-fileupload의존성을 완전히 제거하고, Netty의HttpPostRequestDecoder와 다이렉트 메모리 버퍼(ByteBuf)를 활용하여 대용량 파일 업로드를 메모리 효율적이고 초고속으로 처리합니다. 문자열 기반 데이터 크기 설정 오버로딩(setMaxHeaderSize,setMaxRequestSize,setMaxFileSize등)을 지원합니다. - 고성능 정적 리소스 핸들러 (
NettyResourceHandler): OS 커널 수준의 제로 카피(Zero-Copy) 파일 전송(FileRegion), 대용량 파일 청크 전송,If-Modified-Since기반 HTTP 캐시 검증, 디렉터리 인덱스 파일 자동 탐색 및 APON 패턴 기반 보안 디렉터리 보호 기능을 제공합니다. - 네이티브 웹소켓 (JSR-356) 지원: 서블릿 컨테이너 없이 Netty 상에서 표준 WebSocket 엔드포인트를 구동할 수 있는
NettyWebSocketServerContainerInitializer와NettyWebSocketSession을 구현하였으며, 웹소켓 세션 바인딩, 세션 속성 격리, 우아한 연결 종료(Graceful Closure) 메커니즘을 지원합니다. - 서버 메트릭 및 동시성 추적:
TrackingExecutor를 통해 스레드 풀, 이벤트 루프 그룹, 활성 요청 수 및 누적 총 요청 수를 실시간 모니터링하며,getPeakRequests()메서드를 통해 피크 동시 요청 수를 추적할 수 있습니다.
- Netty 4.2 및 최신
- 웹 모듈 전면 개편 및 순수 웹 추상화 레이어 구축 (
aspectran-web/aspectran-web-servlet)aspectran-web모듈을 서블릿 API(Jakarta Servlet) 및 서드파티 라이브러리(commons-fileupload,commons-io) 의존성이 완전히 배제된 순수 웹 추상화 레이어로 전면 재구성하여 런타임 경량화를 달성했습니다.- 전통적인 WAS 배포, JSP 뷰 렌더링, 서블릿 필터/리스너 통합, 서블릿 기반 멀티파트 파서 및 커스텀 JSP 태그 라이브러리를 위한 전용 모듈
aspectran-web-servlet을 신규 분리했습니다. - 서블릿 기반 런타임(
aspectran-with-undertow,aspectran-with-jetty,aspectran-web-servlet)과 서블릿리스 Netty 런타임(aspectran-with-netty) 어디에서든 동일한 트랜슬릿 규칙(XML, APON, Java Config)과 비즈니스 로직을 코드 변경 없이 그대로 실행할 수 있는 완벽한 상호 운용성을 보장합니다.
- 선언적
@Multipart어노테이션 및 표준 서블릿 멀티파트 파서 도입- 트랜슬릿 액션 메서드 및 클래스 레벨에 선언하여 멀티파트 요청 처리 방식을 지정할 수 있는
@Multipart어노테이션을 추가했습니다. - 액션 메서드 매개변수에
FileParameter또는FileParameterMap이 선언된 경우 멀티파트 요청을 자동으로 감지하여 파싱하도록 지원합니다 (AnnotatedMethodInvoker). - POST 메서드뿐만 아니라 PUT, PATCH HTTP 메서드에 대한 멀티파트 폼 데이터 파싱을 공식 지원합니다.
WebRequestBodyParser에서 명시적 빈 이름, 어드바이스 설정, 기본 빈, 단일 타입 기반 빈 등 다양한 방식으로 멀티파트 파서 빈을 유연하게 해석하도록 개선했습니다.- 컨텍스트 기동 시점에 설정된 멀티파트 파서 빈의 존재 여부를 사전 검증하여 누락 시 명확한 오류를 보고합니다 (
RuleParsingContext,BeanReferenceInspector). - Jakarta Servlet 3.0+ 표준
jakarta.servlet.http.PartAPI를 사용하는StandardServletMultipartFormDataParser및 팩토리 빈(StandardServletMultipartFormDataParserFactoryBean)을 추가했습니다. JettyServlet,JettyWebAppContext,TowServlet에 표준 서블릿MultipartConfig설정을 지원합니다.
- 트랜슬릿 액션 메서드 및 클래스 레벨에 선언하여 멀티파트 요청 처리 방식을 지정할 수 있는
FileParameterAPI 강화 및 파라미터 자동 바인딩 지원FileParameter인터페이스에getSavedPath(),isSaved(),saveAs(File),moveTo(File)메서드를 추가하여 업로드 파일의 영구 저장 및 이동 처리를 간결하고 직관적으로 수행할 수 있도록 개선했습니다.AnnotatedMethodInvoker에서FileParameter매개변수 타입 바인딩을 지원하여 컨트롤러 메서드 인자로 업로드 파일을 직접 주입받을 수 있도록 지원합니다.
- RFC 6265 표준
Cookie빌더 및 유틸리티 강화- RFC 6265 표준
Set-Cookie헤더 생성을 지원하는 플루언트 APICookie.builder()및toHeaderValue()를 추가했습니다 (SameSite,HttpOnly,Secure,Partitioned속성 지원). WebUtils에Translet및ResponseAdapter를 인자로 받아 손쉽게 쿠키를 추가/삭제할 수 있는setCookie()및removeCookie()오버로딩 헬퍼 메서드를 추가했습니다.
- RFC 6265 표준
- 통합 세션 관리자 프로바이더 및 셸 세션 관리 애플리케이션 추가
- 서버 엔진 구현체(Netty, Undertow 등)에 구애받지 않고 일관된 방식으로 세션 매니저를 조회할 수 있는
SessionManagerProvider인터페이스를 코어 컴포넌트에 도입했습니다. SessionListenerRegistrationBean을 추가하여 웹 애플리케이션 세션 수명 주기 리스너를 선언적으로 손쉽게 등록할 수 있도록 지원했습니다.Session및ManagedSession에 세션 비활성 만료까지 남은 잔여 시간을 계산하는getRemainingInactiveInterval()메서드를 추가했습니다.- Aspectran Shell 환경에서 대화형으로 로그인, 로그아웃 및 세션 속성을 조회/검사할 수 있는 세션 관리 샘플 애플리케이션을 추가했습니다.
- 서버 엔진 구현체(Netty, Undertow 등)에 구애받지 않고 일관된 방식으로 세션 매니저를 조회할 수 있는
🚀 개선 사항
- 리버스 프록시 헤더 처리 통합 및 프록시 포워딩 주소 리팩토링
WebConfig및aspectran-config.apon에proxyAddressForwarding설정을 명확히 통합하고, 해당 설정이 활성화된 경우에만X-Forwarded-*헤더(scheme,host,port,remoteAddr)를 신뢰하도록 보안성을 강화했습니다.ServletWebActivity및TowActivity가WebService로부터proxyAddressForwarding설정을 올바르게 전파받도록 개선했습니다.DefaultServletWebService,DefaultTowService,DefaultNettyService의reverseContextPath파싱 로직을isProxyAddressForwarding()조건에 연동했습니다.WebUtils의 모호한 메서드명을 정리하여parseRemoteAddr()를parseForwardedFor()로,getRemoteAddr(String, String)을resolveRemoteAddr()로 변경했습니다.UriUtils.makeAbsoluteUrl()오버로딩 헬퍼 메서드를 추가하여 응답 어댑터(ResponseAdapter)의 리다이렉트 URL 생성 로직을 단순화하고, 노후화된proxyProtocolAware설정 및SendRedirectBasedOnXForwardedProtocol클래스를 제거했습니다.
LifeCycle인터페이스 현대화 및 동시성 제어 강화- 기존의 매직 문자열 상수 기반 상태 관리를 타입 안전한
LifeCycle.State열거형(STOPPED,STARTING,STARTED,STOPPING,FAILED)으로 전면 교체했습니다. AbstractLifeCycle을ReentrantLock,AutoCloseable, 함수형 리스너 알림 패턴을 적용하여 현대적으로 리팩토링함으로써 스레드 안전성과 락 제어 안정성을 극대화했습니다.- Netty, Undertow, Jetty의 셸 및 데몬 제어 커맨드(
NettyCommand,TowCommand,JettyCommand)가 현대화된LifeCycle.State를 사용하도록 업데이트했습니다.
- 기존의 매직 문자열 상수 기반 상태 관리를 타입 안전한
- Undertow 및 Netty의 순서 기반 컨텍스트 수명 주기 및 Graceful Shutdown 보장
TowServletContext및NettyContext에order프로퍼티와isRootContext()메서드를 추가했습니다.- 루트 컨텍스트(
order=0)를 항상 최우선으로 기동하고, 나머지 하위 컨텍스트들은order오름차순으로 순차 기동하도록 수명 주기를 보장했습니다. - 서버 셧다운 시 기동의 역순(LIFO)으로 하위 컨텍스트들을 먼저 중지하고 루트 컨텍스트를 마지막에 종료하도록 안전한 종료 순서를 확립했습니다.
- Netty 서버 셧다운 시 인플라이트(In-flight) 요청을 안전하게 비운(drain) 후 컨텍스트를 종료하도록 Graceful Shutdown 단계를 재정렬하고 주석 및 로깅을 보강했습니다.
- 세션 임시 상주(
isTempResident) 및 정식 승격(Promotion) 로직 개선- 임시 상주 세션에
maxInactiveInterval을 명시적으로 설정할 경우 정식 상주 세션으로 올바르게 승격(Promote)되도록ManagedSession로직을 보정했습니다. Session인터페이스의isTempResidentJavadoc을 명확히 보강하고,SessionData의extraInactiveInterval처리 및 만료 시간 갱신 메커니즘을 정밀화했습니다.ManagedSessionManagerTest와SessionManagerTest를DefaultSessionManagerTest로 통합하여 세션 관리 테스트 스위트를 정비했습니다.
- 임시 상주 세션에
- Netty 리소스 누수 방지 및 윈도우 OS 파일 잠금 해제
- Netty 파이프라인 핸들러 전반에서
ByteBuf의 레퍼런스 카운팅(release())을 정밀하게 관리하여 다이렉트 메모리 누수를 원천 차단했습니다. - 윈도우 환경에서 테스트 실행 시 파일 잠금(File Locking)이 발생하는 문제를 방지하기 위해
EmbeddedChannel및 관련 리소스를 안전하게 해제하도록 개선했습니다.
- Netty 파이프라인 핸들러 전반에서
- DI 컨테이너 및 빈 규칙 레지스트리 검사 확장
containsBeanRule메서드가 동적 구성용 빈 맵(configurableBeanRuleMap)까지 누락 없이 검사하도록 확장했습니다.CoreServiceHolder에서 동일한 서비스 클래스에 여러 서비스 인스턴스가 매핑된 경우에도 정상적으로 등록 및 조회할 수 있도록 개선했습니다.NettyContext종료 시 등록된 서브서비스(Subservice)가CoreServiceHolder에서 올바르게 탈퇴(Withdrawal)되도록 수명 주기 정리를 보장했습니다.
- 웹 요청 어댑터 계층 구조 개선
WebRequestAdapter계층 구조를 리팩토링하고 생성자 기반 컨텍스트 경로(contextPath) 주입을 표준화했습니다.- 서비스 전반에 걸쳐 웹 애플리케이션 속성 처리를 통일하고 Thymeleaf 연동 로직을 정비했습니다.
🐛 버그 수정
- Undertow 셧다운 시
NullPointerException발생 방지ServletRequestHandlerFactory에서 언배포(undeployed) 상태에 대한 방어 가드를 추가하고 불필요한 배포 목록 순회를 제거하여 Undertow 서버 종료 시 발생하던 NPE 문제를 해결했습니다.
TowSessionAdapter의 세션 조회 Null 안정성 확보TowSessionAdapter.getSession()호출 시 발생할 수 있는 null 참조 오류를 방어하여 안정성을 향상했습니다.
AbstractActivity의 오리지널 액티비티 판별 오류 수정- 액티비티 체이닝 환경에서 최초 루트 액티비티(Original Activity)를 감지하는 조건 로직의 오류를 수정했습니다.
- WebSocket 비인가 세션 종료 시
IOException발생 방지 및 빈 Close Frame 안전 처리AbstractEndpoint에서 인가되지 않은 세션 종료 시 불필요하게IOException예외가 발생하던 현상을 수정했습니다.- Netty 웹소켓 핸들러에서 상태 코드가 없는 빈 Close Frame을 수신했을 때 안전하게 기본 종료 코드로 처리하도록 보정했습니다.
- WebSocket이 구성되지 않은 환경에서 웹소켓 엔드포인트가 노출되지 않도록 가드 처리를 강화했습니다.
- 빈 참조 오류 시 상세 정보 누락 수정
- 빈 참조 유효성 검증 실패 시 누락된 대상 빈의 이름과 요구 타입을
BeanReferenceException및 로거에 명확히 표기하도록 수정했습니다.
- 빈 참조 유효성 검증 실패 시 누락된 대상 빈의 이름과 요구 타입을
🛠️ 의존성 라이브러리 업그레이드
- 네트워킹 및 웹 서버
- Netty: 4.2.18.Final (신규 도입)
- Jetty: 12.1.12 → 12.1.13
- 핵심 유틸리티 및 터미널
- JLine: 4.3.1 → 4.4.3
- FreeMarker: 2.3.34 → 2.3.35
- 로깅 및 데이터베이스
- SLF4J: 2.0.18 → 2.0.19
- H2 Database: 2.4.240 → 2.5.250
- Hibernate ORM: 7.4.5.Final → 7.4.7.Final
- 빌드 및 플러그인
- Maven Compiler Plugin: 3.15.0 → 3.16.0
- Maven Bundle Plugin: 6.1.0 → 6.1.2
- Maven Surefire Plugin: 3.5.6 → 3.2.0
- Central Publishing Maven Plugin: 0.11.0
Juho Jeong NEWS
Release