Skip to content

rest client reactive throws npe on null request body #32047

@Postremus

Description

@Postremus

Describe the bug

I use rest client reactive with this interface:

@Consumes(MediaType.APPLICATION_JSON)
public interface GreetingAPI {

    @POST
    @Path("hello")
    void greet(GreetingAPI api);
}

On the server side, I have not defined an endpoint for this resource. I therefore expect something like 405 or 404 as response code.

If I specifiy a request body, I correctly get my 405.

If I leave the request body as null, I get the exception from below.
This worked with the old rest-client.

Expected behavior

if my request body is empty, no body is sent to server.

Actual behavior

2023-03-22 18:20:32,082 ERROR [org.jbo.res.rea.com.cor.AbstractResteasyReactiveContext] (executor-thread-0) Request failed: java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "entityObject" is null
        at org.jboss.resteasy.reactive.client.impl.RestClientRequestContext.writeEntity(RestClientRequestContext.java:251)
        at org.jboss.resteasy.reactive.client.handlers.ClientSendRequestHandler.setRequestHeadersAndPrepareBody(ClientSendRequestHandler.java:497)
        at org.jboss.resteasy.reactive.client.handlers.ClientSendRequestHandler$2.accept(ClientSendRequestHandler.java:190)
        at org.jboss.resteasy.reactive.client.handlers.ClientSendRequestHandler$2.accept(ClientSendRequestHandler.java:114)
        at io.smallrye.context.impl.wrappers.SlowContextualConsumer.accept(SlowContextualConsumer.java:21)
        at io.smallrye.mutiny.helpers.UniCallbackSubscriber.onItem(UniCallbackSubscriber.java:73)
        at io.smallrye.mutiny.operators.uni.UniOperatorProcessor.onItem(UniOperatorProcessor.java:47)
        at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:60)
        at org.jboss.resteasy.reactive.client.AsyncResultUni.lambda$subscribe$1(AsyncResultUni.java:35)
        at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
        at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
        at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
        at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
        at io.vertx.core.http.impl.HttpClientImpl.lambda$null$5(HttpClientImpl.java:652)
        at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
        at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
        at io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:86)
        at io.vertx.core.impl.DuplicatedContext.execute(DuplicatedContext.java:163)
        at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:51)
        at io.vertx.core.impl.future.FutureImpl.addListener(FutureImpl.java:196)
        at io.vertx.core.impl.future.PromiseImpl.addListener(PromiseImpl.java:23)
        at io.vertx.core.impl.future.FutureImpl.onComplete(FutureImpl.java:164)
        at io.vertx.core.impl.future.PromiseImpl.onComplete(PromiseImpl.java:23)
        at io.vertx.core.http.impl.Http1xClientConnection.createStream(Http1xClientConnection.java:1199)
        at io.vertx.core.http.impl.HttpClientImpl.lambda$doRequest$6(HttpClientImpl.java:635)
        at io.vertx.core.net.impl.pool.Endpoint.lambda$getConnection$0(Endpoint.java:52)
        at io.vertx.core.http.impl.SharedClientHttpStreamEndpoint$Request.handle(SharedClientHttpStreamEndpoint.java:162)
        at io.vertx.core.http.impl.SharedClientHttpStreamEndpoint$Request.handle(SharedClientHttpStreamEndpoint.java:123)
        at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:55)
        at io.vertx.core.impl.ContextBase.emit(ContextBase.java:239)
        at io.vertx.core.net.impl.pool.SimpleConnectionPool$LeaseImpl.emit(SimpleConnectionPool.java:704)
        at io.vertx.core.net.impl.pool.SimpleConnectionPool$ConnectSuccess$2.run(SimpleConnectionPool.java:338)
        at io.vertx.core.net.impl.pool.CombinerExecutor.submit(CombinerExecutor.java:50)
        at io.vertx.core.net.impl.pool.SimpleConnectionPool.execute(SimpleConnectionPool.java:245)
        at io.vertx.core.net.impl.pool.SimpleConnectionPool.lambda$connect$2(SimpleConnectionPool.java:257)
        at io.vertx.core.http.impl.SharedClientHttpStreamEndpoint.lambda$connect$2(SharedClientHttpStreamEndpoint.java:102)
        at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
        at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
        at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
        at io.vertx.core.impl.future.Composition$1.onSuccess(Composition.java:62)
        at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
        at io.vertx.core.impl.future.FutureImpl.addListener(FutureImpl.java:196)
        at io.vertx.core.impl.future.PromiseImpl.addListener(PromiseImpl.java:23)
        at io.vertx.core.impl.future.Composition.onSuccess(Composition.java:43)
        at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60)
        at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211)
        at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23)
        at io.vertx.core.Promise.complete(Promise.java:66)
        at io.vertx.core.net.impl.NetClientImpl.lambda$connected$8(NetClientImpl.java:311)
        at io.vertx.core.net.impl.VertxHandler.setConnection(VertxHandler.java:82)
        at io.vertx.core.net.impl.VertxHandler.handlerAdded(VertxHandler.java:88)
        at io.netty.channel.AbstractChannelHandlerContext.callHandlerAdded(AbstractChannelHandlerContext.java:1114)
        at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:609)
        at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:223)
        at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:195)
        at io.vertx.core.net.impl.NetClientImpl.connected(NetClientImpl.java:313)
        at io.vertx.core.net.impl.NetClientImpl.lambda$connectInternal2$2(NetClientImpl.java:271)
        at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:264)
        at io.vertx.core.net.impl.ChannelProvider.connected(ChannelProvider.java:175)
        at io.vertx.core.net.impl.ChannelProvider.lambda$handleConnect$0(ChannelProvider.java:158)
        at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:590)
        at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:583)
        at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:559)
        at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:492)
        at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:636)
        at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:625)
        at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:105)
        at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84)
        at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:300)
        at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:335)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:776)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
        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)

How to Reproduce?

Reproducer:
rrc-no-entity-npe.zip

  1. mvn quarkus:dev
  2. Open http://localhost:8080/hello in a browser
  3. NPE is thrown

Output of uname -a or ver

MINGW64_NT-10.0-19044 NANBCHL9NG3 3.3.6-341.x86_64 2022-09-05 20:28 UTC x86_64 Msys

Output of java -version

openjdk 17.0.4 2022-07-19 OpenJDK Runtime Environment Temurin-17.0.4+8 (build 17.0.4+8) OpenJDK 64-Bit Server VM Temurin-17.0.4+8 (build 17.0.4+8, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.16.5.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537) Maven home: C:\eclipse\tools\java\maven Java version: 17.0.4, vendor: Eclipse Adoptium, runtime: C:\eclipse\tools\java\17 Default locale: de_DE, platform encoding: Cp1252 OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

Additional information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions