Lio*_*fon 8 java asynchronous nullpointerexception java-8 completable-future
我收到这个异常:
Caused by: java.lang.NullPointerException
at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:616) ~[?:1.8.0_302]
at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:591) ~[?:1.8.0_302]
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488) ~[?:1.8.0_302]
at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1975) ~[?:1.8.0_302]
at com.tcom.concurrent.ConcurrentUtils$3.onSuccess(ConcurrentUtils.java:140) ~[framework-20220815.38-RELEASE.jar:?]
Run Code Online (Sandbox Code Playgroud)
这种异常很少见,并且在我的系统中无法重现。
查看 CompletableFuture.java 似乎fFunction 变量为 null。
但第二行有一个空检查uniApply(),所以f不能为空。
那么为什么 JVM 声称我在函数调用行上有 NPE 呢?如果 NPE 来自调用的函数内部,我不应该在堆栈跟踪中看到它吗?
public static <I, O> CompletableFuture<O> buildCompletableFuture(final ListenableFuture<I> listenableFuture,
final Function<I, O> responseApplier,
final Consumer<I> onSuccessConsumer,
final Consumer<Throwable> onFailureConsumer,
final Supplier<O> defaultValueOnExceptionSupplier,
final Executor callBackExecutor) {
//create an instance of CompletableFuture
final CompletableFuture<I> innerComplete = new CompletableFuture<I>() {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
// propagate cancel to the listenable future
boolean result = listenableFuture.cancel(mayInterruptIfRunning);
super.cancel(mayInterruptIfRunning);
return result;
}
};
// add callback
Futures.addCallback(listenableFuture, new FutureCallback<I>() {
@Override
public void onSuccess(I result) {
innerComplete.complete(result);
if (onSuccessConsumer != null) {
onSuccessConsumer.accept(result);
}
}
@Override
public void onFailure(Throwable t) {
innerComplete.completeExceptionally(t);
if (onFailureConsumer != null) {
onFailureConsumer.accept(t);
}
}
}, callBackExecutor);
CompletableFuture<O> returnedFuture = innerComplete.thenApply(responseApplier);
if (defaultValueOnExceptionSupplier != null) { //when we have default value the exception will not thrown
returnedFuture = returnedFuture.exceptionally((ex) -> defaultValueOnExceptionSupplier.get());
}
return returnedFuture;
}
Run Code Online (Sandbox Code Playgroud)
final <S> boolean uniApply(CompletableFuture<S> a,
Function<? super S,? extends T> f,
UniApply<S,T> c) {
Object r; Throwable x;
if (a == null || (r = a.result) == null || f == null)
return false;
tryComplete: if (result == null) {
if (r instanceof AltResult) {
if ((x = ((AltResult)r).ex) != null) {
completeThrowable(x, r);
break tryComplete;
}
r = null;
}
try {
if (c != null && !c.claim())
return false;
@SuppressWarnings("unchecked") S s = (S) r;
completeValue(f.apply(s)); // This is CompletableFuture.java:616
} catch (Throwable ex) {
completeThrowable(ex);
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
ConcurrentUtils.buildCompletableFuture(asyncTask,
ObjectWithTimestamp::getObject, s -> {},
e -> logger.error("error message"), null, MoreExecutors.directExecutor())
Run Code Online (Sandbox Code Playgroud)
实际上是funiApply()ObjectWithTimestamp::getObject
| 归档时间: |
|
| 查看次数: |
3009 次 |
| 最近记录: |