tomcatjsf-2richfacesjsf-2.2myfaces

Deploying RichFaces 3.3.3 to Tomcat having MyFaces 2.2, PrimeFaces, OmniFaces etc


I have the following configuration ( don't get scared by the stack traces :) )

Tomcat 7.0.53 + All our jars - including MyFaces 2.2.3 / Omnifaces / PrimeFaces / etc...) are located apart of the web apps (not inside web-inf\lib , but inside the other path Tomcat\someName\lib... and are referenced from catalina.properties file with the common.loader) this setup serves all our webapps just fine, except one legacy webapp that is using RichFaces 3.3.3 - RichFaces jars are in that specific webapp lib folder, (which worked just fine while we were using MyFaces 2.0.11) but now after switching to the MyFaces 2.2.3 I'm getting the following exception

java.lang.NoClassDefFoundError: com/sun/facelets/tag/jsf/ComponentHandler at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)

...

Caused by: java.lang.ClassNotFoundException: com.sun.facelets.tag.jsf.ComponentHandler at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571) at org.apache.tomee.catalina.LazyStopWebappClassLoader.loadClass(LazyStopWebappClassLoader.java:143) ... 64 more

And it seems because of facelets packages changes between 2.0 and 2.2

So I tried dropping jsf-facelets-1.1.14.jar to that webapp lib folder and got the following exception

javax.faces.FacesException: Cannot instantiate TagLibrary at org.apache.myfaces.view.facelets.compiler.TagLibraryConfig.create(TagLibraryConfig.java:424) at org.apache.myfaces.view.facelets.compiler.FaceletsCompilerSupport.loadLibraries(FaceletsCompilerSupport.java:157) at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.loadLibraries(FaceletViewDeclarationLanguage.java:2520)

...

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.Exception: com.sun.facelets.tag.jsf.core.CoreLibrary must be an instance of org.apache.myfaces.view.facelets.tag.TagLibrary at org.apache.myfaces.view.facelets.compiler.TagLibraryConfig.createClass(TagLibraryConfig.java:542) at org.apache.myfaces.view.facelets.compiler.TagLibraryConfig.create(TagLibraryConfig.java:419) ... 50 more

So now I tried to drop the myfaces-impl-2.0.11 and myfaces-api-2.0.11 to that webapp lib folder , but now the webapp insn't even being deployed by Tomcat and throwing exception regarding OmniFaces (which is not even used by that webapp and not mentioned anywhere there)

[2014-08-28 09:36:12,645 IDT] E 000001b4 (org.apache.myfaces.webapp.AbstractFacesInitializer#initFaces) An error occured while initializing MyFaces: Class org.omnifaces.application.OmniApplicationFactory is no javax.faces.application.ApplicationFactory java.lang.IllegalArgumentException: Class org.omnifaces.application.OmniApplicationFactory is no javax.faces.application.ApplicationFactory at javax.faces.FactoryFinder.newFactoryInstance(FactoryFinder.java:320) at javax.faces.FactoryFinder._getFactory(FactoryFinder.java:286) at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:191) at org.apache.myfaces.config.FacesConfigurator.configureApplication(FacesConfigurator.java:500) at org.apache.myfaces.config.FacesConfigurator.configure(FacesConfigurator.java:411) at org.apache.myfaces.webapp.AbstractFacesInitializer.buildConfiguration(AbstractFacesInitializer.java:337) at org.apache.myfaces.webapp.Jsp21FacesInitializer.initContainerIntegration(Jsp21FacesInitializer.java:73) at org.apache.myfaces.webapp.AbstractFacesInitializer.initFaces(AbstractFacesInitializer.java:140) at org.apache.myfaces.webapp.StartupServletContextListener.contextInitialized(StartupServletContextListener.java:111) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1073) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 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)

I thought that it is possible to mix two different JSF versions (but I might be wrong) and maybe there is a better solution to make that Richfaces 3.3.3 work with JSF 2.2.3

Any Ideas?


Solution

  • RichFaces 3.x is not compatible with JSF 2.2. Tomcat does not support isolated JSF class loading such as JBoss with org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL context param in web.xml, GlassFish with <property name="useBundledJsf" value="true" /> in glassfish-web.xml, etc. So even when you supply another JSF version via the webapp, Tomcat keeps loading its own. This just can't work.

    You've basically 3 options:

    1. Deploy that RichFaces 3.x webapp on a separate Tomcat instance without those common libs.

    2. Move those common libs from Tomcat back in those other webapps, so each webapp gets its own.

    3. Upgrade to RichFaces 4.x. Been there, done that, they've a quite good migration guide.