705 Promises Specification

705.1 Introduction

One of the fundamental pieces of an asynchronous programming model is the mechanism by which clients retrieve the result of the asynchronous task. Since Java 5, there has been a java.util.concurrent.Future interface available in the Java class libraries, which means that it is the de facto API in Java for handling the result of an asynchronous task. Futures have some limitations however in that they have no mechanism for registering callbacks. Java 8 introduces the class java.util.concurrent.CompletableFuture which addresses this but the requirement of Java 8 is unsuitable for many OSGi users at this time.

This specification defines a Promises API which can be used on many versions of Java including Java 5 and Java ME CDC/Foundation. The Promises API defined by this specification is independent of all other OSGi specifications including the OSGi Framework and thus can be easily used outside of the OSGi environment.

A Promise object holds the result of a potentially asynchronous task. The receiver of a Promise object can register callbacks on the Promise to be notified when the result is available or can block on the result becoming available. Promises can be chained together in powerful ways to handle asynchronous work flows and recovery.

Promises capture the effects of latency and errors by making these explicit in the API signatures. Latency is represented by callbacks which will eventually be called. Errors are represented by the failure member. In essence, this is what sets Promises apart from things such as RPC calls where such effects are not explicitly captured but rather attempted to be transparently handled.

705.1.1 Essentials

  • Common concepts - The API is inspired by the Promises work in JavaScript and uses the same basic concepts. See [2] JavaScript Promises.

  • Independent - The design is independent of all other OSGi specifications and can be used outside of an OSGi environment.

  • Asynchronous - The design supports asynchronous tasks.

  • Small - The API and implementation are very compact.

  • Complete - The design provides a very complete set of operations for Promise which are primitives that can be used to address most use cases.

  • Monad - The design supports monadic programming. See [4] Monad.

  • Resolution - A Promise can be resolved successfully with a value or unsuccessfully with an exception.

  • Generified - Generics are used to promote type safety.

705.1.2 Entities

  • Promise - A Promise object holds the eventual result of a potentially asynchronous task.

  • Callback - The receiver of a Promise can register callbacks on the Promise to be notified when the task is completed.

  • Deferred - A Deferred object represents the potentially asynchronous task and is used to resolve the Promise.

Figure 705.1 Class diagram of org.osgi.util.promise

Class diagram of org.osgi.util.promise

705.2 Promise

A Promise object holds the eventual result of a potentially asynchronous task. A Promise is either unresolved or resolved. An unresolved Promise does not have the result of the associated task available while a resolved Promise has the result of the associated task available. The isDone() method must return true if the Promise is resolved and false if the Promise is unresolved. A Promise must only be resolved once.

A resolved Promise can be either resolved with a value, which means the associated task completed successfully and supplied a result, or resolved with a failure, which means the associated task completed unsuccessfully and supplied an exception. The getFailure() method can be called to determine if the resolved Promise completed successfully with a value or unsuccessfully with a failure. If the getFailure() method returns a Throwable, the Promise resolved unsuccessfully with a failure. If the getFailure() method returns null, the Promise resolved successfully with a value that can be obtained from getValue().

If the Promise is unresolved, then calling getFailure() or getValue() must block until the Promise is resolved. In general, these two methods should not be used outside of a callback. Use callbacks to be notified when the Promise is resolved. See Callbacks.

705.3 Deferred

Promise is an interface which can allow for many Promise implementations. This API contains the Deferred class which provides access to the standard Promise implementation. A Deferred object can be created by calling the deferred() method on a PromiseFactory object.

A PromiseFactory object is created with a specified callback executor and a specified scheduled executor to use for created Promise objects and the Promise objects associated with created Deferred objects. If the callback executor or the scheduled executor is not specified or is specified as null, then implementation default executors will be used. The Deferred() constructor will create a Deferred whose associated Promise uses the implementation default executors. All Promise objects created by a Promise must use the same executors as the creating Promise. Callbacks must be called using the callback executor. The scheduled executor must be used by the timeout(long) and delay(long) operations. The inlineExecutor() method can be used to obtain an executor which runs callbacks immediately on the thread calling the Executor.execute method. This behavior is similar to how callbacks were executed in the default Promise implementation of Promise 1.0 specification.

The Promise associated with a Deferred object can be obtained using getPromise(). This Promise can then be supplied to other parties who can use it to be notified of and obtain the eventual result.

public Promise<String> getTimeConsumingAnswer() {
  Deferred<String> deferred = factory.deferred();
  asynchronously(() -> doTask(deferred));
  return deferred.getPromise();
}

A Deferred object can later be used to resolve the associated Promise successfully by calling resolve(T) or unsuccessfully by calling fail(Throwable).

private void doTask(Deferred<String> deferred) {
  try {
    String answer = computeTimeConsumingAnswer();
    deferred.resolve(answer); // successfully resolve with value
  } catch (Exception e) {
    deferred.fail(e); // unsuccessfully resolve with exception
  }
}

A Deferred object can also be used to resolve the associated Promise with the eventual result of another Promise by calling resolveWith(Promise).

private void doTask(Deferred<String> deferred) {
  try {
    Promise<String> promise = getPromiseWithTheAnswer();
    deferred.resolveWith(promise); // resolve with another Promise
  } catch (Exception e) {
    deferred.fail(e); // unsuccessfully resolve with exception
  }
}

If resolve(T) or fail(Throwable) is called when the Promise associated with the Deferred is already resolved, then an Illegal State Exception must be thrown.

Care must be taken in sharing a Deferred object with other parties since the other parties can resolve the associated Promise. A Deferred object should be made available only to the party that will responsible for resolving the associated Promise.

705.4 Callbacks

To be notified when a Promise has been resolved, callbacks are used. The Promise API provides two forms of callbacks: the basic Runnable and Consumer callbacks and the more specialized Success and Failure callbacks.

A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the callback is called.

Resolving a Promise happens-before any registered callback is called. That is, for the resolved Promise, in a registered callback isDone() must return true and getValue() and getFailure() must not block.

Callbacks may be registered at any time including before and after a Promise has been resolved. If a callback is registered before the Promise is resolved, it will be called later when the Promise is resolved. If a callback is registered on an already resolved Promise, it will be called right away.

705.4.1 Runnable

The onResolve(Runnable) method is used to register a Runnable with the Promise which must be called when the Promise is resolved either successfully with a value or unsuccessfully with a failure. The resolved Promise is not passed to the Runnable, so if the Runnable implementation needs access to the resolved Promise, it must take care to ensure it has access.

final Promise<String> answer = getTimeConsumingAnswer();
answer.onResolve(() -> doSomethingWithAnswer(answer));

The onResolve(Runnable) method returns the Promise object upon which it is called.

705.4.2 Consumer

The thenAccept(Consumer) method is used to register a Consumer with the Promise which must be called when the Promise is resolved successfully with a value. The value of the resolved Promise is passed to the Consumer.

final Promise<String> answer = getTimeConsumingAnswer().thenAccept(s ->
    doSomethingWithAnswer(s)
);

The thenAccept(Consumer) method returns a new Promise which will be resolved with either the exception thrown from the Consumer, if one is thrown, or with the Promise.

The onSuccess(Consumer) method is used to register a Consumer with the Promise which must be called when the Promise is resolved successfully with a value. The value of the resolved Promise is passed to the Consumer. The onSuccess(Consumer) method returns the Promise object upon which it is called.

The onFailure(Consumer) method is used to register a Consumer with the Promise which must be called when the Promise is resolved unsuccessfully with a failure. The failure of the resolved Promise is passed to the Consumer. The onFailure(Consumer) method returns the Promise object upon which it is called.

705.4.3 Success and Failure

The then(Success) and then(Success,Failure) methods can be used to register the more specialized Success and Failure callbacks. The Success callback is only called if the Promise is successfully resolved with a value. The Failure callback is only called if the Promise is unsuccessfully resolved with a failure.

Promise<String> answer = getTimeConsumingAnswer();
answer.then(p -> processResult(p.getValue()), p -> handleFailure(p.getFailure()));

The then methods return a new Promise which can be used to chain Promises together.

705.5 Chaining Promises

The then(Success), then(Success,Failure), and thenAccept(Consumer) methods also provide a means to chain Promises together. These methods return a new Promise which is chained to the original Promise upon which the method was called. The returned Promise must be resolved when the original Promise is resolved after the specified Success, Failure, or Consumer callback is executed. The result of the executed callback must be used to resolve the returned Promise. A sequence of calls to the then methods can be used to create a chain of promises which are resolved in sequence.

For the then(Success) or then(Success,Failure) methods, if the original Promise is successfully resolved, the Success callback is executed and the Promise returned by the Success callback, if any, or thrown exception is used to resolve the Promise returned from the method. If the original Promise is resolved with a failure, the Failure callback is executed and the Promise returned from the method is resolved with a failure.

For the thenAccept(Consumer) method, if the original Promise is successfully resolved, the Consumer callback is executed and the value of the original Promise or thrown exception is used to resolve the Promise returned from the method. If the original Promise is resolved with a failure, the Consumer callback is not executed and the Promise returned from the method is resolved with the failure of the original Promise.

In the following example, a Promise which will supply the name of the file to download is chained to a Promise which will return a mirror URL to use to download the file which is then further chained to a Promise which will return an Input Stream from which to read the download file.

Promise<String> name = getDownloadName();
Promise<URL> mirror = name.then(p -> getMirror(p.getValue()));
Promise<InputStream> in = mirror.then(p -> getStream(p.getValue()));

Since we probably do not need the intermediate Promises, we can collapse the chain into a single statement.

Promise<InputStream> in = getDownloadName().then(p -> getMirror(p.getValue()))
                                           .then(p -> getStream(p.getValue()));

The chain of Promises will also propagate any exceptions that occur to resolve the last Promise in the chain which means we do not need to do any exception handling in the intermediate tasks. Promises can also be chained by using the monadic programming methods in Monad.

705.6 Monad

The Promise API supports monadic programming. See [4] Monad. The Promise interface defines a number of interesting methods including map, flatMap and filter.

  • filter(Predicate) - Filter the value of the Promise.

    If the Promise is successfully resolved, the predicate argument is called with the value of the Promise. If the predicate accepts the value, then the value is used to successfully resolve the Promise returned by the filter method. If the predicate does not accept the value, the Promise returned by the filter method is unsuccessfully resolved with a No Such Element Exception. If the predicate throws an exception, the Promise returned by the filter method is unsuccessfully resolved with that exception.

    If the Promise is unsuccessfully resolved, the predicate argument is not called and the Promise returned by the filter method is unsuccessfully resolved with the failure of the Promise.

  • map(Function) - Map the value of the Promise.

    If the Promise is successfully resolved, the function argument is called with the value of the Promise. The value returned by the function is used to successfully resolve the Promise returned by the map method. If the function throws an exception, the Promise returned by the map method is unsuccessfully resolved with that exception.

    If the Promise is unsuccessfully resolved, the function argument is not called and the Promise returned by the map method is unsuccessfully resolved with the failure of the Promise.

  • flatMap(Function) - FlatMap the value of the Promise.

    If the Promise is successfully resolved, the function argument is called with the value of the Promise. The Promise returned by the function is used to resolve the Promise returned by the flatMap method. If the function throws an exception, the Promise returned by the flatMap method is unsuccessfully resolved with that exception.

    If the Promise is unsuccessfully resolved, the function argument is not called and the Promise returned by the flatMap method is unsuccessfully resolved with the failure of the Promise.

  • recover(Function) - Recover from the unsuccessful resolution of the Promise with a recovery value.

    If the Promise is successfully resolved, the function argument is not called and the Promise returned by the recover method is resolved with the value of the Promise.

    If the Promise is unsuccessfully resolved, the function argument is called with the Promise to supply a recovery value. If the recovery value is not null, the Promise returned by the recover method is successfully resolved with the recovery value. If the recovery value is null, the Promise returned by the recover method is unsuccessfully resolved with the failure of the Promise. If the function throws an exception, the Promise returned by the recover method is unsuccessfully resolved with that exception.

  • recoverWith(Function) - Recover from the unsuccessful resolution of the Promise with a recovery Promise.

    If the Promise is successfully resolved, the function argument is not called and the Promise returned by the recover method is resolved with the value of the Promise.

    If the Promise is unsuccessfully resolved, the function argument is called with the Promise to supply a recovery Promise. If the recovery Promise is not null, the Promise returned by the recover method is resolved with the recovery Promise. If the recovery Promise is null, the Promise returned by the recover method is unsuccessfully resolved with the failure of the Promise. If the function throws an exception, the Promise returned by the recover method is unsuccessfully resolved with that exception.

  • fallbackTo(Promise) - Fall back to the value of the Promise argument if the Promise unsuccessfully resolves.

    If the Promise is successfully resolved, the Promise argument is not used and the Promise returned by the fallbackTo method is resolved with the value of the Promise.

    If the Promise is unsuccessfully resolved, the Promise argument is used to provide a fallback value when it becomes resolved. If the Promise argument is successfully resolved, the Promise returned by the fallbackTo method is resolved with the value of the Promise argument. If the Promise argument is unsuccessfully resolved, the Promise returned by the fallbackTo method is unsuccessfully resolved with the failure of the Promise.

These functions can be used to build pipelines of chained Promises that are processed in sequence. For example, in the following chain, the value of the original promise, once resolved, is filtered for acceptable values. If the filter says the value is not acceptable, the recover method will be used to replace it with a default value.

return promise.filter(v -> isValueOk(v)).recover(p -> getDefaultValue())

With these chains, one can write powerful programs without the need to resort to complex if/else and try/catch logic.

705.7 Timing

The Promise API provides methods to affect the timing of resolving Promises.

  • timeout(long) - Time out the resolution of the Promise.

    If the Promise is successfully resolved before the timeout, the returned Promise is resolved with the value of the Promise. If the Promise is resolved with a failure before the timeout, the returned Promise is resolved with the failure of the Promise. If the timeout is reached before the Promise is resolved, the returned Promise is failed with a TimeoutException.

  • delay(long) - Delay after the resolution of the Promise.

    Once the Promise is resolved, resolve the returned Promise with the Promise after the specified delay.

705.8 Functional Interfaces

In Java 8, the concept of Functional Interfaces is introduced. See [5] Function Interfaces. Functional interfaces are types with a single abstract method. Instances of functional interfaces can be created with lambda expressions, method references, or constructor references. Many methods on Promise take functional interface arguments and so are suitable for use with lambda expressions and method references in Java 8.

Three of these functional interfaces are Function, Predicate, and Consumer. These are equivalent to functional interfaces which are part of the java.util.function package introduced in Java 8. OSGi defines these interfaces to allow throwing checked exceptions which can be propagated in a chain of Promises.

705.9 Utility Methods

The API also provides several useful utility methods when working with Promises.

Often, you may need to create an already resolved Promise to return or chain with another Promise. The resolved(T) method can be used to create a new Promise already successfully resolved with the specified value. The failed(Throwable) method can be used to create a new Promise already unsuccessfully resolved with the specified exception. These methods also exists as static methods on the Promises class returning Promises which use the implementation default executors.

  return getTimeConsumingAnswer().fallbackTo(factory.resolved("Fallback Value"));

The submit(Callable) method can be used to return a new Promise that will hold the result of the specified task. The task will be executed on the callback executor.

The all(Collection) method returns a Promise that is a latch on the specified Promises. The returned Promise must resolve only when all of the specified Promises have resolved. This method also exists as a static method on the Promises class returning a Promise which uses the implementation default executors.

705.10 Security

The Promise API does not define any OSGi services nor does the API perform any privileged actions. Therefore, it has no security considerations.

705.11 org.osgi.util.promise

Version 1.1

Promise Package Version 1.1.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest.

Example import for consumers using the API in this package:

Import-Package: org.osgi.util.promise; version="[1.1,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.util.promise; version="[1.1,1.2)"

705.11.1 Summary

705.11.2 public class Deferred<T>

The value type associated with the created Promise.

A Deferred Promise resolution.

Instances of this class can be used to create a Promise that can be resolved in the future. The associated Promise can be successfully resolved with resolve(Object) or resolved with a failure with fail(Throwable). It can also be resolved with the resolution of another promise using resolveWith(Promise).

The associated Promise can be provided to any one, but the Deferred object should be made available only to the party that will responsible for resolving the Promise.

Immutable

Consumers of this API must not implement this type

705.11.2.1 public Deferred()

Create a new Deferred.

The associated promise will use the default callback executor and default scheduled executor.

PromiseFactory.deferred()

705.11.2.2 public void fail(Throwable failure)

The failure of the resolved Promise. Must not be null.

Fail the Promise associated with this Deferred.

After the associated Promise is resolved with the specified failure, all registered callbacks are called and any chained Promises are resolved. This may occur asynchronously to this method.

Resolving the associated Promise happens-before any registered callback is called. That is, in a registered callback, Promise.isDone() must return true and Promise.getValue() and Promise.getFailure() must not block.

IllegalStateException– If the associated Promise was already resolved.

705.11.2.3 public Promise<T> getPromise()

Returns the Promise associated with this Deferred.

All Promise objects created by the associated Promise will use the executors of the associated Promise.

The Promise associated with this Deferred.

705.11.2.4 public void resolve(T value)

The value of the resolved Promise.

Successfully resolve the Promise associated with this Deferred.

After the associated Promise is resolved with the specified value, all registered callbacks are called and any chained Promises are resolved. This may occur asynchronously to this method.

Resolving the associated Promise happens-before any registered callback is called. That is, in a registered callback, Promise.isDone() must return true and Promise.getValue() and Promise.getFailure() must not block.

IllegalStateException– If the associated Promise was already resolved.

705.11.2.5 public Promise<Void> resolveWith(Promise<? extends T> with)

A Promise whose value or failure must be used to resolve the associated Promise. Must not be null.

Resolve the Promise associated with this Deferred with the specified Promise.

If the specified Promise is successfully resolved, the associated Promise is resolved with the value of the specified Promise. If the specified Promise is resolved with a failure, the associated Promise is resolved with the failure of the specified Promise.

After the associated Promise is resolved with the specified Promise, all registered callbacks are called and any chained Promises are resolved. This may occur asynchronously to this method.

Resolving the associated Promise happens-before any registered callback is called. That is, in a registered callback, Promise.isDone() must return true and Promise.getValue() and Promise.getFailure() must not block.

A Promise that is resolved only when the associated Promise is resolved by the specified Promise. The returned Promise must be successfully resolved with the value null, if the associated Promise was resolved by the specified Promise. The returned Promise must be resolved with a failure of IllegalStateException, if the associated Promise was already resolved when the specified Promise was resolved.

705.11.2.6 public String toString()

Returns a string representation of the associated Promise.

A string representation of the associated Promise.

1.1

705.11.3 public class FailedPromisesException
extends RuntimeException

Promise failure exception for a collection of failed Promises.

705.11.3.1 public FailedPromisesException(Collection<Promise<?>> failed, Throwable cause)

A collection of Promises that have been resolved with a failure. Must not be null, must not be empty and all of the elements in the collection must not be null.

The cause of this exception. This is typically the failure of the first Promise in the specified collection.

Create a new FailedPromisesException with the specified Promises.

705.11.3.2 public Collection<Promise<?>> getFailedPromises()

Returns the collection of Promises that have been resolved with a failure.

The collection of Promises that have been resolved with a failure. The returned collection is unmodifiable.

705.11.4 public interface Failure

Failure callback for a Promise.

A Failure callback is registered with a Promise using the Promise.then(Success, Failure) method and is called if the Promise is resolved with a failure.

This is a functional interface and can be used as the assignment target for a lambda expression or method reference.

Thread-safe

705.11.4.1 public void fail(Promise<?> resolved) throws Exception

The failed resolved Promise.

Failure callback for a Promise.

This method is called if the Promise with which it is registered resolves with a failure.

In the remainder of this description we will refer to the Promise returned by Promise.then(Success, Failure) when this Failure callback was registered as the chained Promise.

If this methods completes normally, the chained Promise must be failed with the same exception which failed the resolved Promise. If this method throws an exception, the chained Promise must be failed with the thrown exception.

Exception– The chained Promise must be failed with the thrown exception.

705.11.5 public interface Promise<T>

The value type associated with this Promise.

A Promise of a value.

A Promise represents a future value. It handles the interactions for asynchronous processing. A Deferred object can be used to create a Promise and later resolve the Promise. A Promise is used by the caller of an asynchronous function to get the result or handle the error. The caller can either get a callback when the Promise is resolved with a value or an error, or the Promise can be used in chaining. In chaining, callbacks are provided that receive the resolved Promise, and a new Promise is generated that resolves based upon the result of a callback.

Both callbacks and chaining can be repeated any number of times, even after the Promise has been resolved.

Example callback usage:

 Promise<String> foo = foo();
 foo.onResolve(() -> System.out.println("resolved"));

Example chaining usage;

 Success<String,String> doubler = p -> Promises
 		.resolved(p.getValue() + p.getValue());
 Promise<String> foo = foo().then(doubler).then(doubler);

Thread-safe

Consumers of this API must not implement this type

705.11.5.1 public Promise<T> delay(long milliseconds)

The time to delay in milliseconds. Zero and negative time is treated as no delay.

Delay after the resolution of this Promise.

Once this Promise is resolved, resolve the returned Promise with this Promise after the specified delay.

A Promise that is resolved with this Promise after this Promise is resolved and the specified delay has elapsed.

1.1

705.11.5.2 public Promise<T> fallbackTo(Promise<? extends T> fallback)

The Promise whose value must be used to resolve the returned Promise if this Promise resolves with a failure. Must not be null.

Fall back to the value of the specified Promise if this Promise fails.

If this Promise is successfully resolved, the returned Promise must be resolved with the value of this Promise.

If this Promise is resolved with a failure, the successful result of the specified Promise is used to resolve the returned Promise. If the specified Promise is resolved with a failure, the returned Promise must be failed with the failure of this Promise rather than the failure of the specified Promise.

This method may be called at any time including before and after this Promise has been resolved.

A Promise that returns the value of this Promise or falls back to the value of the specified Promise.

705.11.5.3 public Promise<T> filter(Predicate<? super T> predicate)

The Predicate to evaluate the value of this Promise. Must not be null.

Filter the value of this Promise.

If this Promise is successfully resolved, the returned Promise must either be resolved with the value of this Promise, if the specified Predicate accepts that value, or failed with a NoSuchElementException, if the specified Predicate does not accept that value. If the specified Predicate throws an exception, the returned Promise must be failed with the exception.

If this Promise is resolved with a failure, the returned Promise must be failed with that failure.

This method may be called at any time including before and after this Promise has been resolved.

A Promise that filters the value of this Promise.

705.11.5.4 public Promise<R> flatMap(Function<? super T, Promise<? extends R>> mapper)

<R>

The value type associated with the returned Promise.

The Function that must flatMap the value of this Promise to a Promise that must be used to resolve the returned Promise. Must not be null.

FlatMap the value of this Promise.

If this Promise is successfully resolved, the returned Promise must be resolved with the Promise from the specified Function as applied to the value of this Promise. If the specified Function throws an exception, the returned Promise must be failed with the exception.

If this Promise is resolved with a failure, the returned Promise must be failed with that failure.

This method may be called at any time including before and after this Promise has been resolved.

A Promise that returns the value of this Promise as mapped by the specified Function.

705.11.5.5 public Throwable getFailure() throws InterruptedException

Returns the failure of this Promise.

If this Promise is not resolved, this method must block and wait for this Promise to be resolved before completing.

If this Promise was resolved with a failure, this method returns with the failure of this Promise. If this Promise was successfully resolved, this method must return null.

The failure of this resolved Promise or null if this Promise was successfully resolved.

InterruptedException– If the current thread was interrupted while waiting.

705.11.5.6 public T getValue() throws InvocationTargetException, InterruptedException

Returns the value of this Promise.

If this Promise is not resolved, this method must block and wait for this Promise to be resolved before completing.

If this Promise was successfully resolved, this method returns with the value of this Promise. If this Promise was resolved with a failure, this method must throw an InvocationTargetException with the failure exception as the cause.

The value of this resolved Promise.

InvocationTargetException– If this Promise was resolved with a failure. The cause of the InvocationTargetException is the failure exception.

InterruptedException– If the current thread was interrupted while waiting.

705.11.5.7 public boolean isDone()

Returns whether this Promise has been resolved.

This Promise may be successfully resolved or resolved with a failure.

true if this Promise was resolved either successfully or with a failure; false if this Promise is unresolved.

705.11.5.8 public Promise<R> map(Function<? super T, ? extends R> mapper)

<R>

The value type associated with the returned Promise.

The Function that must map the value of this Promise to the value that must be used to resolve the returned Promise. Must not be null.

Map the value of this Promise.

If this Promise is successfully resolved, the returned Promise must be resolved with the value of specified Function as applied to the value of this Promise. If the specified Function throws an exception, the returned Promise must be failed with the exception.

If this Promise is resolved with a failure, the returned Promise must be failed with that failure.

This method may be called at any time including before and after this Promise has been resolved.

A Promise that returns the value of this Promise as mapped by the specified Function.

705.11.5.9 public Promise<T> onFailure(Consumer<? super Throwable> failure)

The Consumer callback that receives the failure of this Promise. Must not be null.

Register a callback to be called with the failure for this Promise when this Promise is resolved with a failure. The callback will not be called if this Promise is resolved successfully.

This method may be called at any time including before and after this Promise has been resolved.

Resolving this Promise happens-before any registered callback is called. That is, in a registered callback, isDone() must return true and getValue() and getFailure() must not block.

A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the registered callback is called.

This Promise.

1.1

705.11.5.10 public Promise<T> onResolve(Runnable callback)

The callback to be called when this Promise is resolved. Must not be null.

Register a callback to be called when this Promise is resolved.

The specified callback is called when this Promise is resolved either successfully or with a failure.

This method may be called at any time including before and after this Promise has been resolved.

Resolving this Promise happens-before any registered callback is called. That is, in a registered callback, isDone() must return true and getValue() and getFailure() must not block.

A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the registered callback is called.

This Promise.

705.11.5.11 public Promise<T> onSuccess(Consumer<? super T> success)

The Consumer callback that receives the value of this Promise. Must not be null.

Register a callback to be called with the result of this Promise when this Promise is resolved successfully. The callback will not be called if this Promise is resolved with a failure.

This method may be called at any time including before and after this Promise has been resolved.

Resolving this Promise happens-before any registered callback is called. That is, in a registered callback, isDone() must return true and getValue() and getFailure() must not block.

A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the registered callback is called.

This Promise.

1.1

705.11.5.12 public Promise<T> recover(Function<Promise<?>, ? extends T> recovery)

If this Promise resolves with a failure, the specified Function is called to produce a recovery value to be used to resolve the returned Promise. Must not be null.

Recover from a failure of this Promise with a recovery value.

If this Promise is successfully resolved, the returned Promise must be resolved with the value of this Promise.

If this Promise is resolved with a failure, the specified Function is applied to this Promise to produce a recovery value.

  • If the recovery value is not null, the returned Promise must be resolved with the recovery value.

  • If the recovery value is null, the returned Promise must be failed with the failure of this Promise.

  • If the specified Function throws an exception, the returned Promise must be failed with that exception.

To recover from a failure of this Promise with a recovery value of null, the recoverWith(Function) method must be used. The specified Function for recoverWith(Function) can return Promises.resolved(null) to supply the desired null value.

This method may be called at any time including before and after this Promise has been resolved.

A Promise that resolves with the value of this Promise or recovers from the failure of this Promise.

705.11.5.13 public Promise<T> recoverWith(Function<Promise<?>, Promise<? extends T>> recovery)

If this Promise resolves with a failure, the specified Function is called to produce a recovery Promise to be used to resolve the returned Promise. Must not be null.

Recover from a failure of this Promise with a recovery Promise.

If this Promise is successfully resolved, the returned Promise must be resolved with the value of this Promise.

If this Promise is resolved with a failure, the specified Function is applied to this Promise to produce a recovery Promise.

  • If the recovery Promise is not null, the returned Promise must be resolved with the recovery Promise.

  • If the recovery Promise is null, the returned Promise must be failed with the failure of this Promise.

  • If the specified Function throws an exception, the returned Promise must be failed with that exception.

This method may be called at any time including before and after this Promise has been resolved.

A Promise that resolves with the value of this Promise or recovers from the failure of this Promise.

705.11.5.14 public Promise<R> then(Success<? super T, ? extends R> success, Failure failure)

<R>

The value type associated with the returned Promise.

The Success callback to be called when this Promise is successfully resolved. May be null if no Success callback is required. In this case, the returned Promise must be resolved with the value null when this Promise is successfully resolved.

The Failure callback to be called when this Promise is resolved with a failure. May be null if no Failure callback is required.

Chain a new Promise to this Promise with Success and Failure callbacks.

The specified Success callback is called when this Promise is successfully resolved and the specified Failure callback is called when this Promise is resolved with a failure.

This method returns a new Promise which is chained to this Promise. The returned Promise must be resolved when this Promise is resolved after the specified Success or Failure callback is executed. The result of the executed callback must be used to resolve the returned Promise. Multiple calls to this method can be used to create a chain of promises which are resolved in sequence.

If this Promise is successfully resolved, the Success callback is executed and the result Promise, if any, or thrown exception is used to resolve the returned Promise from this method. If this Promise is resolved with a failure, the Failure callback is executed and the returned Promise from this method is failed.

This method may be called at any time including before and after this Promise has been resolved.

Resolving this Promise happens-before any registered callback is called. That is, in a registered callback, isDone() must return true and getValue() and getFailure() must not block.

A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the registered callback is called.

A new Promise which is chained to this Promise. The returned Promise must be resolved when this Promise is resolved after the specified Success or Failure callback, if any, is executed.

705.11.5.15 public Promise<R> then(Success<? super T, ? extends R> success)

<R>

The value type associated with the returned Promise.

The Success callback to be called when this Promise is successfully resolved. May be null if no Success callback is required. In this case, the returned Promise must be resolved with the value null when this Promise is successfully resolved.

Chain a new Promise to this Promise with a Success callback.

This method performs the same function as calling then(Success, Failure) with the specified Success callback and null for the Failure callback.

A new Promise which is chained to this Promise. The returned Promise must be resolved when this Promise is resolved after the specified Success, if any, is executed.

then(Success, Failure)

705.11.5.16 public Promise<T> thenAccept(Consumer<? super T> consumer)

The Consumer callback that receives the value of this Promise. Must not be null.

Chain a new Promise to this Promise with a Consumer callback that receives the value of this Promise when it is successfully resolved.

The specified Consumer is called when this Promise is resolved successfully.

This method returns a new Promise which is chained to this Promise. The returned Promise must be resolved when this Promise is resolved after the specified callback is executed. If the callback throws an exception, the returned Promise is failed with that exception. Otherwise the returned Promise is resolved with the success value from this Promise.

This method may be called at any time including before and after this Promise has been resolved.

Resolving this Promise happens-before any registered callback is called. That is, in a registered callback, isDone() must return true and getValue() and getFailure() must not block.

A callback may be called on a different thread than the thread which registered the callback. So the callback must be thread safe but can rely upon that the registration of the callback happens-before the registered callback is called.

A new Promise which is chained to this Promise. The returned Promise must be resolved when this Promise is resolved after the specified Consumer is executed.

1.1

705.11.5.17 public Promise<T> timeout(long milliseconds)

The time to wait in milliseconds. Zero and negative time is treated as an immediate timeout.

Time out the resolution of this Promise.

If this Promise is successfully resolved before the timeout, the returned Promise is resolved with the value of this Promise. If this Promise is resolved with a failure before the timeout, the returned Promise is resolved with the failure of this Promise. If the timeout is reached before this Promise is resolved, the returned Promise is failed with a TimeoutException.

A Promise that is resolved when either this Promise is resolved or the specified timeout is reached.

1.1

705.11.6 public class PromiseFactory

Promise factory to create Deferred and Promise objects.

Instances of this class can be used to create Deferred and Promise objects which use the executors used to construct this object for any callback or scheduled operation execution.

1.1

Immutable

705.11.6.1 public PromiseFactory(Executor callbackExecutor)

The executor to use for callbacks. null can be specified for the default callback executor.

Create a new PromiseFactory with the specified callback executor.

The default scheduled executor will be used.

705.11.6.2 public PromiseFactory(Executor callbackExecutor, ScheduledExecutorService scheduledExecutor)

The executor to use for callbacks. null can be specified for the default callback executor.

The scheduled executor for use for scheduled operations. null can be specified for the default scheduled executor.

Create a new PromiseFactory with the specified callback executor and specified scheduled executor.

705.11.6.3 public Promise<List<T>> all(Collection<Promise<S>> promises)

<T, S extends T>

The value type of the List value associated with the returned Promise.

A subtype of the value type of the List value associated with the returned Promise.

The Promises which must be resolved before the returned Promise must be resolved. Must not be null and all of the elements in the collection must not be null.

Returns a new Promise that is a latch on the resolution of the specified Promises.

The returned Promise uses the callback executor and scheduled executor of this PromiseFactory object.

The returned Promise acts as a gate and must be resolved after all of the specified Promises are resolved.

A Promise that must be successfully resolved with a List of the values in the order of the specified Promises if all the specified Promises are successfully resolved. The List in the returned Promise is the property of the caller and is modifiable. The returned Promise must be resolved with a failure of FailedPromisesException if any of the specified Promises are resolved with a failure. The failure FailedPromisesException must contain all of the specified Promises which resolved with a failure.

705.11.6.4 public Deferred<T> deferred()

<T>

The value type associated with the returned Deferred.

Create a new Deferred with the callback executor and scheduled executor of this PromiseFactory object.

Use this method instead of Deferred.Deferred() to create a new Deferred whose associated Promise uses executors other than the default executors.

A new Deferred with the callback and scheduled executors of this PromiseFactory object

705.11.6.5 public Executor executor()

Returns the executor to use for callbacks.

The executor to use for callbacks. This will be the default callback executor if null was specified for the callback executor when this PromiseFactory was created.

705.11.6.6 public Promise<T> failed(Throwable failure)

<T>

The value type associated with the returned Promise.

The failure of the resolved Promise. Must not be null.

Returns a new Promise that has been resolved with the specified failure.

The returned Promise uses the callback executor and scheduled executor of this PromiseFactory object.

Use this method instead of Promises.failed(Throwable) to create a Promise which uses executors other than the default executors.

A new Promise that has been resolved with the specified failure.

705.11.6.7 public static Executor inlineExecutor()

Returns an Executor implementation that executes tasks immediately on the thread calling the Executor.execute method.

An Executor implementation that executes tasks immediately on the thread calling the Executor.execute method.

705.11.6.8 public Promise<T> resolved(T value)

<T>

The value type associated with the returned Promise.

The value of the resolved Promise.

Returns a new Promise that has been resolved with the specified value.

The returned Promise uses the callback executor and scheduled executor of this PromiseFactory object.

Use this method instead of Promises.resolved(Object) to create a Promise which uses executors other than the default executors.

A new Promise that has been resolved with the specified value.

705.11.6.9 public ScheduledExecutorService scheduledExecutor()

Returns the scheduled executor to use for scheduled operations.

The scheduled executor to use for scheduled operations. This will be the default scheduled executor if null was specified for the scheduled executor when this PromiseFactory was created.

705.11.6.10 public Promise<T> submit(Callable<? extends T> task)

<T>

The value type associated with the returned Promise.

The task whose result will be available from the returned Promise.

Returns a new Promise that will hold the result of the specified task.

The returned Promise uses the callback executor and scheduled executor of this PromiseFactory object.

The specified task will be executed on the callback executor.

A new Promise that will hold the result of the specified task.

705.11.7 public class Promises

Static helper methods for Promises.

These methods return Promises which use the default callback executor and default scheduled executor. See PromiseFactory for similar methods which use executors other than the default executors.

PromiseFactory

Thread-safe

705.11.7.1 public static Promise<List<T>> all(Collection<Promise<S>> promises)

<T, S extends T>

The value type of the List value associated with the returned Promise.

A subtype of the value type of the List value associated with the returned Promise.

The Promises which must be resolved before the returned Promise must be resolved. Must not be null and all of the elements in the collection must not be null.

Returns a new Promise that is a latch on the resolution of the specified Promises.

The returned Promise acts as a gate and must be resolved after all of the specified Promises are resolved.

A Promise which uses the default callback executor and default scheduled executor that is resolved only when all the specified Promises are resolved. The returned Promise must be successfully resolved with a List of the values in the order of the specified Promises if all the specified Promises are successfully resolved. The List in the returned Promise is the property of the caller and is modifiable. The returned Promise must be resolved with a failure of FailedPromisesException if any of the specified Promises are resolved with a failure. The failure FailedPromisesException must contain all of the specified Promises which resolved with a failure.

PromiseFactory.all(Collection)

705.11.7.2 public static Promise<List<T>> all(Promise<? extends T>... promises)

<T>

The value type associated with the specified Promises.

The Promises which must be resolved before the returned Promise must be resolved. Must not be null and all of the arguments must not be null.

Returns a new Promise that is a latch on the resolution of the specified Promises.

The new Promise acts as a gate and must be resolved after all of the specified Promises are resolved.

A Promise which uses the default callback executor and scheduled executor that is resolved only when all the specified Promises are resolved. The returned Promise must be successfully resolved with a List of the values in the order of the specified Promises if all the specified Promises are successfully resolved. The List in the returned Promise is the property of the caller and is modifiable. The returned Promise must be resolved with a failure of FailedPromisesException if any of the specified Promises are resolved with a failure. The failure FailedPromisesException must contain all of the specified Promises which resolved with a failure.

PromiseFactory.all(Collection)

705.11.7.3 public static Promise<T> failed(Throwable failure)

<T>

The value type associated with the returned Promise.

The failure of the resolved Promise. Must not be null.

Returns a new Promise that has been resolved with the specified failure.

A new Promise which uses the default callback executor and default scheduled executor that has been resolved with the specified failure.

PromiseFactory.failed(Throwable)

705.11.7.4 public static Promise<T> resolved(T value)

<T>

The value type associated with the returned Promise.

The value of the resolved Promise.

Returns a new Promise that has been resolved with the specified value.

A new Promise which uses the default callback executor and default scheduled executor that has been resolved with the specified value.

PromiseFactory.resolved(Object)

705.11.8 public interface Success<T, R>

The value type of the resolved Promise passed as input to this callback.

The value type of the returned Promise from this callback.

Success callback for a Promise.

A Success callback is registered with a Promise using the Promise.then(Success) method and is called if the Promise is resolved successfully.

This is a functional interface and can be used as the assignment target for a lambda expression or method reference.

Thread-safe

705.11.8.1 public Promise<R> call(Promise<T> resolved) throws Exception

The successfully resolved Promise.

Success callback for a Promise.

This method is called if the Promise with which it is registered resolves successfully.

In the remainder of this description we will refer to the Promise returned by this method as the returned Promise and the Promise returned by Promise.then(Success) when this Success callback was registered as the chained Promise.

If the returned Promise is null then the chained Promise must resolve immediately with a successful value of null. If the returned Promise is not null then the chained Promise must be resolved when the returned Promise is resolved.

The Promise to use to resolve the chained Promise, or null if the chained Promise is to be resolved immediately with the value null.

Exception– The chained Promise must be failed with the thrown exception.

705.11.9 public class TimeoutException
extends Exception

Timeout exception for a Promise.

1.1

705.11.9.1 public TimeoutException()

Create a new TimeoutException.

705.12 org.osgi.util.function

Version 1.1

Function Package Version 1.1.

Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest.

Example import for consumers using the API in this package:

Import-Package: org.osgi.util.function; version="[1.1,2.0)"

Example import for providers implementing the API in this package:

Import-Package: org.osgi.util.function; version="[1.1,1.2)"

705.12.1 Summary

  • Consumer - A function that accepts a single argument and produces no result.

  • Function - A function that accepts a single argument and produces a result.

  • Predicate - A predicate that accepts a single argument and produces a boolean result.

705.12.2 public interface Consumer<T>

The type of the function input.

A function that accepts a single argument and produces no result.

This is a functional interface and can be used as the assignment target for a lambda expression or method reference.

1.1

Thread-safe

705.12.2.1 public void accept(T t) throws Exception

The input to this function.

Applies this function to the specified argument.

Exception– An exception thrown by the method.

705.12.3 public interface Function<T, R>

The type of the function input.

The type of the function output.

A function that accepts a single argument and produces a result.

This is a functional interface and can be used as the assignment target for a lambda expression or method reference.

Thread-safe

705.12.3.1 public R apply(T t) throws Exception

The input to this function.

Applies this function to the specified argument.

The output of this function.

Exception– An exception thrown by the method.

705.12.4 public interface Predicate<T>

The type of the predicate input.

A predicate that accepts a single argument and produces a boolean result.

This is a functional interface and can be used as the assignment target for a lambda expression or method reference.

Thread-safe

705.12.4.1 public boolean test(T t) throws Exception

The input to this predicate.

Evaluates this predicate on the specified argument.

true if the specified argument is accepted by this predicate; false otherwise.

Exception– An exception thrown by the method.

705.14 Changes

  • Function and Predicate are updated so that their methods are now declared to throw Exception.

  • The Consumer functional interface is added to the org.osgi.util.function package. New methods are added to Promise which accept a Consumer. See Consumer.

  • New timeout and delay methods are added to Promise. See Timing.

  • The new PromiseFactory class has constructors which allow the caller to specify the executors to be used by Deferred and Promise objects created by a PromiseFactory object. The PromiseFactory class provides an inlineExecutor which can be used to provide behavior similar to how callbacks were executed in the default Promise implementation of the Promise 1.0 specification.