Atlassian uses cookies to improve your browsing experience, perform analytics and research, and conduct advertising. Accept all cookies to indicate that you agree to our use of cookies on your device. Atlassian cookies and tracking notice, (opens new window)
Infinite recursion in reactive subdoc get operation
Description
Suggested release note:
Fixed a regression in 3.4.5 that caused `ReactiveCollection.lookupIn` to always throw `StackOverflowException`.
Attempting to use any reactive subdoc get operation using the latest Java client (3.4.5) results in a StackOverflowError due to infinite recursion.
Sample code (reproduce using the travel sample data):
var cluster = Cluster.connect("localhost", "username", "password"); cluster.waitUntilReady(Duration.ofSeconds(30)); var bucket = cluster.bucket("travel-sample"); bucket.waitUntilReady(Duration.ofSeconds(30)); var result = bucket.defaultCollection().reactive() .lookupIn("airline_10", List.of(LookupInSpec.get("name"))) .block(); System.out.println(result);
Partial output:
[ WARN] (main) throwIfFatal detected a jvm fatal exception, which is thrown and logged below: - java.lang.StackOverflowError java.lang.StackOverflowError at reactor.core.publisher.Operators.onOperatorError(Operators.java:719) at reactor.core.publisher.Operators.onOperatorError(Operators.java:697) at reactor.core.publisher.Operators.onOperatorError(Operators.java:679) at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:48) at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ...hundreds of lines... at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
Suggested release note:
Attempting to use any reactive subdoc get operation using the latest Java client (3.4.5) results in a StackOverflowError due to infinite recursion.
Sample code (reproduce using the travel sample data):
var cluster = Cluster.connect("localhost", "username", "password");
cluster.waitUntilReady(Duration.ofSeconds(30));
var bucket = cluster.bucket("travel-sample");
bucket.waitUntilReady(Duration.ofSeconds(30));
var result = bucket.defaultCollection().reactive()
.lookupIn("airline_10", List.of(LookupInSpec.get("name")))
.block();
System.out.println(result);
Partial output:
[ WARN] (main) throwIfFatal detected a jvm fatal exception, which is thrown and logged below: - java.lang.StackOverflowError
java.lang.StackOverflowError
at reactor.core.publisher.Operators.onOperatorError(Operators.java:719)
at reactor.core.publisher.Operators.onOperatorError(Operators.java:697)
at reactor.core.publisher.Operators.onOperatorError(Operators.java:679)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:48)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
...hundreds of lines...
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
This appears to be due to the following method, which does not defer to the corresponding async method as the other reactive methods do, instead calling itself: https://github.com/couchbase/couchbase-jvm-clients/blob/8263a6b445df6c0b7aa072497266d7b6553102b5/core-io/src/main/java/com/couchbase/client/core/api/kv/CoreKvOps.java#L318-L325