Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebSocket endpoint and CDI injection: No active contexts for scope RequestScoped

I want to inject a @RequestScoped CDI bean in my Java EE 7 WebSocket endpoint.

However I am getting error WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped.

What am I doing wrong and why it is not possible?

@Named
@RequestScoped
public class Storage {

}

Which I @Inject in the endpoint like this:

@ServerEndpoint("/serverpush")
public class ContratoEndpoint {

    @Inject
    private Storage storage;

}

And I am getting the following stack trace:

org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped
    at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:689)
    at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:90)
    at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:165)
    at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
    at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:125)
like image 531
Evandro Pomatti Avatar asked Sep 18 '25 01:09

Evandro Pomatti


2 Answers

As @John mentioned, RequestContext is not active in WebSocket methods. Instead of using Deltaspike (which is a good option), you can also write your own Interceptor to activate/deactivate weld RequestContext.

As you are using Wildfly, you can use weld as a provided dependency :

<dependency>
    <groupId>org.jboss.weld</groupId>
    <artifactId>weld-core</artifactId>
    <version>2.2.12.Final</version>
    <scope>provided</scope>
</dependency>

Then you can define an InterceptorBinding @RequestContextOperation :

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.interceptor.InterceptorBinding;

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

}

And the corresponding RequestContextInterceptor where we activate/deactivate the RequestContext:

import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

import org.jboss.weld.context.RequestContext;
import org.jboss.weld.context.unbound.Unbound;

@Interceptor
@RequestContextOperation
public class RequestContextInterceptor {

    /** The RequestContext */
    @Inject
    @Unbound
    private RequestContext m_requestContext;

    /**
     * 
     * @param p_invocationContext
     * @return
     * @throws Exception
     */
    @AroundInvoke
    public Object activateRequestContext(final InvocationContext p_invocationContext) throws Exception {
        try {
            m_requestContext.activate();
            return p_invocationContext.proceed();
        } finally {
            m_requestContext.invalidate();
            m_requestContext.deactivate();
        }
    }
}

You can then use the @RequestContextOperation annotation on your class or on a specific method :

@ServerEndpoint("/serverpush")
public class ContratoEndpoint {

    @Inject
    private Storage storage;

    @OnMessage
    @RequestContextOperation
    public String handleMessage(String message){

        // Here the @RequestScoped bean is valid thanks to the @RequestContextOperation InterceptorBinding
        storage.yourMethod();
        ....
    }

}
like image 106
Rouliboy Avatar answered Sep 20 '25 15:09

Rouliboy


WebSockets do not initialize a request scope context for their method invocations. You can use deltaspike context control to manually start a request context for the method invocation.

like image 33
John Ament Avatar answered Sep 20 '25 15:09

John Ament