Closed GeorgiPetkov closed 3 years ago
has-workaround
: since this is a fusion issue, disabling fusion by hiding the source will temporarily fix the problem:
Mono.empty()
.map(x -> "test1")
.single()
.hide() // THIS IS THE WORKAROUND
.map(x -> "test2")
.block();
As a potential workaround to be applied to an entire codebase, one can use the hook demonstrated below:
// see https://github.com/reactor/reactor-core/issues/2663
@Test
void smokeTestFusionMonoSingleMonoWithGh2663Workaround() {
//HOOK START
//TODO remove the workaround part when #2663 is fixed
Hooks.onEachOperator("workaroundGh2663", p -> {
if ("MonoSingleMono".equals(p.getClass().getSimpleName())
|| "MonoSingleCallable".equals(p.getClass().getSimpleName())) {
//it should be ok to use the Mono API here as we selectively
// wrap two types of publishers, so it won't loop and reapply
//this hook to hide()
return ((Mono) p).hide();
}
return p;
});
//HOOK ENDS, DEMONSTRATION BELOW
Mono.just(1)
.map(Function.identity())
.single()
.filter(v -> true)
.block();
Mono.fromCallable(() -> 1)
.single()
.filter(v -> true)
.block();
}
Usage of
Mono#single
between 2 calls ofMono#map
fails withClassCastException
.Expected Behavior
no
ClassCastException
failure during subscription (worked on 3.4.3)Actual Behavior
ClassCastException
failure during subscriptionSteps to Reproduce
The following test fails with
ClassCastException
(instead ofNoSuchElementException
). The expected behaviour is not relevant, you can replaceMono.empty()
withMono.just("test")
and it will still fail withClassCastException
(instead of passing). Note that each of the 3 operators is necesasry to reproduce the issue.Test output (version 3.4.4):
Expected output (version 3.4.3):
Your Environment
Java15, project reactor v3.4.4 (works on 3.4.3)