0

I'm trying to upgrade an old web app from JSF 2.1.1-FCS to 2.2.14 running in the Tomcat 8.5 Servlet 3.1 container.

The Mojarra JSF minimum requirements (for the latest version I guess, the page doesn't seem clear) says among other things that CDI 1.2 is required with 2.0 recommended.

I added cd-api-2.0 and weld-servlet-shaded-3.0.0.Final along with the other dependencies. Things seem to work until I test some URLs we've been using a long time. Our application has been using a cid parameter. Weld uses the same parameter to track conversations. As a result we get the WELD-000321: No conversation found to restore for id error.

I would like to call the org.jboss.weld.context.http.HttpConversationContext.setParameterName(String cid) as early as possible to modify the value for this web application.

What is the best way to change this value in a Servlet 3.1 Container Context like the one provided by Tomcat 8.5?

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
jla
  • 6,904
  • 2
  • 36
  • 34
  • Do you call that method 'manually' from your source code? Did you migrate to CDI annotations? – Selaron May 17 '19 at 07:43
  • You can configure the weld parameter iirc – Kukeltje May 17 '19 at 12:43
  • @Selaron, I did try to inject an HttpConversationContext to call setParameterName on from a couple different places, similar to what is shown in this answer: https://stackoverflow.com/a/26744986/101151, but it didn't seem to be getting injected. I'm not sure when the right time to hook into it is. In the servlet seems too late. – jla May 20 '19 at 14:55
  • @Kukeltje I went back and looked again for the parameter at your suggestion. It looks like it is WELD_CONTEXT_ID_KEY. Works great, thank you! I don't know if I missed it because I was looking too hard for org.jboss.weld... or if because the way they describe it in Environments didn't match my use case and error. The bug report WELD-1697 did. – jla May 20 '19 at 19:54
  • Cool, please create an answer if you cannot find a duplicate in stackoverflow. – Kukeltje May 20 '19 at 19:58

1 Answers1

1

Initialize WELD_CONTEXT_ID_KEY in web.xml

Using the web.xml context-param WELD_CONTEXT_ID_KEY allowed me to override the Weld CDI conversation parameter key name from cid to a value of my choosing so I could preserve the legacy usage of cid in my upgraded application and avoid the WELD-000321 error.

<context-param>
    <param-name>WELD_CONTEXT_ID_KEY</param-name>
    <param-value>customValue</param-value>
</context-param>

This was the simplest solution, but I didn't make the association between that context parameter name and the conversation parameter key or error WELD-000321 when first reading the Weld documentation.

Or set programmatically

I was also able to override the parameter name / context id key programmatically from a custom ServletContextListener.contextInitialized method based on the SO example for getting rid of the NonexistentConversationException. Since I'm on Tomcat 8.5 (Servlet 3.1) I was able to use either @WebListener or the listener element in web.xml. It didn't seem to matter if my web.xml web-app version was the old 2.5 or if I updated it to 3.1.

package ssce;

import java.util.UUID;
import javax.inject.Inject;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.jboss.weld.context.http.HttpConversationContext;

@WebListener
public class MyServletContextListener implements ServletContextListener {

    @Inject
    private HttpConversationContext conversationContext;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        hideConversationScope();
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {

    }


    /**
     * "Hide" conversation scope by replacing its default "cid" parameter name
     * by something unpredictable.
     */
    private void hideConversationScope() {
        conversationContext.setParameterName(UUID.randomUUID().toString());
    }

}
jla
  • 6,904
  • 2
  • 36
  • 34