jsfprimefacesglassfishosgiwab

JSF web app as OSGi bundle - getting error FacesContextFactory was not configured properly


I'm trying to convert my JSF app into a OSGi Bundle (WAB), but I kept getting the error below when I deploy the war file to glassfish/autodeploy/bundles, which I'm not really sure what it means.

[#|2016-09-06T11:35:05.402+0200|SEVERE|glassfish3.1.2|org.apache.catalina.core.ContainerBase|_ThreadID=61;_ThreadName=pool-5-thread-1;|ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: java.lang.RuntimeException: com.sun.faces.config.ConfigurationException: Factory 'javax.faces.context.FacesContextFactory' was not configured properly.
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:5389)
        at com.sun.enterprise.web.WebModule.start(WebModule.java:498)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:901)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:733)
        at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2018)
        at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1669)
        at com.sun.enterprise.web.WebApplication.start(WebApplication.java:109)
        at org.glassfish.internal.data.EngineRef.start(EngineRef.java:130)
        at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269)
        at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:301)
        at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:461)
        at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
        at org.glassfish.osgijavaeebase.OSGiDeploymentRequest.deploy(OSGiDeploymentRequest.java:183)
        at org.glassfish.osgijavaeebase.OSGiDeploymentRequest.execute(OSGiDeploymentRequest.java:118)
        at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.deploy(AbstractOSGiDeployer.java:121)
        at org.glassfish.osgijavaeebase.OSGiContainer.deploy(OSGiContainer.java:154)
        at org.glassfish.osgijavaeebase.JavaEEExtender.deploy(JavaEEExtender.java:107)
        at org.glassfish.osgijavaeebase.JavaEEExtender.access$200(JavaEEExtender.java:61)
        at org.glassfish.osgijavaeebase.JavaEEExtender$HybridBundleTrackerCustomizer$1.call(JavaEEExtender.java:151)
        at org.glassfish.osgijavaeebase.JavaEEExtender$HybridBundleTrackerCustomizer$1.call(JavaEEExtender.java:148)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: com.sun.faces.config.ConfigurationException: Factory 'javax.faces.context.FacesContextFactory' was not configured properly.
        at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:292)
        at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:4750)
        at com.sun.enterprise.web.WebModule.contextListenerStart(WebModule.java:550)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:5366)
        ... 24 more
Caused by: com.sun.faces.config.ConfigurationException: Factory 'javax.faces.context.FacesContextFactory' was not configured properly.
        at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:305)
        at com.sun.faces.config.processor.FactoryConfigProcessor.process(FactoryConfigProcessor.java:219)
        at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:360)
        at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:225)
        ... 27 more
Caused by: javax.faces.FacesException: com.sun.faces.context.InjectionFacesContextFactory
        at javax.faces.FactoryFinder.getImplGivenPreviousImpl(FactoryFinder.java:630)
        at javax.faces.FactoryFinder.getImplementationInstance(FactoryFinder.java:509)
        at javax.faces.FactoryFinder.access$400(FactoryFinder.java:139)
        at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:993)
        at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:343)
        at com.sun.faces.config.processor.FactoryConfigProcessor.verifyFactoriesExist(FactoryConfigProcessor.java:303)
        ... 30 more
Caused by: java.lang.IllegalArgumentException: argument type mismatch
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
        at javax.faces.FactoryFinder.getImplGivenPreviousImpl(FactoryFinder.java:623)
        ... 35 more
|#]

The structure of my war file is as follows:

testWab.war
 |
 - img/
 - META-INF/
    |
    - MANIFEST.MF
 - WEB-INF/
    |
    - classes/
    |
    - lib/
       |
       - primefaces-5.3.jar
       |
       - javax.servlet.jsp-api-2.2.1.jar
       |
       - and other jar files 
    |
    - web.xml
    |
    - faces-config.xml
    |
    - web.xml
    |
    - glassfish-web.xml
 - views/
    |
    - all *.xhtml

My web.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Production</param-value>
    </context-param>
    <context-param>
        <param-name>primefaces.FONT_AWESOME</param-name>
        <param-value>true</param-value>
    </context-param>

    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>

    <!-- Servlet Config -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
</web-app>

And my glassfish-web.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
    <context-root>/testWAB</context-root>
    <class-loader delegate="false"/>
    <property name="useBundledJsf" value="true"/>
</glassfish-web-app>

My MANIFEST.MF is like this:

Manifest-Verion: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: TestWAB
Bundle-Version: 0.1.0.SNAPSHOT
Bundle-Name: Simulation Vis
Import-Package: javax.servlet,
 javax.servlet.http,
 javax.ws.rs,
 javax.ws.rs.core,
 org.osgi.framework;version="1.3.0"
Bundle-ClassPath: WEB-INF/classes,
 WEB-INF/lib/commons-fileupload-1.3.jar,
 WEB-INF/lib/commons-io-2.2.jar,
 WEB-INF/lib/el-api-2.2.jar,
 WEB-INF/lib/el-impl-2.2.jar,
 WEB-INF/lib/javax.faces-api-2.2.jar,
 WEB-INF/lib/javax.servlet.jsp-api-2.2.1.jar,
 WEB-INF/lib/javax.servlet-api-3.1.0.jar,
 WEB-INF/lib/primefaces-5.3.jar
Web-ContextPath: /testWAB
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-Activator: test.Activator
Require-Bundle: myBundle0;bundle-version="0.1.0";visibility:=reexport,
 myBundle1;bundle-version="0.1.0";visibility:=reexport,
 myBundle2;bundle-version="0.1.0"
Bundle-Vendor: FooBar

Solution

  • OK. So after a lot of hair pulling and keyboard banging, I finally got these frameworks to work together.

    Here's for your reference.


    Framework version:


    1. The Primefaces jar should NOT be in your WAR's WEB-INF/lib folder. It should be deployed as an OSGi Bundle. This is as simple as dropping the jar into glassfish/autodeploy/bundles directory.

    2. Copy the following resource files and directory from the Primefaces jar's META-INF into your web bundle: primefaces-p.taglib.xml, faces-config.xml and resources.

    My bundle already has its own faces-config.xml, so I renamed the one from Primefaces primefaces-config.xml, and put it under my bundle's WEB-INF. Then I added the following to my web.xml to use both files:

    <context-param>
      <param-name>javax.faces.CONFIG_FILES</param-name>
      <param-value>
          /WEB-INF/faces-config.xml,
          /WEB-INF/primefaces-config.xml
      </param-value>
    </context-param>
    
    1. In the end, my WAB has the following structure:

      testWab.war

      • img/
      • resources/ (from Primefaces jar)
      • META-INF/

        • MANIFEST.MF

        • primefaces-p.taglib.xml (from Primefaces jar)

      • WEB-INF/

        • classes/

        • lib/

          • some jar files EXCLUDE primefaces jar
        • web.xml

        • faces-config.xml

        • primefaces-config.xml

        • web.xml

        • glassfish-web.xml

      • views/

        • all *.xhtml

    The glitches?

    1. Your Primefaces version may not like the jsf version that comes with Glassfish. I suggest you resist the urge to include your own jsf jar and tell Glassfish to useBundledJsf. I tried. Wasted countless hours, and nothing worked.

    Ideally, you can upgrade your frameworks to whatever version so that they work well together, but in my case, was not allowed to so here's what I did.

    I have Glassfish 3.1.2 which comes with JSF 2.1, which doesn't work with Primefaces 5.3. I replaced the original glassfish\modules\javax.faces.jar with my javax.faces-2.2.jar.

    My glassfish-web.xml looks like this:

    <glassfish-web-app error-url="">
        <context-root>/testWAB</context-root>
        <class-loader delegate="true" />
    </glassfish-web-app>
    
    1. Your WAB suddenly couldn't find any of the Java faces classes.

    Make sure bundle classpath is correct and javax.faces.* are listed under Import-Package.

    My MANIFEST.MF looks like this:

    Manifest-Verion: 1.0
    Bundle-ManifestVersion: 2
    Bundle-SymbolicName: testWAB
    Bundle-Version: 0.1.0.SNAPSHOT
    Bundle-Name: Simulation Vis
    Import-Package: javax.faces;version="2.2.0",
     javax.faces.application;version="2.2.0",
     javax.faces.bean,
     javax.faces.component;version="2.2.0",
     javax.faces.context;version="2.2.0",
     javax.faces.event;version="2.2.0",
     javax.servlet,
     javax.servlet.http,
     javax.ws.rs,
     javax.ws.rs.core,
     org.osgi.framework;version="1.3.0"
    Bundle-ClassPath: WEB-INF/classes,
     WEB-INF/lib/jar1.jar,
     WEB-INF/lib/jar2.jar
    Web-ContextPath: /testWAB
    Bundle-RequiredExecutionEnvironment: JavaSE-1.7
    Bundle-Activator: test.Activator
    Require-Bundle: myBundle1;bundle-version="0.1.0";visibility:=reexport,
     myBundle1;bundle-version="0.1.0";visibility:=reexport,
     org.primefaces;bundle-version="5.3.0"
    Bundle-Vendor: Me