This release is a major architectural milestone featuring native HTTP/2 protocol support for Netty and Undertow, a high-performance Redis Sorted Set-based session expiration index and lock-free striped connection pool for large-scale distributed clustering, enhanced WebSocket multi-message broadcasting and serialized asynchronous messaging, streamlined action execution exception handling and parameter binding, and comprehensive modernization and JSpecify null-safety standardization across the core utilities.
Servlet-less Netty and Undertow web services now natively support multiplexed HTTP/2 communication over Cleartext (h2c) and TLS ALPN (h2). In addition, the Lettuce-based distributed session store has transitioned from an $O(N)$ full SCAN polling model to an $O(\log N + M)$ Redis Sorted Set (ZSET) expiration index structure, dramatically reducing session scavenging overhead. This release also eliminates redundant exception wrapping across the Action execution pipeline, optimizes ETag and conditional HTTP processing, reinforces REST request/response APIs, and substantially expands unit test coverage and runtime resilience across all framework layers.
🚀 New Features
- Native HTTP/2 Protocol Support for Netty and Undertow Services (Cleartext
h2cand TLS ALPNh2)- Added comprehensive HTTP/2 protocol support across
aspectran-with-nettyandaspectran-with-undertowmodules. - Cleartext HTTP/2 (
h2c): Supports both direct connection and HTTP/1.1 Upgrade handshakes for h2c communication, delivering low-latency, multiplexed networking for internal microservices. - Secure TLS ALPN (
h2): Implemented Application-Layer Protocol Negotiation (ALPN) to seamlessly negotiate HTTP/1.1 or HTTP/2 over a single TLS port and process multiplexed streams. - Added
Http2Configfor granular tuning of header table size, maximum concurrent streams, initial window size, maximum frame size, and maximum header list size. - Enhanced startup logging in Netty and Undertow web servers to clearly report HTTP/2 activation status and protocol negotiation details.
- Added comprehensive HTTP/2 protocol support across
- Redis Sorted Set Expiration Index (
aspectran:session:expiry) and Lightweight SessionDataCodec- Replaced the legacy $O(N)$ Redis SCAN-based session expiration polling with an $O(\log N + M)$ Redis Sorted Set (ZSET) index (
aspectran:session:expiry). - Stored expiration timestamps as ZSET scores to achieve lightning-fast lookups (
doGetExpired,getAllSessions) even with millions of distributed sessions. - Lightweight
SessionDataCodecOptimization: Introduced magic byte tags (MAGIC_ID_ONLY,MAGIC_FULL) to encode session IDs for index storage with minimal byte overhead while maintaining full backward compatibility. - Added the
expiryIndexKeyconfiguration option toAbstractLettuceSessionStoreand session store factories for customizable index naming.
- Replaced the legacy $O(N)$ Redis SCAN-based session expiration polling with an $O(\log N + M)$ Redis Sorted Set (ZSET) index (
- Redis Distributed Lock (
SET NX EX) for Session Scavenging and Orphan Cleanup- Integrated Redis distributed locking (
SET NX EX) into expired session scavenging (doGetExpired) and orphan session cleanup (doCleanOrphans) in multi-node clusters. - Prevented redundant deletions and Redis I/O contention by guaranteeing that only a single cluster node performs background cleanup routines at any given time.
- Enhanced
doCleanOrphansto physically delete orphaned session data keys from Redis before clearing index entries.
- Integrated Redis distributed locking (
- Lock-Free Striped Connection Pool for Lettuce Session Stores
- Completely removed Apache Commons Pool2 dependencies and introduced a high-throughput, lock-free
StripedConnectionPooltailored for Lettuce’s asynchronous multiplexing architecture. - Applied dynamic proxies to make connection
close()calls safe no-ops withintry-with-resourcesblocks. - Standardized connection pooling across Standalone, Cluster, and Primary-Replica topologies via a single
poolSizeconfiguration, eliminating lock contention.
- Completely removed Apache Commons Pool2 dependencies and introduced a high-throughput, lock-free
- Enhanced WebSocket Broadcasting and Serialized Asynchronous Messaging in
SimplifiedEndpoint- Added
broadcast(String)andbroadcast(ByteBuffer)toSimplifiedEndpointfor efficient multi-session message broadcasting. - Expanded synchronous (
sendText,sendBinary) and queue-based serialized asynchronous (sendTextAsync,sendBinaryAsync) messaging APIs to eliminate concurrent write collisions and ensure reliable WebSocket delivery.
- Added
- Legacy HTTP
HEADRequest Handling andNoBodyResponseSupport- Established standardized HTTP HEAD request processing across Servlet, Netty, and Undertow services to return accurate response headers and
Content-Lengthwithout generating response bodies. - Introduced
NoBodyResponseto bypass redundant body serialization and optimize header metadata generation.
- Established standardized HTTP HEAD request processing across Servlet, Netty, and Undertow services to return accurate response headers and
🚀 Improvements
- Streamlined Action Exception Pipeline and Transparent Root Cause Propagation
- Removed redundant
ActionExecutionExceptiontry-catch wrapping from individual action implementations (AnnotatedAction,InvokeAction,EchoAction,HeaderAction,IncludeAction,ChooseAction,AdviceAction,AnnotatedAdviceAction). - Centralized exception wrapping within the execution engines (
CoreActivityandAdviceActivity) to simplify execution stack traces and improve performance. - Enhanced
AnnotatedMethodInvokerto reliably supportInstantTransletenvironments, parameter mapping, and bean resolution.
- Removed redundant
- Defensive Response Transformation (
TransformResponse) and View Dispatching in Non-Translet Environments- Added defensive
activity.hasTranslet()guards acrossAponTransformResponse,JsonTransformResponse,TextTransformResponse,XmlTransformResponse,XslTransformResponse, and view dispatchers before invokingactivity.getTranslet(). - Ensured safe character encoding resolution and template rendering in standalone or daemon execution contexts where translet instances may not be present.
- Modernized
TransformResponseFactoryusing Javaswitchexpressions.
- Added defensive
- Optimized HTTP ETag and Conditional Processing (
ETagInterceptor)- Supported wildcard (
*) matching inIf-None-Matchheaders in full compliance with RFC 7232. - Added
isEligibleMethodandisEligibleResponseguards to restrict ETag processing to eligible HTTP methods (GET/HEAD) and successful responses (2xx). - Optimized hex token formatting via
DigestUtils.appendMd5DigestAsHexdirectly onStringBuilderinstances to minimize temporary string allocations.
- Supported wildcard (
- Reinforced REST Request/Response APIs and Advanced Content Negotiation
- Enhanced
RestRequestwith a fluent API for chaining headers, query parameters, and request body payloads. - Added HTTP status code validation helpers and response conversion utilities to
RestResponse. - Extended
WebRequestBodyParserto recognize structured syntax suffixes (e.g.,application/vnd.api+json,application/problem+xml). - Optimized
MediaTypeandMediaTypeUtilswith standard media type constants, parsing caching, and fast-path lookups. - Added support for
Retry-Afterheaders in error responses to guide client retry intervals.
- Enhanced
- Refined Clustered Session Lifecycle and Atomic Destruction Control
- Implemented silent eviction (
checkActiveInStore) to gracefully evict local session entries when a local timer expires while the session remains active in the shared cluster store. - Introduced the
deletedInStoreflag inManagedSessionto guarantee thatonSessionDestroyedis fired only once by the specific node that atomically deletes the session from the store. - Acquired session locks in
AbstractSessionCache.deleteto maximize concurrency safety.
- Implemented silent eviction (
- Modernized Core Utilities and Comprehensive JSpecify Null-Safety Annotations
DurationUtils: Added ISO-8601 duration string (PT1H30M) parsing, day unit (d/day/days) support, and locale-safe formatting viaLocale.ROOT.DataSizeUtils: Supported IEC binary suffixes (KiB, MiB, GiB, TiB), added byte unit constants, 64-bit integer overflow guards, and locale-independent formatting.Assert: ExtendedCharSequencesupport and provided default failure message overloads forstate,isTrue,notNull,hasText,noNullElements, etc.ArrayStack: Added polymorphic generic lookups (peek(Class<T>),pop(Class<T>)), safe lookup helpers (peekOrNull,popOrNull),java.util.Stackcompatibility (empty), and consistent negative index bounds checking.DigestUtils: Added SHA-1/256/512 digest methods and in-placeappend*DigestAsHexformatters.CopyOnWriteMap: Fixed NPE on missing keys, wrapped collection views (keySet,values,entrySet) for immutability, and overrode atomiccompute*methods.FileLocker: ImplementedAutoCloseable(try-with-resources), modernized PID extraction usingProcessHandle.current().pid(), and ensured automatic parent directory creation.ClassUtils/TypeUtils: Prevented unintended static class initialization (initialize: false), supported primitive and array type parsing, and improved unwrapping of nested CGLIB/Javassist proxies.- Standardized nullability annotations (
@NonNull,@Nullable) and improved functionality acrossAutoLock,ShutdownHook,CyclicTimeout,Scheduler,LocaleUtils,FilenameUtils,PathUtils,SystemUtils,ObjectUtils,ExceptionUtils,ConcurrentReferenceHashMap,BeanUtils, andLinkedCaseInsensitiveMap.
- Refactored i18n Locale Resolution and Message Sources
- Reorganized
LocaleResolverhierarchy and strategies, accompanied by comprehensive Javadoc documentation. - Improved consistency and unit testing across
AcceptHeaderLocaleResolver,CookieLocaleResolver, andSessionLocaleResolver.
- Reorganized
🐛 Bug Fixes
- Fixed Map Mutation Risk on Path Parameter Extraction in
WebSocketEndpointTemplate- Refactored
WebSocketEndpointTemplate.match()to lazily instantiate the parameter map only when variable segments are decoded, preventing potential mutation errors on immutableCollections.emptyMap()and eliminating unnecessary allocations on literal or non-matching paths.
- Refactored
- Fixed
NullPointerExceptionon Missing Keys inCopyOnWriteMap- Resolved NPEs occurring when invoking
remove(key, value)orreplace(key, oldValue, newValue)on keys not present in the map.
- Resolved NPEs occurring when invoking
- Fixed NPE on Null Elements and Inconsistent Negative Index Bounds in
ArrayStack- Fixed an NPE when invoking
peek(Class)on stacks containingnullelements and ensuredEmptyStackExceptionis consistently thrown for negative indices.
- Fixed an NPE when invoking
- Fixed Fixed-Size Buffer Overflow in
DigestUtils.encodeHex- Corrected fixed character buffer allocation to accommodate arbitrary byte array lengths during hex encoding.
- Fixed Filter Evaluation Logic in
TransletScanner- Fixed an issue where certain wildcard filter patterns failed to match candidate translet rules during component scanning.
- Fixed Target Matching and Flash Attribute Scoping in
FlashMap- Corrected destination target path evaluation and reinforced null safety during flash attribute lifecycle handling.
- Corrected Header Overwriting Logic in
HeaderAction- Updated response header configuration to explicitly set headers (
setHeader) instead of appending them (addHeader).
- Updated response header configuration to explicitly set headers (
🛠️ Dependency Upgrades
- Networking & Distributed Sessions
- Netty: 4.2.18.Final (Introduced BOM dependency management and added
netty-codec-http2) - Lettuce Core: 7.7.0.RELEASE → 7.8.0.RELEASE (Removed Apache Commons Pool2)
- Netty: 4.2.18.Final (Introduced BOM dependency management and added
- Core Utilities & Expressions
- OGNL: 3.4.12 → 3.4.13
- JLine: 4.4.3 → 4.4.6
- Logging & Database
- SLF4J: 2.0.19 → 2.0.20
- Logback Classic: 1.6.3 → 1.6.4
- H2 Database: 2.5.250 → 2.5.252
- Hibernate ORM: 7.4.7.Final → 7.4.11.Final
- Hibernate Validator: 9.1.3.Final → 9.1.4.Final
- QueryDSL: 7.6 → 7.7
- Build & Plugins
- Maven Install Plugin: 3.1.4 → 3.2.0
- Maven Deploy Plugin: 3.1.4 → 3.2.0
- Maven Bundle Plugin: 6.1.2 → 6.2.0
- Build Helper Maven Plugin: 3.6.1 → 3.6.2
Juho Jeong NEWS
Release