Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Resilience4j 2.0.0 Delivers Support for JDK 17

Resilience4j 2.0.0 Delivers Support for JDK 17

Resilience4j, a lightweight fault tolerance library designed for functional programming, has released version 2.0 featuring support for Java 17 and dependency upgrades to Kotlin, Spring Boot and Micronaut. This new version also removes the dependency on Vavr in order to become a more lightweight library.

Robert Winkler, solution architect at Deutsche Telekom AG and creator of Resilience4j explained the removal of Vavr on Twitter, writing:

I still love Vavr, but users of Resilience4j requested to have an even more lightweight library.

Vavr, a functional library for Java, provides immutable collections and supporting functions and control structures. The latest version, 0.10.4, was released July 2021. The library, formerly called Javaslang, was first released in 2013 before rebranding to Vavr in 2017.

Resilience4j 2.0.0 succeeds version 1.7.1, released in June 2021, and is the first major release since version 1.0.0 in September 2019.

The library now requires Java 17, the latest available LTS version, which allows users to run on Java 17 and use features such as Sealed Classes. There were also dependency upgrades to Kotlin 1.7.20, Spring Boot 2.7 and Micronaut 3.7.3.

Resilience4j offers several features such as the CircuitBreaker which prevents calls to a service whenever the service isn't responding properly on time. This prevents the service from overloading. Consider the following example in which CircuitBreaker may be implemented for a retrieveStudents() method on a SchoolService class:

Supplier<String> decoratedSupplier = CircuitBreaker
    .decorateSupplier(circuitBreaker, schoolService::retrieveStudents);

String result = Try.ofSupplier(decoratedSupplier)
    .recover(throwable -> "Recovered from throwable").get();

Alternatively, the CircuitBreaker may be implemented without a decorator:

String result = circuitBreaker

TimeLimiter allows limiting the amount of time spent calling a service by specifying a timeout. For example, by using a CompletableFuture to create a non-blocking solution:

TimeLimiter timeLimiter = TimeLimiter.of(Duration.ofSeconds(1));

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);

timeLimiter.executeCompletionStage(scheduler, () -> CompletableFuture.supplyAsync(schoolService::retrieveStudents))

While TimeLimiter restricts the call duration from the client, RateLimiter restricts the number of calls per second from client(s). By default, the requests are limited to 50 calls per 500 ns:

CheckedRunnable restrictedCall = RateLimiter
  .decorateCheckedRunnable(rateLimiter, schoolService::retrieveStudents);
    .onFailure((RequestNotPermitted throwable) ->"Please 

RateLimiter also limits the total number of calls in a certain period and ThreadPoolBulkhead limits the number of concurrent calls:

ThreadPoolBulkheadConfig config = ThreadPoolBulkheadConfig.custom()

ThreadPoolBulkhead bulkhead = ThreadPoolBulkhead.of("name", config);


Retry is another feature which, by default, retries the call three times with 500ms between calls:

CheckedFunction0<Student> retryableSupplier = Retry
    .decorateCheckedSupplier(retry, schoolService::retrieveStudents);

Try<String> result = Try.of(retryableSupplier)
    .recover((throwable) -> "Recovered from throwable");

Spring Boot makes it even easier to use Resilience4j by providing annotations such as @CircuitBreaker, @RateLimiter, @Bulkhead, @Retry and @TimeLimiter. The Getting Started Guide for Spring Boot 2 describes the options in more detail.

More information about Resilience4j may be found in the User Guide.

About the Author

Rate this Article