Reputation: 15144
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)
Upvotes: 4
Views: 3081
Reputation: 406
Although Request Scope is not active in WebSockets (including Atmosphere) you can manually activate it using the approach proposed in a previous answer.
However, since CDI 2.0, you can use the @ActivateRequestContext
annotation (from javax.enterprise.context.control.ActivateRequestContext
) interceptor to do just that.
Either annotate the class or the method where you want to have Request Scope and this will activate it at the beginning of method execution and deactivate it when it finishes,
Upvotes: 0
Reputation: 1377
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();
....
}
}
Upvotes: 3
Reputation: 11723
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.
Upvotes: 2