Get rid of org.jboss.weld.context.NonexistentConversationException when a query string parameter named cid is appended to the url
Take a simple CDI (it can also be a JSF managed bean) bean like this.
import java.io.Serializable;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
@Named
@ViewScoped
public class TestManagedBean implements Serializable
{
private static final long serialVersionUID=1L;
public TestManagedBean() {}
}
If this bean is available in an XHTML page with a named query string parameter cid
that is required for a @ConversationScoped
managed CDI bean (which may have been accidentally / intentionally added by end users), an exception similar to the following is thrown:
Severe: Error Rendering View[/Test.xhtml]
org.jboss.weld.context.NonexistentConversationException: WELD-000321: No conversation found to restore for id 1
at org.jboss.weld.context.AbstractConversationContext.initialize(AbstractConversationContext.java:259)
at org.jboss.weld.context.http.LazyHttpConversationContextImpl.initialize(LazyHttpConversationContextImpl.java:68)
at org.jboss.weld.context.http.LazyHttpConversationContextImpl.checkContextInitialized(LazyHttpConversationContextImpl.java:93)
at org.jboss.weld.context.AbstractConversationContext.getCurrentConversation(AbstractConversationContext.java:445)
at org.jboss.weld.jsf.ConversationAwareViewHandler.getActionURL(ConversationAwareViewHandler.java:111)
at com.sun.faces.renderkit.html_basic.FormRenderer.getActionStr(FormRenderer.java:250)
at com.sun.faces.renderkit.html_basic.FormRenderer.encodeBegin(FormRenderer.java:143)
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:864)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1854)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:456)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
Warning: StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
org.jboss.weld.context.NonexistentConversationException: WELD-000321: No conversation found to restore for id 1
at org.jboss.weld.context.AbstractConversationContext.initialize(AbstractConversationContext.java:259)
at org.jboss.weld.context.http.LazyHttpConversationContextImpl.initialize(LazyHttpConversationContextImpl.java:68)
at org.jboss.weld.context.http.LazyHttpConversationContextImpl.checkContextInitialized(LazyHttpConversationContextImpl.java:93)
at org.jboss.weld.context.AbstractConversationContext.getCurrentConversation(AbstractConversationContext.java:445)
at org.jboss.weld.jsf.ConversationAwareViewHandler.getActionURL(ConversationAwareViewHandler.java:111)
at com.sun.faces.renderkit.html_basic.FormRenderer.getActionStr(FormRenderer.java:250)
at com.sun.faces.renderkit.html_basic.FormRenderer.encodeBegin(FormRenderer.java:143)
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:864)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1854)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:456)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
Can this exception be thrown altogether, even if a named parameter is added to the URL cid
?
source to share
This is Weld specific (implementation), not CDI (API). There, in the current version of Weld 2.2.x, there is no easy and common way to disable it. However, Weld allows you to change the query parameter name cid
to something else via HttpConversationContext#setParameterName()
. You can install it for example. java.util.UUID
when starting the application.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ApplicationScoped;
import org.jboss.weld.context.http.HttpConversationContext;
@ManagedBean(eager=true)
@ApplicationScoped
public class Application {
@Inject
private HttpConversationContext conversationContext;
@PostConstruct
public void init() {
hideConversationScope();
}
/**
* "Hide" conversation scope by replacing its default "cid" parameter name
* by something unpredictable.
*/
private void hideConversationScope() {
conversationContext.setParameterName(UUID.randomUUID().toString());
}
}
Unfortunately, CDI has no equivalent for eager=true
. Alternative, if you have an EJB in your hands:
import javax.ejb.Startup;
import javax.ejb.Singleton;
@Startup
@Singleton
public class Application {
(you can add @TransactionAttribute(NOT_SUPPORTED)
to disable unnecessary DB transaction management around it)
Or, if you have OmniFaces in your hands:
import org.omnifaces.cdi.Startup;
@Startup
public class Application {
source to share
There is a race condition in the context of AbstractConversationContext when the first conversation scope is created if this is the first request of a single session. Suppose a scenario like this
- User requests jsf page
- Welding creates a conversation map in AbstractConversationContext.associate ()
- Since this is the first request, there is no session. Weld keep this card in request
- A search scope bean is created and placed on the map.
- Where the session was created
- During the render phase, the server sends a partial response back. The page needs some jsf resource like jsf2 ajax or jsf resource
- Browser requests new jsf resource
- At this time, the first request has not yet completed. Therefore it does not reach disociate () and does not put the talk map into the session.
- Meanwhile, the second request reaches associate (). No session dialog and session. This puts its new card on! <====
- Then even the first request reaches dissociate (), because there is already a card, it no longer puts its owner. <====
A quick and dirty fix is ββalways creating a session before post (). However, it's better to concatenate the map in discociate ()
Please look:
source to share
In the case of a servlet or other context that supports the web.xml context parameter, you can set WELD_CONTEXT_ID_KEY as currently noted in the latest welding documentation for supported environments :
<context-param>
<param-name>WELD_CONTEXT_ID_KEY</param-name>
<param-value>customValue</param-value>
</context-param>
source to share