3

Take a simple CDI (it could also be a JSF managed bean) bean as follows.

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 accessed by an XHTML page with a query-string parameter named cid which is needed for a @ConversationScoped CDI managed bean (which may accidently/deliberately be appended by end-users too), an exception looking something like 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 avoided anyway even though a parameter named cid is appended to the URL?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Tiny
  • 27,221
  • 105
  • 339
  • 599

3 Answers3

4

This is specific to Weld (the implementation), not to CDI (the API). There's in the current Weld 2.2.x version no simple nor native way to disable it. Weld however allows you changing the request parameter name cid to something else via HttpConversationContext#setParameterName(). You could set it to e.g. an java.util.UUID value during application's startup.

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 doesn't have any equivalent for eager=true. Alternative is, if you've EJB at hands:

import javax.ejb.Startup;
import javax.ejb.Singleton;

@Startup
@Singleton
public class Application {

(you might want to add @TransactionAttribute(NOT_SUPPORTED) to turn off unnecessary DB transaction management around it)

Or, if you've OmniFaces at hands:

import org.omnifaces.cdi.Startup;

@Startup
public class Application {
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • This is working but the application scoped bean does not seem to be eagerly loaded unless it is explicitly referenced, for example, from an EL context like `#{application.someUnusedProperty}`. Unlike JSF managed beans, there does not seem to be an equivalent `Named(eager=true)` (as in JSF managed beans, `ManagedBean(eager=true)`). – Tiny Nov 04 '14 at 21:33
  • Now going well. Thanks :) – Tiny Nov 04 '14 at 21:41
  • I got a message on server log like `Severe: No valid EE environment for injection of org.omnifaces.cdi.eager.EagerBeansRepository` but I avoided it after looking into [this](http://stackoverflow.com/a/25741716/1391249) answer. – Tiny Nov 04 '14 at 21:56
  • This is not specific to Weld. CDI 1.2 spec 6.7.4. Conversation context lifecycle: `If the propagated conversation cannot be restored, the container must associate the request with a new transient conversation and throw an exception of type javax.enterprise.context.NonexistentConversationException.` – Vsevolod Golovanov Feb 24 '15 at 08:16
  • @Vsevolod: the behavior not but the request parameter is. – BalusC Feb 24 '15 at 08:20
  • @BalusC, still not sure, what you mean. CDI 1.2 also specifies `cid` as the conversation propagation request parameter. – Vsevolod Golovanov Feb 24 '15 at 09:26
0

There's a race condition in AbstractConversationContext when create first conversation scope if it's the first request of one session. Suppose such scenario

  1. User requests a jsf page
  2. weld creates a conversations map in the AbstractConversationContext.associate()
  3. Because it is the first request, there's no session. Weld keep this map in request
  4. A conversation scoped bean is created and put to the map.
  5. In somewhere, a session is created
  6. In the render phase, server sends partial response back. The page need some jsf resource, eg, jsf2 ajax or jsf resource
  7. Browser requests the new jsf resource
  8. At this time The first request has not finished. So it doesn't reach dissociate() and doesn't put conversations map in the session.
  9. Meanwhile The second request reach associate(). There's no conversations map in the session, and the session is existing. It puts its new map! <====
  10. Then, even the first request reach dissociate(), because there's already a map, it doesn't put its owner anymore. <====

A quick and dirty fix is always create session before associate(). However, it's better to merge the map in the dissociate()

Please see :

https://issues.jboss.org/browse/WELD-1418

WELD-1500 issue

Kamal SABBAR
  • 638
  • 5
  • 11
  • 1
    According to the links you posted, this cause of this (same) error was fixed in 2.1Beta1 and 2.1 has been released 3.5 years ago!!! Is it still a problem in newer releases? Then create a new weld issue and link to that! – Kukeltje Apr 11 '17 at 10:51
0

In the case of a servlet or other context supporting the web.xml context-param, you could set WELD_CONTEXT_ID_KEY as currently noted in the latest Weld documentation on supported environments:

<context-param>
   <param-name>WELD_CONTEXT_ID_KEY</param-name>
   <param-value>customValue</param-value>
</context-param>
jla
  • 6,904
  • 2
  • 36
  • 34