Topic
  • 3 replies
  • Latest Post - ‏2013-11-04T10:53:26Z by domak
domak
domak
3 Posts

Pinned topic CODI with ejb stateless on Websphere liberty profile 8.5.5

‏2013-10-31T14:36:11Z |

I've already post this question on stackoverflow: http://stackoverflow.com/questions/19709201/codi-with-ejb-stateless-on-websphere-liberty-profile-8-5-5

I cannot launch a webapp that embedd CODI on websphere liberty profile 8.5.5 if the webapp contains a @Stateless ejb.

I get this exception:


[ERROR   ] null
java.lang.reflect.InvocationTargetException
[ERROR   ] An error occured while initializing MyFaces: java.lang.reflect.InvocationTargetException
java.lang.reflect.InvocationTargetException
[ERROR   ] Uncaught.init.exception.thrown.by.servlet 
    Faces Servlet
    codiTest
    javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
    at org.apache.webbeans.container.BeanManagerImpl.getContext(BeanManagerImpl.java:342)
    at [internal classes]
    at org.apache.myfaces.extensions.cdi.core.api.config.CodiCoreConfig_$$_javassist_78.isAdvancedQualifierRequiredForDependencyInjection(CodiCoreConfig_$$_javassist_78.java)
    at org.apache.myfaces.extensions.cdi.jsf.impl.listener.phase.PhaseListenerExtension.consumePhaseListeners(PhaseListenerExtension.java:110)
    at org.apache.myfaces.extensions.cdi.jsf2.impl.listener.phase.CodiLifecycleFactoryWrapper.getLifecycle(CodiLifecycleFactoryWrapper.java:67)
    at javax.faces.webapp.FacesServlet.init(FacesServlet.java:119)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:322)
    at [internal classes]

[ERROR   ] SRVE0266E: Error occured while initializing servlets: javax.servlet.ServletException: SRVE0207E: Uncaught initialization exception created by servlet
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:385)
    at [internal classes]
Caused by: javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread
    at org.apache.webbeans.container.BeanManagerImpl.getContext(BeanManagerImpl.java:342)
    at [internal classes]
    at org.apache.myfaces.extensions.cdi.core.api.config.CodiCoreConfig_$$_javassist_78.isAdvancedQualifierRequiredForDependencyInjection(CodiCoreConfig_$$_javassist_78.java)
    at org.apache.myfaces.extensions.cdi.jsf.impl.listener.phase.PhaseListenerExtension.consumePhaseListeners(PhaseListenerExtension.java:110)
    at org.apache.myfaces.extensions.cdi.jsf2.impl.listener.phase.CodiLifecycleFactoryWrapper.getLifecycle(CodiLifecycleFactoryWrapper.java:67)
    at javax.faces.webapp.FacesServlet.init(FacesServlet.java:119)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:322)
    ... 1 more

[WARNING ] Unknown RenderKit 'HTML_BASIC'.
[WARNING ] Unknown RenderKit 'HTML_BASIC'.
[ERROR   ] An exception occurred
java.lang.IllegalArgumentException: Could not find a RenderKit for "HTML_BASIC"

I've constated that the problem occurs only if an ejb is present in the project (in my case a @Stateless ejb).

In this case, the application context is initialized when the server is started and the webapp installed/deployed. No problem here.

When the first HTTP request is handled by the webapp, the FacesServlet is initialized andCodiNavigationHandler is instanciated.

The method CodiNavigationHandler.isAddViewConfigsAsNavigationCaseActivated() is called in the constructor and tries to get a reference on CODI JsfModuleConfig. ThisJsfModuleConfig has an @ApplicationScoped annotation and the the beanManager tries to get the application context.

This application context has already been created (when the webapp is deployed) but theLibertyContextsService.initApplicationContext(String)has not been called yet. So the application context is null on the LibertyContextsService.applicationContexts ThreadLocal variable and the error occurs:


WebBeans context with scope type annotation @ApplicationScoped does not exist within current thread

To reproduce:

  • create a Dynamic Web Project
  • add an almost empty beans.xml under WEB-INF (just a beans element)
  • add an almost empty faces-config.xml under WEB-INF (just a faces-config element)
  • add a web.xml with a faces/index.xhtml
  • copy codi jars in WEB-INF/lib (http://www.apache.org/dyn/closer.cgi/myfaces/binaries/myfaces-extcdi-assembly-jsf20-1.0.5-bin.zip)
  • add a stateless bean:

    
    import javax.annotation.PostConstruct;
    import javax.ejb.Stateless;
    
    @Stateless
    public class MyBean {
    
        @PostConstruct
        public void postConstruct() {
            System.out.println("post construct: " + this);
        }
    
        public String getTitle() {
            return "test";
        }
    }
    
    
  • add a jsf bean:

    
    import javax.inject.Inject;
    import javax.inject.Named;
    
    @Named
    public class MyController {
    
        @Inject
        private MyBean myBean;
    
        public String getTitle() {
            return myBean.getTitle();
        }
    }
    
    
  • add a simple jsf web page with:

    
    <h:body>
        <h:outputText>${myController.title}</h:outputText>
    </h:body>
    
    

nota: if you remove the @stateless on the ejb, the application works.

  • bergmark
    bergmark
    42 Posts

    Re: CODI with ejb stateless on Websphere liberty profile 8.5.5

    ‏2013-10-31T15:24:02Z  

    This appears to be a bug, and I would encourage you to open a PMR so we can investigate and fix it.

    Do you see any other errors in the logs during application start?

    If not, my suspicion is that introducing the EJB causes the CDI lifecycle to be started earlier, and it was the lifecycle startup that was previously enabling the @ApplicationScope on the thread that is running the FacesServlet initialization.

     

  • domak
    domak
    3 Posts

    Re: CODI with ejb stateless on Websphere liberty profile 8.5.5

    ‏2013-10-31T15:40:52Z  
    • bergmark
    • ‏2013-10-31T15:24:02Z

    This appears to be a bug, and I would encourage you to open a PMR so we can investigate and fix it.

    Do you see any other errors in the logs during application start?

    If not, my suspicion is that introducing the EJB causes the CDI lifecycle to be started earlier, and it was the lifecycle startup that was previously enabling the @ApplicationScope on the thread that is running the FacesServlet initialization.

     

    Yes, the lifecycle is different if I remove @Stateless from my ejb. In this case the application context is initialized when the FacesServlet is initialized.

    With @Stateless the application context is effectively started earlier, when the scanner looks for ejb.
    So, when the FacesServlet is started (on the first http request), the application context is present in the map of contexts (LibertyContextsService.currentApplicationContexts) but has not yet set on applicationContexts thread local.

    I also can see that it the application context is set after, when the http handler is trying to start the request context (the request context sets the application context in LibertyContextsService.initRequestContext()). But it is to late because the FacesServlet failed to init and the rendering cannot be done.

    Can I open a PMR with my account? I know that some people in my (too big) company can do it but it is a complex processing...

  • domak
    domak
    3 Posts

    Re: CODI with ejb stateless on Websphere liberty profile 8.5.5

    ‏2013-11-04T10:53:26Z  
    • domak
    • ‏2013-10-31T15:40:52Z

    Yes, the lifecycle is different if I remove @Stateless from my ejb. In this case the application context is initialized when the FacesServlet is initialized.

    With @Stateless the application context is effectively started earlier, when the scanner looks for ejb.
    So, when the FacesServlet is started (on the first http request), the application context is present in the map of contexts (LibertyContextsService.currentApplicationContexts) but has not yet set on applicationContexts thread local.

    I also can see that it the application context is set after, when the http handler is trying to start the request context (the request context sets the application context in LibertyContextsService.initRequestContext()). But it is to late because the FacesServlet failed to init and the rendering cannot be done.

    Can I open a PMR with my account? I know that some people in my (too big) company can do it but it is a complex processing...

    I can't open a PMR with my own account. I'm going to try to get an account from my company but it can take a long time. By the way, I tried the same test on jboss 6.1 EAP and it works well.