javaquarkusinterceptorrequesthandlerrequestscope

Quarkus - ContextNotActiveException when injecting a request scoped bean in Interceptor


I've got a Quarkus application. The entry point to trigger this application is a class which implements AWS RequestHandler. Before it runs I would like to set the context depending on the given parameter fields. To store the context somewhere I created a requestScoped bean with a field that we set with a simple setter method.

To do this I thought of using Interceptors. In my interceptor class, I inject this request scoped bean.

When running the application it triggers the interceptor but I noticed I get an error while debugging.

Method threw 'javax.enterprise.context.ContextNotActiveException'. Cannot evaluate common.service.MyRequestScopedBean_ClientProxy.toString()

I've run this in another application where I trigger a rest endpoint instead. And don't have the same issue.

Quarkus platform version: 2.7.5.Final.

Why is ContextNotActiveException being thrown here, is there a way to fix this?

@Setter
@Getter
@RequestScoped
public class MyRequestScopedBean {

    private String context;
}

My InterceptorBinding annotation:

@InterceptorBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ContextBinding {
}

The ContextInterceptor class:

@Slf4j
@Interceptor
@ContextBinding
public class ContextInterceptor {

    @Inject
    MyRequestScopedBean myRequestScopedBean;

    @AroundInvoke
    public Object setContext(InvocationContext context) throws Exception {

        log.info("{}", context);

        myRequestScopedBean.setContext("Some context");

        return context.proceed();
    }
}

My handler class, with @AcitivateRequestContext:

@Slf4j
@ActivateRequestContext
@ContextBinding
@Named("Handler")
public class Handler implements RequestHandler<Event, Void> {

    @Override
    public Void handleRequest(Event event, Context context) {
        // some logic
    }
}

Solution

  • Your interceptor does not declare a @Priority. By specification, such interceptor should not be enabled, but Quarkus deviates from that and assigns a default priority of 0. You should even see this warning:

    The interceptor x.y.z.ContextInterceptor does not declare any @Priority.
    It will be assigned a default priority value of 0.
    

    The @ActivateRequestContext interceptor has, by specification, the priority of PLATFORM_BEFORE + 100.

    Combined, this means that your interceptor runs before the request context is activated. You should assign your interceptor a correct priority explicitly:

    @Interceptor
    @Priority(Interceptor.Priority.LIBRARY_BEFORE + 100)
    @ContextBinding
    public class ContextInterceptor {
        ...
    }
    

    I chose LIBRARY_BEFORE + 100 with little deliberation, but it seems likely to me that your interceptor priority should be in the "early interceptors defined by extension libraries" category, so LIBRARY_BEFORE + 100 should be a good start.