Tag Archives: checkedfuture

Guava: Using CheckedFuture

In this post, I want to discuss another class from Google Guava. Today, it will be CheckedFuture. Let’s first see the JavaDoc of the class:

A CheckedFuture is an extension of Future that includes versions of the get methods that can throw a checked exception and allows listeners to be attached to the future. This makes it easier to create a future that executes logic which can throw an exception.

Implementations of this interface must adapt the exceptions thrown by Future#get(): CancellationException, ExecutionException and InterruptedException into the type specified by the E type parameter.

This interface also extends the ListenableFuture interface to allow listeners to be added. This allows the future to be used as a normal Future or as an asynchronous callback mechanism as needed. This allows multiple callbacks to be registered for a particular task, and the future will guarantee execution of all listeners when the task completes.

From this explanation, we can conclude two things about CheckedFuture:

  1. It extends ListenableFuture which has been discussed in this article.
  2. It aims to simplify exception management of Future.

Let’s look at code. Normally, if Future execution is cancelled because the inner-process throws exception, it will wrap the exception in a ExecutionException. So, our code will looks like something like this.

try {
	task.get();
} catch (ExecutionException e) {
	if (e.getCause()
			instanceof ApplicationException) {
		throw (ApplicationException) e.getCause();
	}
	throw new ApplicationException(e);
} catch (InterruptedException e) {
	throw new ApplicationException(e);
} catch (CancellationException e) {
	throw new ApplicationException(e);
}

A lazy programmer (don’t we all are lazy)? will write that like this:

try {
	task.get();
} catch (Exception e) {
	if (e.getCause()
			instanceof ApplicationException) {
		throw (ApplicationException) e.getCause();
	}
	throw new ApplicationException(e);
}

The same code can be implemented using CheckedFuture like this:

Function<Exception, ApplicationException> mapper =
	new Function<Exception, ApplicationException>() {

	@Override
	public ApplicationException apply(
			Exception from) {
		if (from.getCause() instanceof ApplicationException) {
			throw (ApplicationException) from.getCause();
		}
		throw new ApplicationException(from);
	}
};
CheckedFuture<String, ApplicationException> checkedTask =
	Futures.makeChecked(task, mapper);

checkedTask.checkedGet();

So I guess you’ll say: ‘but the code is longer than the original’. It’s true that in this example the code seems to be longer. In fact, if your case is so simple like this, I’ll suggest you to just use the original version.

This is pretty much same case of using functional-like Java coding style. It’s overkill if the case is so small. The advantage can only be seen once your code grows bigger.

In this CheckedFuture case, one example where using it will give you huge benefit is when you start sending the Future/CheckedFuture around and the get()/checkedGet() is executed in many places. That time, you’ll see that wrapping each call will try catch is annoying and this is where CheckedFuture-based solution will shine.