Comprehensive Java utility library providing infrastructure and helper classes for the Eclipse Jetty web server
—
Comprehensive callback and promise APIs for building non-blocking, asynchronous applications with various callback implementations and patterns for efficient resource utilization.
Core asynchronous operation completion handler with success/failure semantics.
/**
* Callback interface for asynchronous operations
*/
public interface Callback {
/** Called when operation completes successfully */
void succeeded();
/** Called when operation fails */
void failed(Throwable x);
/** Check if callback is non-blocking */
default boolean isNonBlocking() { return false; }
/** Create callback from Runnable and Consumer */
static Callback from(Runnable success, Consumer<Throwable> failure);
/** Create callback from Runnable only */
static Callback from(Runnable success);
/** Get NOOP callback instance */
static Callback NOOP;
}Usage Examples:
import org.eclipse.jetty.util.Callback;
// Simple callback usage
public void performAsyncTask(Callback callback) {
new Thread(() -> {
try {
// Simulate work
Thread.sleep(1000);
callback.succeeded();
} catch (Exception e) {
callback.failed(e);
}
}).start();
}
// Using factory methods
Callback callback = Callback.from(
() -> System.out.println("Success!"),
error -> System.err.println("Failed: " + error)
);
performAsyncTask(callback);Type-safe callback abstraction for operations that return results.
/**
* Promise interface extending Callback with result handling
*/
public interface Promise<C> extends Callback {
/** Called when operation completes successfully with result */
void succeeded(C result);
/** Create promise from Consumer and Consumer for error */
static <T> Promise<T> from(Consumer<T> success, Consumer<Throwable> failure);
/** Complete promise immediately with result */
static <T> Promise<T> complete(T result);
}Usage Examples:
import org.eclipse.jetty.util.Promise;
// Promise with result
public void fetchData(Promise<String> promise) {
CompletableFuture.supplyAsync(() -> {
// Simulate data fetching
return "Hello, World!";
}).whenComplete((result, error) -> {
if (error != null) {
promise.failed(error);
} else {
promise.succeeded(result);
}
});
}
// Using promise
Promise<String> promise = Promise.from(
result -> System.out.println("Got: " + result),
error -> System.err.println("Error: " + error)
);
fetchData(promise);Concrete implementation combining Future and Promise interfaces for synchronous and asynchronous usage patterns.
/**
* Future-based promise implementation
*/
public class FuturePromise<C> implements Future<C>, Promise<C> {
/** Create empty future promise */
public FuturePromise();
/** Create future promise with immediate result */
public FuturePromise(C result);
/** Create future promise with immediate failure */
public FuturePromise(C ctx, Throwable failed);
/** Get result, blocking if necessary (from Future) */
public C get() throws InterruptedException, ExecutionException;
/** Get result with timeout (from Future) */
public C get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
/** Get result or throw original exception */
public C getOrThrow() throws Exception;
/** Check if operation completed */
public boolean isDone();
/** Check if operation was cancelled */
public boolean isCancelled();
/** Cancel the operation */
public boolean cancel(boolean mayInterruptIfRunning);
/** Utility to rethrow ExecutionException as IOException */
public static void rethrow(ExecutionException e) throws IOException;
}Usage Examples:
import org.eclipse.jetty.util.FuturePromise;
import java.util.concurrent.TimeUnit;
// Create and use FuturePromise
FuturePromise<String> promise = new FuturePromise<>();
// Start async operation
performAsyncTask(promise);
// Block for result
try {
String result = promise.get(5, TimeUnit.SECONDS);
System.out.println("Result: " + result);
} catch (TimeoutException e) {
System.out.println("Operation timed out");
promise.cancel(true);
} catch (ExecutionException e) {
System.out.println("Operation failed: " + e.getCause());
}
// Pre-completed promise
FuturePromise<Integer> completed = new FuturePromise<>(42);
assert completed.isDone();
assert completed.get() == 42;
// Failed promise
FuturePromise<String> failed = new FuturePromise<>(null, new RuntimeException("Error"));
assert failed.isDone();
try {
failed.getOrThrow(); // Throws the original RuntimeException
} catch (RuntimeException e) {
System.out.println("Expected failure: " + e.getMessage());
}Various callback implementations for different use cases.
/**
* Callback that counts down operations
*/
public class CountingCallback implements Callback {
/** Create counting callback */
public CountingCallback(Callback callback, int count);
/** Get current count */
public int getCount();
}
/**
* Future-based callback implementation
*/
public class FutureCallback implements Callback, Future<Void> {
/** Create future callback */
public FutureCallback();
/** Create future callback with boolean result */
public FutureCallback(boolean completed);
/** Block until completion */
public void block() throws IOException;
}
/**
* Iterating callback for step-by-step processing
*/
public abstract class IteratingCallback implements Callback {
/** Perform next iteration step */
protected abstract Action process() throws Throwable;
/** Start iteration process */
public void iterate();
/** Action enum for iteration control */
public enum Action { SCHEDULED, IDLE, SUCCEEDED }
}
/**
* Shared blocking callback for reuse
*/
public class SharedBlockingCallback {
/** Create shared callback with pool */
public SharedBlockingCallback();
/** Acquire callback for use */
public Blocker acquire();
/** Blocker interface for blocking operations */
public interface Blocker extends Callback, Closeable {
void block() throws IOException;
}
}Usage Examples:
import org.eclipse.jetty.util.*;
// Counting multiple operations
CountingCallback counter = new CountingCallback(finalCallback, 3);
performAsyncTask(counter); // Will call finalCallback after 3 completions
performAsyncTask(counter);
performAsyncTask(counter);
// Future-style blocking
FutureCallback future = new FutureCallback();
performAsyncTask(future);
try {
future.get(5, TimeUnit.SECONDS); // Block with timeout
} catch (TimeoutException e) {
// Handle timeout
}
// Iterative processing
IteratingCallback processor = new IteratingCallback() {
private int step = 0;
@Override
protected Action process() throws Throwable {
if (step++ < 10) {
// Process step
return Action.SCHEDULED;
}
return Action.SUCCEEDED;
}
};
processor.iterate();
// Shared blocking callback
SharedBlockingCallback shared = new SharedBlockingCallback();
try (SharedBlockingCallback.Blocker blocker = shared.acquire()) {
performAsyncTask(blocker);
blocker.block(); // Block until completion
}Additional utilities for asynchronous programming.
/**
* Utility for blocking operations
*/
public class Blocker implements Callback, Closeable {
/** Block until callback completes */
public void block() throws IOException;
/** Block with timeout */
public boolean block(long timeout, TimeUnit unit) throws IOException;
/** Check if completed */
public boolean isDone();
/** Get failure cause if any */
public Throwable getFailure();
}
/**
* Wrapper callback for additional functionality
*/
public class CallbackWrapper implements Callback {
/** Create wrapper around another callback */
public CallbackWrapper(Callback callback);
/** Get wrapped callback */
public Callback getCallback();
}Usage Examples:
import org.eclipse.jetty.util.Blocker;
import org.eclipse.jetty.util.CallbackWrapper;
// Simple blocking
try (Blocker blocker = new Blocker()) {
performAsyncTask(blocker);
boolean completed = blocker.block(30, TimeUnit.SECONDS);
if (!completed) {
System.out.println("Operation timed out");
}
}
// Callback decoration
Callback wrapped = new CallbackWrapper(originalCallback) {
@Override
public void succeeded() {
System.out.println("Operation succeeded");
super.succeeded();
}
@Override
public void failed(Throwable x) {
System.out.println("Operation failed: " + x.getMessage());
super.failed(x);
}
};// Chain multiple async operations
public void chainedOperations(Callback finalCallback) {
performFirstOperation(new Callback() {
@Override
public void succeeded() {
performSecondOperation(new Callback() {
@Override
public void succeeded() {
performThirdOperation(finalCallback);
}
@Override
public void failed(Throwable x) {
finalCallback.failed(x);
}
});
}
@Override
public void failed(Throwable x) {
finalCallback.failed(x);
}
});
}// Robust error handling
public class SafeCallback implements Callback {
private final Callback delegate;
public SafeCallback(Callback delegate) {
this.delegate = delegate;
}
@Override
public void succeeded() {
try {
delegate.succeeded();
} catch (Exception e) {
// Log but don't propagate callback exceptions
logger.warn("Callback exception", e);
}
}
@Override
public void failed(Throwable x) {
try {
delegate.failed(x);
} catch (Exception e) {
logger.warn("Callback exception", e);
}
}
}isNonBlocking() to indicate callback execution characteristicsSharedBlockingCallback for blocking operations to reduce allocationIteratingCallback for step-by-step processing to avoid stack overflowAsynchronous operations handle errors through the callback mechanism:
failed(Throwable) is called for all operation failuresInstall with Tessl CLI
npx tessl i tessl/maven-org-eclipse-jetty--jetty-util