You're seeing the release note of an old version. Check out the latest release note.
v1.19.0
September 13, 2022
🌟 New features
-
You can now repeatedly aggregate an
HttpRequestandHttpResponsewhen usingHttpRequest.aggregate()andHttpResponse.aggregate(). If anHttpRequestor anHttpResponseis aggregated before, the cachedAggregatedHttpRequestorAggregatedHttpResponseis returned for subsequent calls. #3789 #4366HttpRequest request = ...;
AggregatedHttpRequest aggregatedReq0 = request.aggregate().join();
AggregatedHttpRequest aggregatedReq1 = request.aggregate().join();
assert aggregatedReq0 == aggregatedReq1;
HttpResponse response = ...;
AggregatedHttpResponse aggregatedRes0 = response.aggregate().join();
AggregatedHttpResponse aggregatedRes1 = response.aggregate().join();
assert aggregatedRes0 == aggregatedRes1; -
You can now customize the behavior of auto-refresh for an
AddressResolverGroupwithDnsResolverGroupBuilder. #4400// Disable auto refresh
ClientFactory
.builder()
.domainNameResolverCustomizer(customizer -> {
customizer.enableAutoRefresh(false); // 👈👈👈
})
.build();
// Set a constant refresh timeout
ClientFactory
.builder()
.domainNameResolverCustomizer(customizer -> {
customizer.autoRefreshTimeout(Duration.ofDays(1)); // 👈👈👈
})
.build();
// Build a flexible refresh timeout depending on the hostname
ClientFactory
.builder()
.domainNameResolverCustomizer(customizer -> {
customizer.autoRefreshTimeout(hostname -> { // 👈👈👈
if (hostname.endsWith("busy.domain.com")) {
// Automatically refresh the cached domain for 7 days.
return Duration.ofDays(7).toMillis();
}
if (hostname.endsWith("sporadic.domain.dom")) {
// Don't need to refresh a sporadically used domain.
return 0;
}
...
});
})
.build(); -
You can now export
RequestOnlyLog.requestCause()andRequestLog.responseCause()to MDC by specifyingreq.causeandres.causeto an appender of a Logback configuration.<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="RCEA" class="com.linecorp.armeria.common.logback.RequestContextExportingAppender">
...
<export>req.cause</export> <!-- 👈👈👈 -->
<export>res.cause</export> <!-- 👈👈👈 -->
...
</appender>
</configuration> -
You can now trace a
RequestContextleak by specifying-Dcom.linecorp.armeria.requestContextLeakDetectionSampler=<sampler-spec>or implementing a customFlagsProvider. #4100 #4232public final class LeakDetectingFlagsProvider implements FlagsProvider {
@Override
public Sampler<? super RequestContext> requestContextLeakDetectionSampler() {
// Samples all request contexts.
return Sampler.always();
}
} -
DocServicenow automatically generates a specification of annotated services for well known types. #4309 #4322- Java POJO
- Kotlin data class
- Scala case class
- Protocol Buffers'
Message - ScalaPB's
GeneratedMessage
-
You can now upload files to your
GraphQlServiceusing GraphQL multipart requests. #3971 #4199 -
You can now use
armeria-version-catalogmodule to easily import Armeria and Armeria's direct dependencies using Gradle's version catalog. #4377// in settings.gradle
dependencyResolutionManagement {
versionCatalogs {
create("armeriaDeps") {
from("com.linecorp.armeria:armeria-version-catalog:1.19.0")
}
}
}
📈 Improvements
CompositeExceptionnow shows full stack traces of all nested exceptions when-Dcom.linecorp.armeria.verboseExceptions=trueis set. #4347 #4356
🛠️ Bug fixes
-
You can now use Armeria Spring actuator with WebFlux correctly. #4396 #4408
-
You no longer see
ClassCastExceptionwhen an invalid path request is received. #4405 -
Annotated services now correctly return
204 No Contentstatus whenvoid,Publisher<Void>orCompletionStage<Void>and@ProducesJsonare used at the same time. #4390 #4398// 200 OK status and "null" string body is returned
@Get("/null-content")
@ProducesJson
public Publisher<Void> nullBody() {
return Mono.empty();
}
// 204 No Content status and no body is returned
@Get("/no-content")
@StatusCode(204)
@ProducesJson
public Publisher<Void> noBody() {
return Mono.empty();
} -
Armeria server no longer sends chunked encoding header with
304 Not Modifiedstatus. #4386 -
HTTP/2 graceful shutdown timeout is correctly set using
ClientFactory.idleTimeoutMillis(). #4381 -
Unframed
GrpcServicesnow supportapplication/x-protobufandapplication/x-google-protobufmedia types. #4355 #4364 -
You can now use a custom
JsonFormat.PrinterforProtobufResponseConverterFunction. #4301 #4336
📃 Documentation
- You can now learn how to write a gRPC service and client with Armeria by walking through
the gRPC tutorial. #3987
- Special thanks to @freevie who volunteered for this.
🏚️ Deprecations
DnsResolverGroupBuilder.refreshBackoff()has been deprecated in favor ofDnsResolverGroupBuilder.autoRefreshBackoff(). #4400
☢️ Breaking changes
- The method signature of
ResponseConverterFunctionProvider.createResponseConverterFunction()has been changed.ResponseConverterFunctionProviderno longer takes aResponseConverterFunctionas the second parameter. UseDelegatingResponseConverterFunctionProviderto create a newResponseConverterFunctionbased on the delegatingResponseConverterFunction.
⛓ Dependencies
- Brave 5.13.10 → 5.13.11
- Brotli4J 1.7.1 → 1.8.0
- Dropwizard Metrics 4.2.10 → 4.2.12
- gRPC-Java 1.48.0 → 1.49.0
- Jackson 2.13.3 → 2.13.4
- Micrometer 1.9.2 → 1.9.3
- Reactor 3.4.21 → 3.4.22
- Sangria 3.0.1 → 3.2.0
- Scala 3.1.3 → 3.2.0
- Spring Boot 2.7.2 → 2.7.3
🙇 Thank you
This release was possible thanks to the following contributors who shared their brilliant ideas and awesome pull requests:

















