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 and CodiNavigationHandler
is instanciated.
The method CodiNavigationHandler.isAddViewConfigsAsNavigationCaseActivated()
is called in the constructor and tries to get a reference on CODI JsfModuleConfig
. This JsfModuleConfig
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 the LibertyContextsService.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.