or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/maven-com-squareup-retrofit2--adapter-guava

A Retrofit CallAdapter for Guava's ListenableFuture

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/com.squareup.retrofit2/adapter-guava@3.0.x

To install, run

npx @tessl/cli install tessl/maven-com-squareup-retrofit2--adapter-guava@3.0.0

index.mddocs/

Retrofit Guava Adapter

A Retrofit CallAdapter for Guava's ListenableFuture that enables seamless integration between Retrofit HTTP client and Guava's asynchronous programming model. This adapter automatically converts Retrofit's Call objects into ListenableFuture instances, allowing service methods to return ListenableFuture instead of Call objects.

Package Information

  • Package Name: adapter-guava
  • Package Coordinates: com.squareup.retrofit2:adapter-guava
  • Package Type: maven
  • Language: Java
  • Installation:
    <dependency>
      <groupId>com.squareup.retrofit2</groupId>
      <artifactId>adapter-guava</artifactId>
      <version>3.0.0</version>
    </dependency>
    Gradle:
    implementation 'com.squareup.retrofit2:adapter-guava:3.0.0'

Core Imports

import retrofit2.adapter.guava.GuavaCallAdapterFactory;
import com.google.common.util.concurrent.ListenableFuture;
import retrofit2.HttpException;  // For error handling

For deprecated HttpException (not recommended):

import retrofit2.adapter.guava.HttpException;  // Deprecated - use retrofit2.HttpException instead

Basic Usage

import retrofit2.Retrofit;
import retrofit2.adapter.guava.GuavaCallAdapterFactory;
import com.google.common.util.concurrent.ListenableFuture;

// Add the adapter to Retrofit
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addCallAdapterFactory(GuavaCallAdapterFactory.create())
    .build();

// Define service interface with ListenableFuture return types
interface ApiService {
    @GET("users/{id}")
    ListenableFuture<User> getUser(@Path("id") String userId);
    
    @GET("users/{id}")
    ListenableFuture<Response<User>> getUserWithResponse(@Path("id") String userId);
}

// Use the service
ApiService service = retrofit.create(ApiService.class);
ListenableFuture<User> userFuture = service.getUser("123");

// Add callbacks using Guava's Futures utility
Futures.addCallback(userFuture, new FutureCallback<User>() {
    @Override
    public void onSuccess(User user) {
        // Handle successful response
    }

    @Override
    public void onFailure(Throwable throwable) {
        // Handle error (retrofit2.HttpException for HTTP errors, IOException for network errors)
    }
}, MoreExecutors.directExecutor());

Architecture

The adapter provides two main response handling modes:

  • Direct Body Mode (ListenableFuture<T>): Returns the deserialized response body for successful HTTP responses (2XX), and sets exceptions for errors
  • Response Wrapped Mode (ListenableFuture<Response<T>>): Returns the complete Response object for all HTTP responses, allowing access to headers and status codes

The adapter automatically handles:

  • HTTP error responses (non-2XX) by setting retrofit2.HttpException
  • Network failures by propagating IOException
  • Future cancellation by cancelling the underlying Retrofit Call through CallCancelListenableFuture

Internal Implementation:

  • Uses BodyCallAdapter for direct body responses (ListenableFuture<T>)
  • Uses ResponseCallAdapter for Response-wrapped responses (ListenableFuture<Response<T>>)
  • Employs CallCancelListenableFuture (extends Guava's AbstractFuture) to handle proper cancellation propagation

Capabilities

GuavaCallAdapterFactory

Factory class for creating Guava ListenableFuture call adapters.

/**
 * A call adapter factory which creates Guava futures.
 * Adding this class to Retrofit allows you to return ListenableFuture from service methods.
 */
public final class GuavaCallAdapterFactory extends CallAdapter.Factory {
    
    /**
     * Creates a new instance of GuavaCallAdapterFactory
     * @return GuavaCallAdapterFactory instance
     */
    public static GuavaCallAdapterFactory create();
    
    /**
     * Returns a call adapter for interface methods that return ListenableFuture
     * @param returnType the return type to adapt
     * @param annotations annotations on the declaring method
     * @param retrofit the current Retrofit instance
     * @return CallAdapter for ListenableFuture types, or null if not applicable
     */
    @Override
    public @Nullable CallAdapter<?, ?> get(
        Type returnType, 
        Annotation[] annotations, 
        Retrofit retrofit
    );
}

Supported Return Types

The adapter supports two configurations for ListenableFuture type parameters:

// Direct body - returns deserialized body for 2XX responses
// Sets retrofit2.HttpException for non-2XX responses, IOException for network errors
ListenableFuture<User> getUser();

// Response wrapped - returns Response object for all HTTP responses
// Sets IOException for network errors only
ListenableFuture<Response<User>> getUserWithResponse();

HttpException (Deprecated)

/**
 * @deprecated Use retrofit2.HttpException instead
 */
@Deprecated
public final class HttpException extends retrofit2.HttpException {
    
    /**
     * Creates HTTP exception from Retrofit Response
     * @param response the HTTP response that caused the exception
     */
    public HttpException(Response<?> response);
}

Error Handling

The adapter provides comprehensive error handling:

  • HTTP Errors (non-2XX responses): For direct body mode (ListenableFuture<T>), the future is set with a retrofit2.HttpException containing the response details
  • Network Errors: IOException is propagated for network-level failures
  • Invalid Return Types: IllegalStateException is thrown for:
    • Non-parameterized ListenableFuture return types: "ListenableFuture return type must be parameterized as ListenableFuture<Foo> or ListenableFuture<? extends Foo>"
    • Non-parameterized Response types in Response-wrapped mode: "Response must be parameterized as Response<Foo> or Response<? extends Foo>"
  • Future Cancellation: Cancelling the returned ListenableFuture automatically cancels the underlying Retrofit Call

Type Safety

The adapter maintains full type safety:

// Parameterized types are required
ListenableFuture<User> validReturn();              // ✓ Valid
ListenableFuture<Response<User>> validReturn();     // ✓ Valid

ListenableFuture invalidReturn();                   // ✗ IllegalStateException
ListenableFuture<Response> invalidReturn();         // ✗ IllegalStateException

Integration with Guava

The adapter creates ListenableFuture instances that are fully compatible with Guava's concurrency utilities:

  • Futures.addCallback(): Add success/failure callbacks
  • Futures.transform(): Transform results asynchronously
  • Futures.allAsList(): Combine multiple futures
  • Future cancellation: Properly cancels underlying HTTP calls
  • Executor integration: Work with any Executor for callback execution

Dependencies

Required dependencies:

  • retrofit2: Core Retrofit library
  • com.google.common.util.concurrent: Guava's ListenableFuture and related utilities
  • javax.annotation.Nullable: For null safety annotations

Module Configuration:

  • Automatic Module Name: retrofit2.adapter.guava
  • Gradle Configuration: API dependencies on both retrofit2 and guava