ibmdb / java_reactive_driver

IBM Db2 Java Reactive Driver based on R2DBC.
6 stars 1 forks source link

Various `NullPointerException` on connection handshake failures #3

Open mp911de opened 1 year ago

mp911de commented 1 year ago

Connecting fails quite often with NullPointerException when either the remote peer closes the connection immediately (e.g. when DB2 within docker doesn't listen and the docker portforwarding closes the connection right after connecting or after Internal Error - Remote System CCSID Manager is unknown)

stack trace:

java.lang.NullPointerException: Cannot invoke "com.ibm.db2.r2dbc.DB2Connection.close()" because "this.h" is null
    at com.ibm.db2.r2dbc.b.d.lambda$new$6(d.java:136)
    at reactor.netty.transport.ClientTransportConfig$ClientTransportDoOn.lambda$onStateChange$0(ClientTransportConfig.java:296)
    at reactor.core.publisher.LambdaMonoSubscriber.onComplete(LambdaMonoSubscriber.java:135)
    at reactor.core.publisher.Operators.complete(Operators.java:137)
    at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4495)
    at reactor.core.publisher.Mono.subscribeWith(Mono.java:4561)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4462)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4398)
    at reactor.netty.DisposableChannel.onDispose(DisposableChannel.java:140)
    at reactor.netty.Connection.onDispose(Connection.java:277)
    at reactor.netty.channel.ChannelOperations.onDispose(ChannelOperations.java:239)
    at reactor.netty.transport.ClientTransportConfig$ClientTransportDoOn.onStateChange(ClientTransportConfig.java:296)
    at reactor.netty.resources.NewConnectionProvider$NewConnectionObserver.onStateChange(NewConnectionProvider.java:211)
    at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:490)
    at reactor.netty.channel.ChannelOperations.onInboundClose(ChannelOperations.java:446)
    at reactor.netty.channel.ChannelOperationsHandler.channelInactive(ChannelOperationsHandler.java:73)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:305)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281)
    at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901)
    at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:813)
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:833)

java.lang.RuntimeException: [rdb2-1-0] inbound is on complete

    at com.ibm.db2.r2dbc.b.d.lambda$null$2(d.java:123)
    Suppressed: The stacktrace has been enhanced by Reactor, refer to additional information below: 
Assembly trace from producer [reactor.core.publisher.MonoCreate] :
    reactor.core.publisher.Mono.create(Mono.java:202)
    com.ibm.db2.r2dbc.b.d.a(d.java:445)
Error has been observed at the following site(s):
    *________Mono.create ⇢ at com.ibm.db2.r2dbc.b.d.a(d.java:445)
    |_  Mono.flatMapMany ⇢ at com.ibm.db2.r2dbc.b.d.a(d.java:462)
    |_       Flux.handle ⇢ at com.ibm.db2.r2dbc.b.q.a(q.java:90)
    |_ Flux.doOnComplete ⇢ at com.ibm.db2.r2dbc.b.q.a(q.java:126)
    |_         Flux.then ⇢ at com.ibm.db2.r2dbc.b.q.a(q.java:135)
    *____Mono.delayUntil ⇢ at com.ibm.db2.r2dbc.DB2ConnectionFactory.create(DB2ConnectionFactory.java:77)
    *____Mono.delayUntil ⇢ at com.ibm.db2.r2dbc.DB2ConnectionFactory.create(DB2ConnectionFactory.java:78)
    *____Mono.delayUntil ⇢ at com.ibm.db2.r2dbc.DB2ConnectionFactory.create(DB2ConnectionFactory.java:79)
    |_          Mono.map ⇢ at com.ibm.db2.r2dbc.DB2ConnectionFactory.create(DB2ConnectionFactory.java:134)
    *____Mono.delayUntil ⇢ at com.ibm.db2.r2dbc.DB2ConnectionFactory.create(DB2ConnectionFactory.java:136)
Original Stack Trace:
        at com.ibm.db2.r2dbc.b.d.lambda$null$2(d.java:123)
        at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:268)
        at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:277)
        at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onComplete(FluxHandleFuseable.java:239)
        at reactor.core.publisher.FluxPeekFuseable$PeekFuseableConditionalSubscriber.onComplete(FluxPeekFuseable.java:595)
        at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onComplete(FluxMap.java:275)
        at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:413)
        at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:431)
        at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:485)
        at reactor.netty.channel.ChannelOperations.onInboundClose(ChannelOperations.java:446)
        at reactor.netty.channel.ChannelOperationsHandler.channelInactive(ChannelOperationsHandler.java:73)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:305)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281)
        at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901)
        at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:813)
        at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:833)
    Suppressed: java.lang.Exception: #block terminated with an error
        at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:102)
        at reactor.core.publisher.Mono.block(Mono.java:1712)
rs-rappavu commented 1 year ago

Thanks Mark. Will check this out.

rs-rappavu commented 1 year ago

Can you please share the code sample that caused this issue?

mp911de commented 1 year ago

It is essentially the following code block either during Docker startup (when the server does not listen yet on port 50000 or when the database initialization has failed):

DB2ConnectionFactory cf = new DB2ConnectionFactory(DB2ConnectionConfiguration.builder()
        .host("localhost")
        .port(50000)
        .database("testdb")
        .username("db2inst1")
        .password("foobar").build()
);

        cf.create().block();