question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unpredictable reactive controller behavior.

See original GitHub issue

Describe the bug

I decided to refactor one of my service written in quarkus from blocking io to reactive manner.

I have many mock controller which works perfectly before refactor but now some of them throws errors:

java.lang.NullPointerException: Cannot invoke "org.jboss.resteasy.reactive.server.mapping.RuntimeResource.getResourceClass()" because the return value of "org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext.getTarget()" is null
	at org.jboss.resteasy.reactive.server.core.ExceptionMapping.logBlockingErrorIfRequired(ExceptionMapping.java:103)
	at org.jboss.resteasy.reactive.server.core.ExceptionMapping.mapException(ExceptionMapping.java:95)
	at org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext.mapExceptionIfPresent(ResteasyReactiveRequestContext.java:340)
	at org.jboss.resteasy.reactive.server.handlers.ExceptionHandler.handle(ExceptionHandler.java:15)
	at org.jboss.resteasy.reactive.server.handlers.ExceptionHandler.handle(ExceptionHandler.java:9)
	at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:141)
	at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:47)
	at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:17)
	at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:7)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1127)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:151)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:133)
	at io.quarkus.vertx.http.runtime.StaticResourcesRecorder.lambda$start$1(StaticResourcesRecorder.java:67)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1127)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:151)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:133)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:351)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:329)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1127)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:151)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:133)
	at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:55)
	at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:37)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$10.handle(VertxHttpRecorder.java:443)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$10.handle(VertxHttpRecorder.java:440)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$1.handle(VertxHttpRecorder.java:151)
	at io.quarkus.vertx.http.runtime.VertxHttpRecorder$1.handle(VertxHttpRecorder.java:133)
	at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:67)
	at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:30)
	at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:50)
	at io.vertx.core.impl.DuplicatedContext.emit(DuplicatedContext.java:168)
	at io.vertx.core.http.impl.Http1xServerConnection.handleMessage(Http1xServerConnection.java:143)
	at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:155)
	at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:154)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
	at io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.channelRead(WebSocketServerExtensionHandler.java:99)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.vertx.core.http.impl.Http1xUpgradeToH2CHandler.channelRead(Http1xUpgradeToH2CHandler.java:116)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:311)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:432)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.vertx.core.http.impl.Http1xOrH2CHandler.end(Http1xOrH2CHandler.java:61)
	at io.vertx.core.http.impl.Http1xOrH2CHandler.channelRead(Http1xOrH2CHandler.java:38)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:795)
	at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:480)
	at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
	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:831)

For example this controller doesn’t work:

package pl.test.rest.recaptcha;

import io.smallrye.mutiny.Uni;
import pl.test.rest.recaptcha.model.SiteVerifyResponse;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.Date;

@Path("/recaptcha/api/siteverify")
public class MockResource {
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Uni<SiteVerifyResponse> siteVerify(@FormParam("response") String response
            , @FormParam("secret") String secret, @FormParam("remoteip") String remoteip) {
        return Uni.createFrom().item(SiteVerifyResponse.builder()
                .success(true)
                .score((float) 1.0)
                .action("ACTION")
                .hostname("localhost")
                .challengeTs(new Date())
                .build());
    }
}

But this work’s:

package pl.test.rest.dotpay;

import io.smallrye.mutiny.Uni;
import lombok.val;
import pl.test.rest.dotpay.model.PaymentEntry;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.Collections;
import java.util.List;

@Path("/s2/login/api/purchase_history/")
public class MockResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Uni<List<PaymentEntry>> api(@QueryParam("email") String email) {
        return Uni.createFrom().item(Collections.singletonList(createPaymentEntry()));
    }

    private PaymentEntry createPaymentEntry() {
        val entry = new PaymentEntry();
        entry.setDate("2018-06-09T16:54:15.855823");
        entry.setAmount("8.29");
        entry.setCurrency("PLN");
        entry.setStatus("completed");
        entry.setRequestIp("188.146.162.128");
        entry.setMcc("4112");
        entry.setChannel("73");
        entry.setMerchantId("5d51e2dc7bc76cf9841d82ba404d134646bdbd97");

        return entry;
    }
}

The one thing what I’am done in refactor is change the return type to new one with wrapper Uni.

I found on network similar error: https://github.com/quarkusio/quarkus/runs/3204982867

Expected behavior

No response

Actual behavior

No response

How to Reproduce?

No response

Output of uname -a or ver

Linux 5.13.0-20-generic #20-Ubuntu SMP Fri Oct 15 14:21:35 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

16.0.2

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.4.0.Final

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

Apache Maven 3.6.2

Additional information

No response

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
kazik666commented, Nov 1, 2021

Ok I’am closing this issue.

1reaction
geoandcommented, Nov 1, 2021

If you are trying to read the entire body of the request on the event loop thread, then yes, that is still not allowed

Read more comments on GitHub >

github_iconTop Results From Across the Web

Reactive Behaviors in Dogs - Symptoms, Causes, Diagnosis ...
Dogs that overreact in response to certain stimuli are known as reactive. Most reactive dogs can become somewhat calmer and happier animals with...
Read more >
How to turn your child's reactive, inflexible behavior around
Parenting a child who gets reactive, constantly disagrees, and pushes back gets exhausting. This strategy shows you how to meet them calmly.
Read more >
Reforming a Reactive Dog - Whole Dog Journal
Dogs are called leash-reactive when the frustration caused by a restrictive leash overwhelms them (see Feisty Fido by Patricia McConnell).
Read more >
6 Ways to Calm Your Reactive Dog - Wags & Wiggles
Reactivity is when a dog over reacts to things in their environment. These reactions can include: barking, lunging, and growling.
Read more >
A Beginner's Guide to Helping Your Reactive Dog Get Better
Aversives work to suppress behavior, but do nothing to change the underlying problem that caused the behavior. In fact, the dog may become...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found