1.25.0 release notes
22nd August 2023
🌟 New features
GraalVM Support: Armeria now provides GraalVM reachability metadata to easily build GraalVM native images. #5005
Micrometer Observation Support: Support for Micrometer Observation is added. Refer to
ObservationClientorObservationServicefor details on how to integrate with Armeria. #4659 #4980ObservationRegistry observationRegistry = ... WebClient.builder() .decorator(ObservationClient.newDecorator(observationRegistry)) ... Server.builder() .decorator(ObservationService.newDecorator(observationRegistry)) ...WebSocket Client Support: You can now send and receive data over WebSocket using
WebSocketClient. #4972WebSocketClient client = WebSocketClient.of("ws://..."); client.connect("/").thenAccept(webSocketSession -> { WebSocketWriter writer = WebSocket.streaming(); webSocketSessions.setOutbound(writer); outbound.write("Hello!"); Subscriber<WebSocketFrame> subscriber = new Subscriber<WebSocketFrame>() { ... } webSocketSessions.inbound().subscribe(subscriber); });Implement gRPC Richer Error Model More Easily: You can now easily use gRPC Richer Error Model via
GoogleGrpcStatusFunction. #4614 #4986GoogleGrpcStatusFunction statusFunction = (ctx, throwable, metadata) -> { if (throwable instanceof MyException) { return com.google.rpc.Status.newBuilder() .setCode(Code.UNAUTHENTICATED.getNumber()) .addDetails(detail(throwable)) .build(); } ... }; Server.builder().service( GrpcService.builder() .exceptionMapping(statusFunction))Set HTTP Trailers Easily: You can now easily set trailers to be sent after the data stream using
HttpRequest.of()orHttpResponse.of(). #3959 #4727New API for Multipart Headers: You can now retrieve headers from a multipart request in an annotated service using
MultipartFile.headers(). #5106Access RequestLogProperty Values More Easily:
RequestLogAccess.getIfAvailable()has been introduced, which allows users to access aRequestLogPropertyimmediately if available. #4956 #4966Keep an Idle Connection Alive on PING: The
keepAliveOnPingoption has been introduced. Enabling this option will keep an idle connection alive when an HTTP/2 PING frame orOPTIONS * HTTP/1.1is received. The option can be configured byServerBuilder.idleTimeout()orClientFactoryBuilder.idleTimeout(). #4794 #4806Create a StreamMessage from Future: You can now easily create a
StreamMessagefrom aCompletionStageusingStreamMessage.of())>. #4995More Shortcuts for PrometheusExpositionService: You can now create a
PrometheusExpositionServicewithout specifying the defaultCollectorRegistryexplicitly. #5134
📈 Improvements
- The number of event loops is equal to the number of cores by default when 
io_uringis used as the transport type. #5089 - You can now customize error responses when a service for a request is not found
using 
ServiceErrorHandler.renderStatus(). #4996 - Redirection for a trailing slash is done correctly even if a reverse proxy rewrites the path. #4994
 DocServicenow tries to guess the correct route behind a reverse proxy. #4987- The 
RetentionPolicyof@UnstableApiannotation is nowCLASSso that bytecode analysis tools can detect the declaration and usage of unstable APIs. #5131 
🛠️ Bug fixes
GrpcServicenow returns anINTERNALerror code if an error occurs while serializing gRPC metadata. #4625 #4686DnsCachenow allows zero TTL for resolved DNS records. #5119- Armeria's DNS resolver doesn't cache a DNS whose query was timed out. #5117
 - Fixed a bug where headers could be written twice if 
Content-Lengthwas exceeded during HTTP/2 cleartext upgrade. #5113 ServiceRequestContext.localAddress()andServiceRequestContext.remoteAddress()now return correct values when using domain sockets in abstract namespace. #5096armeria-logback12,armeria-logback13, andarmeria-logback14have been introduced for better compatibility with Logback. #5045 #5079 #5078 #5077- You can now use either an inline debug form or a modal debug form when using 
DocService. #5072 - When using Spring integrations, even if 
internal-services.portandmanagement.server.portare set to the same value internal services are bound to the port only once. #4796 #5022 - Exceptions that occurred during a TLS handshake are properly propagated to users. #4950
 AggregatedHttpObject.content()now respects thecharsetattribute in theContent-Typeheader if available. #4931 #4948- Routes with dynamic predicates are not incorrectly cached anymore. #4927 #4934
 
📃 Documentation
- A new page has been added which describes how to integrate Armeria with Spring Boot. #4670 #4957
 - Documentation on how 
Flagswork in Armeria has been added. #4870 - A new example on how to use krotoDC with Armeria has been added. #5092
 
☢️ Breaking changes
- The 
toStringHelper()method inDynamicEndpointGrouphas been replaced withtoString(Consumer)to avoid exposing an internal API in the public API. #5132 
🏚️ Deprecations
HttpResponse.from()and its variants methods are deprecated. #5075- Use 
HttpResponse.of()and its variants instead. 
- Use 
 
⛓ Dependencies
- gRPC-Java 1.56.0 → 1.57.2
 - GraphQL Kotlin 6.5.2 → 6.5.3
 - Guava 32.0.1-jre → 32.1.2-jre
 - Jakarta Websocket 2.1.0 → 2.1.1
 - Kafka client 3.4.0 → 3.4.1
 - Kotlin 1.8.22 → 1.9.0
 - Kotlin Coroutine 1.7.1 → 1.7.3
 - Logback 1.4.7 → 1.4.11
 - Micrometer 1.11.1 → 1.11.3
 - Netty 4.1.94.Final → 4.1.96.Final
 - Protobuf 3.22.3 → 3.24.0
 - Reactor 3.5.7 → 3.5.8
 - Resilience4j 2.0.2 → 2.1.0
 - Resteasy 5.0.5.Final → 5.0.7.Final
 - Sangria 4.0.0 → 4.0.1
 - scala-collection-compat 2.10.0 → 2.11.0
 - Spring 6.0.9 → 6.0.11
 - Spring Boot 2.7.12 → 2.7.14, 3.1.0 → 3.1.1
 - Tomcat 10.1.10 → 10.1.12