Internal optimization utilities for accessing failure causes in Guava's Future implementations without full exception handling overhead
npx @tessl/cli install tessl/maven-com-google-guava--failureaccess@1.0.0Guava FailureAccess provides internal optimization utilities for accessing failure causes in Future implementations without the overhead of full exception handling. This micro-optimization library enables efficient failure cause retrieval for completed futures, primarily used internally by Guava and other Google libraries.
pom.xml:<dependency>
<groupId>com.google.guava</groupId>
<artifactId>failureaccess</artifactId>
<version>1.0.3</version>
</dependency>Or to your build.gradle:
implementation 'com.google.guava:failureaccess:1.0.3'import com.google.common.util.concurrent.internal.InternalFutureFailureAccess;
import com.google.common.util.concurrent.internal.InternalFutures;import com.google.common.util.concurrent.internal.InternalFutureFailureAccess;
import com.google.common.util.concurrent.internal.InternalFutures;
// Extend InternalFutureFailureAccess in your Future implementation
public class CustomFuture<V> extends InternalFutureFailureAccess {
private volatile Throwable failure;
@Override
protected Throwable tryInternalFastPathGetFailure() {
return failure; // Return failure cause if available, null otherwise
}
// Your Future implementation...
}
// Use InternalFutures to access failure cause from outside the class
CustomFuture<String> future = new CustomFuture<>();
Throwable failureCause = InternalFutures.tryInternalFastPathGetFailure(future);
if (failureCause != null) {
// Future has failed - handle the failure
System.out.println("Future failed with: " + failureCause.getMessage());
}The library follows a simple optimization pattern:
The core capability for accessing failure causes from Future implementations without exception overhead.
/**
* Abstract base class for futures that can optionally provide access to failure causes.
* Used for micro-optimization of Future utilities.
*/
public abstract class InternalFutureFailureAccess {
/**
* Protected constructor for use by subclasses.
* Prevents direct instantiation - must be extended.
*/
protected InternalFutureFailureAccess();
/**
* Returns the failure cause if this Future has failed, null otherwise.
* Protected method - use InternalFutures.tryInternalFastPathGetFailure() to access.
*
* Contract: If this returns non-null, then:
* - isDone() must return true
* - isCancelled() must return false
* - get() must throw ExecutionException with this as the cause
*/
protected abstract Throwable tryInternalFastPathGetFailure();
}Public interface for accessing the failure cause from InternalFutureFailureAccess instances.
/**
* Static utilities for InternalFutureFailureAccess.
* Most users will never need to use this class.
* Follows utility class pattern with private constructor.
*/
public final class InternalFutures {
/**
* Returns the failure cause if the given Future has failed, null otherwise.
* This is the public way to access the protected tryInternalFastPathGetFailure method.
*
* @param future The InternalFutureFailureAccess instance to query
* @return The failure cause if available, null otherwise
*/
public static Throwable tryInternalFastPathGetFailure(InternalFutureFailureAccess future);
/** Private constructor prevents instantiation - this is a utility class. */
private InternalFutures();
}The failure access mechanism has a strict contract:
If tryInternalFastPathGetFailure() returns non-null:
isDone() must return true on the FutureisCancelled() must return false on the Futureget() must not block and must throw ExecutionException with the returned Throwable as its causeFailure definition:
null even for failed futures (optimization is optional)This library does not throw exceptions during normal operation. The tryInternalFastPathGetFailure() method returns null when no failure information is available, requiring callers to handle this case appropriately.
com.google.common.util.concurrent.internal for JPMS compatibilityFor projects using the Java Platform Module System (JPMS), the library provides:
module com.google.common.util.concurrent.internal {
exports com.google.common.util.concurrent.internal;
}This allows proper module dependency declaration in your module-info.java:
requires com.google.common.util.concurrent.internal;