eclipse-ee4j / mojarra

Mojarra, a Jakarta Faces implementation
Other
159 stars 109 forks source link

Error: mojarra 4 installation on Tomcat 10.1.8 and jdk 17.0.6 #5232

Closed vtrance closed 11 months ago

vtrance commented 1 year ago

A war deployment of a hello world project with mojarra 4 on Tomcat 10.1.8 and jdk 17.0.6 failed with an error:

SEVERE [Catalina-utility-2] com.sun.faces.config.ConfigureListener.contextInitialized Critical error during deployment: com.sun.faces.config.ConfigurationException: CONFIGURATION FAILED! Cannot invoke "jakarta.faces.application.ResourceHandler.createViewResource(jakarta.faces.context.FacesContext, String)" because "this.resourceHandler" is null at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:319) at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:179) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4451) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4885) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:713) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:975) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1949) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123) at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:776) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:426) at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1705) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:305) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1102) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1301) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1305) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1283) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.lang.NullPointerException: Cannot invoke "jakarta.faces.application.ResourceHandler.createViewResource(jakarta.faces.context.FacesContext, String)" because "this.resourceHandler" is null at com.sun.faces.facelets.impl.DefaultResourceResolver.resolveUrl(DefaultResourceResolver.java:34) at com.sun.faces.facelets.impl.DefaultFaceletFactory.init(DefaultFaceletFactory.java:107) at com.sun.faces.application.ApplicationAssociate.createFaceletFactory(ApplicationAssociate.java:647) at com.sun.faces.application.ApplicationAssociate.initializeFacelets(ApplicationAssociate.java:338) at com.sun.faces.application.ApplicationAssociate.getCompiler(ApplicationAssociate.java:373) at com.sun.faces.config.processor.FaceletTaglibConfigProcessor.process(FaceletTaglibConfigProcessor.java:214) at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:310) ... 29 more

SEVERE [Catalina-utility-2] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file SEVERE [Catalina-utility-2] org.apache.catalina.core.StandardContext.startInternal Context [/pf2] startup failed due to previous errors SEVERE [Catalina-utility-2] jakarta.faces.FactoryFinderInstance.logNoFactory Application was not properly initialized at startup, could not find Factory: jakarta.faces.application.ApplicationFactory. Attempting to find backup. SEVERE [Catalina-utility-2] com.sun.faces.config.ConfigureListener.contextDestroyed Unexpected exception when attempting to tear down the Mojarra runtime java.lang.IllegalStateException: Could not find backup for factory jakarta.faces.application.ApplicationFactory. at jakarta.faces.FactoryFinderInstance.notNullFactory(FactoryFinderInstance.java:497) at jakarta.faces.FactoryFinderInstance.getFactory(FactoryFinderInstance.java:190) at jakarta.faces.FactoryFinder.getFactory(FactoryFinder.java:263) at com.sun.faces.config.InitFacesContext.getApplication(InitFacesContext.java:108) at com.sun.faces.el.ELContextImpl.(ELContextImpl.java:60) at com.sun.faces.config.ConfigureListener.contextDestroyed(ConfigureListener.java:300) at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4497) at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5118) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:187) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:713) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:975) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1949) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123) at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:776) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:426) at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1705) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:305) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1102) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1301) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1305) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1283) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:833)

Desktop (please complete the following information):

Additional context https://github.com/vtrance/pf2

BalusC commented 1 year ago

This is not the root cause. Much earlier in the server log there's a WARN line coming from Weld that the BDA is empty followed by an exception from Mojarra that CDI is unavailable. Mojarra basically needs to fail immediately when CDI is unavailable instead of continuing initialization which would then throw various kinds of exceptions, including the one reported in this issue.

vtrance commented 1 year ago

Thank you, BalusC! I added a dummy class with an annotation Named to a project, and the issue was resolved.

arjantijms commented 1 year ago

Hi,

This does bring us to an important defect in how Faces and CDI interoperate. CDI (Weld) skips initialization of itself when it does not encounter any bean in the application (and/or the appropriate beans.xml). Faces however always needs CDI, but also skips initialization if no Faces content of any kind is found.

However, when Faces (Mojarra) does find Faces content, but there is no CDI bean in the application, Faces would need to tell CDI to initialize itself regardless. This is however currently not possible. There's a bunch of obscure errors because of this. The dummy class fixes this, but dummy classes should not be needed.

When using a CDI bean with FacesConfig instead of a web.xml entry with the FacesServlet the dummy class is not needed, but as we still support web.xml we should be able to init CDI ourselves.

BalusC commented 1 year ago

First I added a line to FacesInitializer to make sure it fails fast when CDI is really unavailable. So you end up with only one exception in server log followed by an immediate shutdown of the server. The exception is the IllegalStateException coming from Mojarra's Utils#getCdiBeanManager().

Then I digged into Weld's source code and figured out how to force it to reinitialize with a non-empty BDA. Then I implemented this hack into Utils#getCdiBeanManager(). This all worked for me with your project.

But really, Weld should probably be readjusted to not skip initialization when it finds a FacesServlet being explicitly registered in web.xml. @arjantijms perhaps you can ping Weld guys for this?

vtrance commented 1 year ago

@BalusC Thanks so much for your valuable time on my issue! @arjantijms Thanks much for your thought!