GoogleCloudPlatform / cloud-spanner-r2dbc

R2DBC driver for Google Cloud Spanner
Apache License 2.0
57 stars 29 forks source link

Aggregate functions in cloud-spanner-spring-data-r2dbc repos throw IndexOutOfBoundsException #609

Closed elmozgo closed 1 year ago

elmozgo commented 1 year ago

I tried to create an example project with:

I'm using cloud-spanner-spring-data-r2dbc version 1.1.0

To be able to start the app, apply schema using liquibase and make basic findById() repository methods work, I had to downgrade the versions quite a bit.

com.google.cloud->google-cloud-spanner-jdbc -> 2.4.4
com.google.cloudspannerecosystem:liquibase-spanner -> 4.9.1
io.r2dbc:r2dbc-spi -> 0.8.6.RELEASE
com.google.cloud:google-cloud-spanner -> 6.18.0
I created a simple entity: ```java @Table("names") public class NameEntity { @Id private String id; private String nickname; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } } ```
and a repo: ```java public interface NamesRepository extends ReactiveCrudRepository, NamesProvider {} ```

When testing the repository:


class NamesRepositoryTest extends CloudSpannerEmulatorSupport {

  @Autowired private NamesRepository namesRepository;

  @Test
  void tryBasicRepoMethods() {

    StepVerifier.create(namesRepository.findById("a1a8687d-3206-47b6-99d9-1317b1de2c94")) // this works 
        .expectNextCount(1L)
        .verifyComplete();

    StepVerifier.create(namesRepository.findAll()).expectNextCount(5L).verifyComplete(); // this works 

    StepVerifier.create(namesRepository.count()).expectNext(5L).verifyComplete(); //this throws
  }
}

I get the exception:

...

Suppressed: java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 1
        at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)
        at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
        at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
        at java.base/java.util.Objects.checkIndex(Objects.java:385)
        at java.base/java.util.ArrayList.get(ArrayList.java:427)
        at com.google.cloud.spanner.AbstractResultSet$GrpcStruct.isNull(AbstractResultSet.java:637)
        at com.google.cloud.spanner.r2dbc.v2.ClientLibraryDecoder.decode(ClientLibraryDecoder.java:92)
        at com.google.cloud.spanner.r2dbc.v2.SpannerClientLibraryRow.get(SpannerClientLibraryRow.java:34)
        at org.springframework.data.r2dbc.core.R2dbcEntityTemplate.lambda$doCount$1(R2dbcEntityTemplate.java:342)
        at com.google.cloud.spanner.r2dbc.v2.SpannerClientLibraryResult.lambda$map$0(SpannerClientLibraryResult.java:54)
        at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:106)
        at reactor.core.publisher.FluxCreate$BufferAsyncSink.drain(FluxCreate.java:814)
        at reactor.core.publisher.FluxCreate$BufferAsyncSink.next(FluxCreate.java:739)
        at reactor.core.publisher.FluxCreate$SerializedFluxSink.next(FluxCreate.java:161)
        at com.google.cloud.spanner.r2dbc.v2.ReactiveResultSetCallback.cursorReady(ReactiveResultSetCallback.java:82)
        at com.google.cloud.spanner.AsyncResultSetImpl$CallbackRunnable.run(AsyncResultSetImpl.java:265)
        at com.google.common.util.concurrent.SequentialExecutor$1.run(SequentialExecutor.java:123)
        at com.google.common.util.concurrent.SequentialExecutor$QueueWorker.workOnQueue(SequentialExecutor.java:235)
        at com.google.common.util.concurrent.SequentialExecutor$QueueWorker.run(SequentialExecutor.java:180)
        ... 9 more

I tried a repository method with a custom SQL (also aggregating) with the same effect.

my dependencies tree ```{style="max-height: 100px;"} [INFO] +- com.google.cloud:spring-cloud-gcp-starter:jar:3.4.0:compile [INFO] | +- com.google.cloud:spring-cloud-gcp-core:jar:3.4.0:compile [INFO] | | \- org.springframework:spring-context:jar:5.3.22:compile [INFO] | | \- org.springframework:spring-expression:jar:5.3.22:compile [INFO] | +- com.google.cloud:spring-cloud-gcp-autoconfigure:jar:3.4.0:compile [INFO] | | \- org.springframework.boot:spring-boot-autoconfigure:jar:2.7.3:compile [INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.7.3:compile [INFO] | | +- org.springframework.boot:spring-boot:jar:2.7.3:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:2.7.3:compile [INFO] | | | +- ch.qos.logback:logback-classic:jar:1.2.11:compile [INFO] | | | | \- ch.qos.logback:logback-core:jar:1.2.11:compile [INFO] | | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.17.2:compile [INFO] | | | | \- org.apache.logging.log4j:log4j-api:jar:2.17.2:compile [INFO] | | | \- org.slf4j:jul-to-slf4j:jar:1.7.36:compile [INFO] | | \- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile [INFO] | \- org.slf4j:slf4j-api:jar:1.7.36:compile [INFO] +- com.google.cloud:cloud-spanner-spring-data-r2dbc:jar:1.1.0:compile [INFO] | +- com.google.cloud:cloud-spanner-r2dbc:jar:1.1.0:compile [INFO] | | +- io.r2dbc:r2dbc-spi:jar:0.8.6.RELEASE:compile [INFO] | | \- io.projectreactor.addons:reactor-extra:jar:3.4.8:compile [INFO] | \- org.springframework.data:spring-data-r2dbc:jar:1.5.2:compile [INFO] | +- org.springframework.data:spring-data-commons:jar:2.7.2:compile [INFO] | +- org.springframework.data:spring-data-relational:jar:2.4.2:compile [INFO] | \- org.springframework:spring-r2dbc:jar:5.3.22:compile [INFO] +- org.springframework.boot:spring-boot-starter-webflux:jar:2.7.3:compile [INFO] | +- org.springframework.boot:spring-boot-starter-json:jar:2.7.3:compile [INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.13.3:compile [INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.13.3:compile [INFO] | | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.13.3:compile [INFO] | +- org.springframework.boot:spring-boot-starter-reactor-netty:jar:2.7.3:compile [INFO] | | \- io.projectreactor.netty:reactor-netty-http:jar:1.0.22:compile [INFO] | | +- io.netty:netty-codec-http:jar:4.1.79.Final:compile [INFO] | | | +- io.netty:netty-common:jar:4.1.79.Final:compile [INFO] | | | +- io.netty:netty-buffer:jar:4.1.79.Final:compile [INFO] | | | +- io.netty:netty-transport:jar:4.1.79.Final:compile [INFO] | | | +- io.netty:netty-codec:jar:4.1.79.Final:compile [INFO] | | | \- io.netty:netty-handler:jar:4.1.79.Final:compile [INFO] | | +- io.netty:netty-codec-http2:jar:4.1.79.Final:compile [INFO] | | +- io.netty:netty-resolver-dns:jar:4.1.79.Final:compile [INFO] | | | +- io.netty:netty-resolver:jar:4.1.79.Final:compile [INFO] | | | \- io.netty:netty-codec-dns:jar:4.1.79.Final:compile [INFO] | | +- io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64:4.1.79.Final:compile [INFO] | | | \- io.netty:netty-resolver-dns-classes-macos:jar:4.1.79.Final:compile [INFO] | | +- io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.79.Final:compile [INFO] | | | +- io.netty:netty-transport-native-unix-common:jar:4.1.79.Final:compile [INFO] | | | \- io.netty:netty-transport-classes-epoll:jar:4.1.79.Final:compile [INFO] | | \- io.projectreactor.netty:reactor-netty-core:jar:1.0.22:compile [INFO] | | \- io.netty:netty-handler-proxy:jar:4.1.79.Final:compile [INFO] | | \- io.netty:netty-codec-socks:jar:4.1.79.Final:compile [INFO] | +- org.springframework:spring-web:jar:5.3.22:compile [INFO] | \- org.springframework:spring-webflux:jar:5.3.22:compile [INFO] +- org.springframework.cloud:spring-cloud-starter-sleuth:jar:3.1.5:compile [INFO] | +- org.springframework.cloud:spring-cloud-starter:jar:3.1.5:compile [INFO] | | +- org.springframework.cloud:spring-cloud-context:jar:3.1.5:compile [INFO] | | | \- org.springframework.security:spring-security-crypto:jar:5.7.3:compile [INFO] | | +- org.springframework.cloud:spring-cloud-commons:jar:3.1.5:compile [INFO] | | \- org.springframework.security:spring-security-rsa:jar:1.0.11.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter-aop:jar:2.7.3:compile [INFO] | | +- org.springframework:spring-aop:jar:5.3.22:compile [INFO] | | \- org.aspectj:aspectjweaver:jar:1.9.7:compile [INFO] | +- org.springframework.cloud:spring-cloud-sleuth-autoconfigure:jar:3.1.5:compile [INFO] | | +- org.springframework.cloud:spring-cloud-sleuth-instrumentation:jar:3.1.5:compile [INFO] | | | \- org.springframework.cloud:spring-cloud-sleuth-api:jar:3.1.5:compile [INFO] | | \- org.aspectj:aspectjrt:jar:1.9.7:compile [INFO] | \- org.springframework.cloud:spring-cloud-sleuth-brave:jar:3.1.5:compile [INFO] | +- io.zipkin.brave:brave:jar:5.13.9:compile [INFO] | +- io.zipkin.brave:brave-context-slf4j:jar:5.13.9:compile [INFO] | +- io.zipkin.brave:brave-instrumentation-messaging:jar:5.13.9:compile [INFO] | +- io.zipkin.brave:brave-instrumentation-rpc:jar:5.13.9:compile [INFO] | +- io.zipkin.brave:brave-instrumentation-spring-rabbit:jar:5.13.9:compile [INFO] | +- io.zipkin.brave:brave-instrumentation-kafka-clients:jar:5.13.9:compile [INFO] | +- io.zipkin.brave:brave-instrumentation-kafka-streams:jar:5.13.9:compile [INFO] | +- io.zipkin.brave:brave-instrumentation-httpclient:jar:5.13.9:compile [INFO] | | \- io.zipkin.brave:brave-instrumentation-http:jar:5.13.9:compile [INFO] | +- io.zipkin.brave:brave-instrumentation-httpasyncclient:jar:5.13.9:compile [INFO] | +- io.zipkin.brave:brave-instrumentation-jms:jar:5.13.9:compile [INFO] | +- io.zipkin.brave:brave-instrumentation-mongodb:jar:5.13.9:compile [INFO] | +- io.zipkin.aws:brave-propagation-aws:jar:0.21.3:compile [INFO] | \- io.zipkin.reporter2:zipkin-reporter-metrics-micrometer:jar:2.16.3:compile [INFO] | \- io.zipkin.reporter2:zipkin-reporter:jar:2.16.3:compile [INFO] | \- io.zipkin.zipkin2:zipkin:jar:2.23.2:compile [INFO] +- org.springframework.boot:spring-boot-starter-actuator:jar:2.7.3:compile [INFO] | +- org.springframework.boot:spring-boot-actuator-autoconfigure:jar:2.7.3:compile [INFO] | | \- org.springframework.boot:spring-boot-actuator:jar:2.7.3:compile [INFO] | \- io.micrometer:micrometer-core:jar:1.9.3:compile [INFO] | +- org.hdrhistogram:HdrHistogram:jar:2.1.12:compile [INFO] | \- org.latencyutils:LatencyUtils:jar:2.0.3:runtime [INFO] +- org.springframework.boot:spring-boot-starter-validation:jar:2.7.3:compile [INFO] | +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.65:compile [INFO] | \- org.hibernate.validator:hibernate-validator:jar:6.2.4.Final:compile [INFO] | +- org.jboss.logging:jboss-logging:jar:3.4.3.Final:compile [INFO] | \- com.fasterxml:classmate:jar:1.5.1:compile [INFO] +- io.vavr:vavr:jar:0.10.4:compile [INFO] | \- io.vavr:vavr-match:jar:0.10.4:compile [INFO] +- jakarta.validation:jakarta.validation-api:jar:2.0.2:compile [INFO] +- org.springdoc:springdoc-openapi-webflux-ui:jar:1.6.11:compile [INFO] | +- org.springdoc:springdoc-openapi-webflux-core:jar:1.6.11:compile [INFO] | | \- org.springdoc:springdoc-openapi-common:jar:1.6.11:compile [INFO] | | \- io.swagger.core.v3:swagger-core:jar:2.2.2:compile [INFO] | | +- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:2.13.3:compile [INFO] | | +- io.swagger.core.v3:swagger-annotations:jar:2.2.2:compile [INFO] | | \- io.swagger.core.v3:swagger-models:jar:2.2.2:compile [INFO] | +- org.webjars:swagger-ui:jar:4.14.0:compile [INFO] | +- org.webjars:webjars-locator-core:jar:0.50:compile [INFO] | \- io.github.classgraph:classgraph:jar:4.8.149:compile [INFO] +- org.liquibase:liquibase-core:jar:4.9.1:compile [INFO] | \- javax.xml.bind:jaxb-api:jar:2.3.1:compile [INFO] | \- javax.activation:javax.activation-api:jar:1.2.0:compile [INFO] +- com.google.cloud:google-cloud-spanner-jdbc:jar:2.4.4:runtime [INFO] | +- com.google.http-client:google-http-client:jar:1.42.2:runtime [INFO] | +- org.apache.httpcomponents:httpclient:jar:4.5.13:runtime [INFO] | +- org.apache.httpcomponents:httpcore:jar:4.4.15:runtime [INFO] | +- com.google.j2objc:j2objc-annotations:jar:1.3:runtime [INFO] | +- io.opencensus:opencensus-api:jar:0.28.0:runtime [INFO] | +- io.opencensus:opencensus-contrib-http-util:jar:0.28.0:runtime [INFO] | +- io.grpc:grpc-api:jar:1.49.2:runtime [INFO] | +- io.grpc:grpc-context:jar:1.49.2:runtime [INFO] | +- com.google.cloud:google-cloud-core-grpc:jar:2.8.20:runtime [INFO] | +- com.google.api:gax:jar:2.19.2:runtime [INFO] | +- com.google.api:gax-grpc:jar:2.19.2:runtime [INFO] | | \- io.grpc:grpc-googleapis:jar:1.49.2:runtime [INFO] | +- io.grpc:grpc-core:jar:1.49.2:runtime [INFO] | +- com.google.api.grpc:proto-google-common-protos:jar:2.9.6:runtime [INFO] | +- com.google.cloud:google-cloud-spanner:jar:6.18.0:compile [INFO] | | +- io.grpc:grpc-xds:jar:1.49.2:runtime [INFO] | | +- io.grpc:grpc-services:jar:1.49.2:runtime [INFO] | | +- com.google.re2j:re2j:jar:1.5:runtime [INFO] | | +- org.bouncycastle:bcpkix-jdk15on:jar:1.67:compile [INFO] | | +- org.bouncycastle:bcprov-jdk15on:jar:1.67:runtime [INFO] | | \- io.opencensus:opencensus-proto:jar:0.2.0:runtime [INFO] | +- com.google.cloud:grpc-gcp:jar:1.2.1:runtime [INFO] | +- io.grpc:grpc-auth:jar:1.49.2:runtime [INFO] | +- com.google.android:annotations:jar:4.1.1.4:runtime [INFO] | +- org.codehaus.mojo:animal-sniffer-annotations:jar:1.20:runtime [INFO] | +- io.perfmark:perfmark-api:jar:0.23.0:runtime [INFO] | +- io.grpc:grpc-protobuf:jar:1.49.2:runtime [INFO] | +- io.grpc:grpc-protobuf-lite:jar:1.49.2:runtime [INFO] | +- io.grpc:grpc-stub:jar:1.49.2:runtime [INFO] | +- javax.annotation:javax.annotation-api:jar:1.3.2:runtime [INFO] | +- com.google.auto.value:auto-value-annotations:jar:1.9:runtime [INFO] | +- com.google.protobuf:protobuf-java-util:jar:3.21.7:runtime [INFO] | +- com.google.errorprone:error_prone_annotations:jar:2.9.0:runtime [INFO] | +- com.google.api.grpc:grpc-google-common-protos:jar:2.9.6:runtime [INFO] | +- com.google.guava:failureaccess:jar:1.0.1:runtime [INFO] | +- com.google.guava:listenablefuture:jar:9999.0-empty-to-avoid-conflict-with-guava:runtime [INFO] | +- org.checkerframework:checker-compat-qual:jar:2.5.5:runtime [INFO] | +- com.google.api.grpc:proto-google-iam-v1:jar:1.6.2:runtime [INFO] | +- com.google.http-client:google-http-client-gson:jar:1.42.2:runtime [INFO] | +- io.opencensus:opencensus-contrib-grpc-util:jar:0.28.0:runtime [INFO] | +- commons-logging:commons-logging:jar:1.2:runtime [INFO] | +- commons-codec:commons-codec:jar:1.15:runtime [INFO] | +- com.google.api.grpc:proto-google-cloud-spanner-admin-instance-v1:jar:6.31.2:runtime [INFO] | +- com.google.api.grpc:proto-google-cloud-spanner-admin-database-v1:jar:6.31.2:runtime [INFO] | +- com.google.api.grpc:grpc-google-cloud-spanner-admin-instance-v1:jar:6.31.2:runtime [INFO] | +- com.google.api.grpc:grpc-google-cloud-spanner-v1:jar:6.31.2:runtime [INFO] | +- com.google.api.grpc:grpc-google-cloud-spanner-admin-database-v1:jar:6.31.2:runtime [INFO] | +- org.checkerframework:checker-qual:jar:3.8.0:runtime [INFO] | +- com.google.code.gson:gson:jar:2.9.1:runtime [INFO] | +- io.grpc:grpc-grpclb:jar:1.49.2:runtime [INFO] | +- org.conscrypt:conscrypt-openjdk-uber:jar:2.5.1:runtime [INFO] | +- io.grpc:grpc-alts:jar:1.49.2:runtime [INFO] | +- com.google.protobuf:protobuf-java:jar:3.21.7:runtime [INFO] | +- com.google.guava:guava:jar:31.1-jre:runtime [INFO] | +- org.threeten:threetenbp:jar:1.5.1:runtime [INFO] | +- io.grpc:grpc-netty-shaded:jar:1.49.2:runtime [INFO] | +- com.google.api:api-common:jar:2.2.1:runtime [INFO] | +- com.google.code.findbugs:jsr305:jar:3.0.2:runtime [INFO] | +- com.google.auth:google-auth-library-oauth2-http:jar:1.11.0:runtime [INFO] | +- com.google.auth:google-auth-library-credentials:jar:1.11.0:runtime [INFO] | +- com.google.cloud:google-cloud-core:jar:2.8.20:compile [INFO] | \- com.google.api.grpc:proto-google-cloud-spanner-v1:jar:6.31.2:runtime [INFO] +- org.springframework:spring-jdbc:jar:5.3.22:runtime [INFO] | +- org.springframework:spring-beans:jar:5.3.22:compile [INFO] | +- org.springframework:spring-core:jar:5.3.22:compile [INFO] | | \- org.springframework:spring-jcl:jar:5.3.22:compile [INFO] | \- org.springframework:spring-tx:jar:5.3.22:compile [INFO] +- com.google.cloudspannerecosystem:liquibase-spanner:jar:4.9.1:runtime [INFO] | \- org.yaml:snakeyaml:jar:1.30:compile [INFO] +- org.springframework.boot:spring-boot-starter-test:jar:2.7.3:test [INFO] | +- org.springframework.boot:spring-boot-test:jar:2.7.3:test [INFO] | +- org.springframework.boot:spring-boot-test-autoconfigure:jar:2.7.3:test [INFO] | +- com.jayway.jsonpath:json-path:jar:2.7.0:test [INFO] | | \- net.minidev:json-smart:jar:2.4.8:test [INFO] | | \- net.minidev:accessors-smart:jar:2.4.8:test [INFO] | +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.3:compile [INFO] | | \- jakarta.activation:jakarta.activation-api:jar:1.2.2:compile [INFO] | +- org.junit.jupiter:junit-jupiter:jar:5.8.2:test [INFO] | | +- org.junit.jupiter:junit-jupiter-params:jar:5.8.2:test [INFO] | | \- org.junit.jupiter:junit-jupiter-engine:jar:5.8.2:test [INFO] | | \- org.junit.platform:junit-platform-engine:jar:1.8.2:test [INFO] | +- org.mockito:mockito-core:jar:4.5.1:test [INFO] | | +- net.bytebuddy:byte-buddy-agent:jar:1.12.13:test [INFO] | | \- org.objenesis:objenesis:jar:3.2:test [INFO] | +- org.mockito:mockito-junit-jupiter:jar:4.5.1:test [INFO] | +- org.skyscreamer:jsonassert:jar:1.5.1:test [INFO] | | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test [INFO] | +- org.springframework:spring-test:jar:5.3.22:test [INFO] | \- org.xmlunit:xmlunit-core:jar:2.9.0:test [INFO] +- io.projectreactor:reactor-test:jar:3.5.0:test [INFO] | \- io.projectreactor:reactor-core:jar:3.4.22:compile [INFO] | \- org.reactivestreams:reactive-streams:jar:1.0.4:compile [INFO] +- org.junit.jupiter:junit-jupiter-api:jar:5.8.2:test [INFO] | +- org.opentest4j:opentest4j:jar:1.2.0:test [INFO] | +- org.junit.platform:junit-platform-commons:jar:1.8.2:test [INFO] | \- org.apiguardian:apiguardian-api:jar:1.1.2:test [INFO] +- io.rest-assured:rest-assured:jar:4.5.1:test [INFO] | +- org.codehaus.groovy:groovy:jar:3.0.12:test [INFO] | +- org.codehaus.groovy:groovy-xml:jar:3.0.12:test [INFO] | +- org.apache.httpcomponents:httpmime:jar:4.5.13:test [INFO] | +- org.ccil.cowan.tagsoup:tagsoup:jar:1.2.1:test [INFO] | +- io.rest-assured:json-path:jar:4.5.1:test [INFO] | | +- org.codehaus.groovy:groovy-json:jar:3.0.12:test [INFO] | | \- io.rest-assured:rest-assured-common:jar:4.5.1:test [INFO] | \- io.rest-assured:xml-path:jar:4.5.1:test [INFO] +- com.github.tomakehurst:wiremock-jre8:jar:2.35.0:test [INFO] | +- org.eclipse.jetty:jetty-server:jar:9.4.48.v20220622:test [INFO] | | +- javax.servlet:javax.servlet-api:jar:4.0.1:test [INFO] | | +- org.eclipse.jetty:jetty-http:jar:9.4.48.v20220622:test [INFO] | | \- org.eclipse.jetty:jetty-io:jar:9.4.48.v20220622:test [INFO] | +- org.eclipse.jetty:jetty-servlet:jar:9.4.48.v20220622:test [INFO] | | +- org.eclipse.jetty:jetty-security:jar:9.4.48.v20220622:test [INFO] | | \- org.eclipse.jetty:jetty-util-ajax:jar:9.4.48.v20220622:test [INFO] | +- org.eclipse.jetty:jetty-servlets:jar:9.4.48.v20220622:test [INFO] | | +- org.eclipse.jetty:jetty-continuation:jar:9.4.48.v20220622:test [INFO] | | \- org.eclipse.jetty:jetty-util:jar:9.4.48.v20220622:test [INFO] | +- org.eclipse.jetty:jetty-webapp:jar:9.4.48.v20220622:test [INFO] | | \- org.eclipse.jetty:jetty-xml:jar:9.4.48.v20220622:test [INFO] | +- org.eclipse.jetty:jetty-proxy:jar:9.4.48.v20220622:test [INFO] | | \- org.eclipse.jetty:jetty-client:jar:9.4.48.v20220622:test [INFO] | +- org.eclipse.jetty.http2:http2-server:jar:9.4.48.v20220622:test [INFO] | | \- org.eclipse.jetty.http2:http2-common:jar:9.4.48.v20220622:test [INFO] | | \- org.eclipse.jetty.http2:http2-hpack:jar:9.4.48.v20220622:test [INFO] | +- org.eclipse.jetty:jetty-alpn-server:jar:9.4.48.v20220622:test [INFO] | +- org.eclipse.jetty:jetty-alpn-java-server:jar:9.4.48.v20220622:test [INFO] | +- org.eclipse.jetty:jetty-alpn-openjdk8-server:jar:9.4.48.v20220622:test [INFO] | +- org.eclipse.jetty:jetty-alpn-java-client:jar:9.4.48.v20220622:test [INFO] | | \- org.eclipse.jetty:jetty-alpn-client:jar:9.4.48.v20220622:test [INFO] | +- org.eclipse.jetty:jetty-alpn-openjdk8-client:jar:9.4.48.v20220622:test [INFO] | +- com.fasterxml.jackson.core:jackson-core:jar:2.13.3:compile [INFO] | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.13.3:compile [INFO] | +- com.fasterxml.jackson.core:jackson-databind:jar:2.13.3:compile [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.1.3:test [INFO] | | +- org.apache.httpcomponents.core5:httpcore5:jar:5.1.4:test [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.1.4:test [INFO] | +- org.xmlunit:xmlunit-legacy:jar:2.9.0:test [INFO] | +- org.xmlunit:xmlunit-placeholders:jar:2.9.0:test [INFO] | +- net.javacrumbs.json-unit:json-unit-core:jar:2.36.0:test [INFO] | +- org.ow2.asm:asm:jar:9.4:test [INFO] | +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test [INFO] | +- org.apache.commons:commons-lang3:jar:3.12.0:compile [INFO] | +- com.github.jknack:handlebars:jar:4.3.1:test [INFO] | +- com.github.jknack:handlebars-helpers:jar:4.3.1:test [INFO] | +- commons-fileupload:commons-fileupload:jar:1.4:test [INFO] | \- commons-io:commons-io:jar:2.11.0:test [INFO] +- org.hamcrest:hamcrest:jar:2.2:test [INFO] +- org.assertj:assertj-core:jar:3.23.1:test [INFO] | \- net.bytebuddy:byte-buddy:jar:1.12.13:test [INFO] +- junit:junit:jar:4.13.2:test [INFO] | \- org.hamcrest:hamcrest-core:jar:2.2:test [INFO] +- org.testcontainers:testcontainers:jar:1.16.3:test [INFO] | +- org.apache.commons:commons-compress:jar:1.21:test [INFO] | +- org.rnorth.duct-tape:duct-tape:jar:1.0.8:test [INFO] | | \- org.jetbrains:annotations:jar:17.0.0:test [INFO] | +- com.github.docker-java:docker-java-api:jar:3.2.12:test [INFO] | \- com.github.docker-java:docker-java-transport-zerodep:jar:3.2.12:test [INFO] | \- com.github.docker-java:docker-java-transport:jar:3.2.12:test [INFO] +- org.testcontainers:gcloud:jar:1.16.3:test [INFO] +- org.testcontainers:junit-jupiter:jar:1.16.3:test [INFO] +- uk.org.webcompere:system-stubs-jupiter:jar:2.0.1:test [INFO] | +- uk.org.webcompere:system-stubs-core:jar:2.0.1:test [INFO] | \- org.mockito:mockito-inline:jar:4.5.1:test [INFO] \- net.java.dev.jna:jna:jar:5.7.0:test```
mpeddada1 commented 1 year ago

@elmozgo Thanks for the details and providing your repro code. To help narrow down this issue, do you see this same behavior with this sample?

elmozgo commented 1 year ago

@mpeddada1 unfortunately it is still a problem in the sample project (v1.2.0):

I added this method to the controller:

@GetMapping("/count")
  public Mono<Long> countBooks() {
    return r2dbcRepository.count();
  }

The exception java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 1 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100) ~[na:na]

is thrown in SpannerClientLibraryRow line 34 - the get(int index, Class<T> type) method is called with index = 0, which is then then decremented to -1

I haven't investigated the underlying root cause

mpeddada1 commented 1 year ago

Thank you for the thorough investigation @elmozgo. That really helps. By calling the method you mentioned above and calling this.webTestClient.get().uri("/count/").exchange().expectBody(Long.class).isEqualTo(1L); in the tests, I'm also able to see the same error message:

java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 1
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) ~[na:na]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    *__checkpoint ⇢ Handler com.example.WebController#countBooks() [DispatcherHandler]
    *__checkpoint ⇢ HTTP GET "/count/" [ExceptionHandlingWebHandler]