eclipse-ee4j / mojarra

Mojarra, a Jakarta Faces implementation
Other
158 stars 107 forks source link

UnsupportedOperationException on empty Weld BDA #5321

Closed larsgrefer closed 9 months ago

larsgrefer commented 9 months ago

Describe the bug

5238 introduces a "hack" in order to force Weld to initialize as explained in https://github.com/eclipse-ee4j/mojarra/issues/5232#issuecomment-1555916766

When trying to use this fallback mechanism, I get the following error:

2023-09-29T19:12:24.171+02:00  WARN 24540 --- [           main] org.jboss.weld.Bootstrap                 : WELD-ENV-000028: Weld initialization skipped - no bean archive found
2023-09-29T19:12:24.186+02:00  WARN 24540 --- [           main] j.e.r.webcontainer.faces.application     : Weld skipped initialization - forcing it to reinitialize
2023-09-29T19:12:24.186+02:00  WARN 24540 --- [           main] j.e.r.webcontainer.faces.application     : Reinitializing Weld failed - giving up, please make sure your project contains at least one bean class with a bean defining annotation and retry

java.lang.UnsupportedOperationException: Section 4.4 of the Servlet 3.0 specification does not permit this method to be called from a ServletContextListener that was not defined in web.xml, a web-fragment.xml file nor annotated with @WebListener
        at org.apache.catalina.core.StandardContext$NoPluggabilityServletContext.setInitParameter(StandardContext.java:6137) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at com.sun.faces.util.Util.getCdiBeanManager(Util.java:1484) ~[jakarta.faces-4.0.4.jar:4.0.4]
        at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:124) ~[jakarta.faces-4.0.4.jar:4.0.4]
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4420) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4860) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[na:na]
        at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) ~[na:na]
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:846) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[na:na]
        at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) ~[na:na]
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:241) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.core.StandardService.startInternal(StandardService.java:433) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:918) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.apache.catalina.startup.Tomcat.start(Tomcat.java:485) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:489) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:183) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:161) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:602) ~[spring-context-6.0.12.jar:6.0.12]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.joinfaces.example.JarExampleApplication.main(JarExampleApplication.java:13) ~[main/:na]

Additional context

Mojarra 4.0.4 on an embedded Tomcat 10.1.13

The ConfigureListener is not allowed to call ServletContext#setInitParameter as it was registered programmatically by com.sun.faces.config.FacesInitializer

larsgrefer commented 9 months ago

When using Undertow instead of Tomcat, the error looks like this:

2023-09-30T02:09:07.305+02:00  WARN 65537 --- [    Test worker] org.jboss.weld.Bootstrap                 : WELD-ENV-000028: Weld initialization skipped - no bean archive found
2023-09-30T02:09:07.320+02:00  WARN 65537 --- [    Test worker] j.e.r.webcontainer.faces.application     : Weld skipped initialization - forcing it to reinitialize
2023-09-30T02:09:07.321+02:00  WARN 65537 --- [    Test worker] j.e.r.webcontainer.faces.application     : Reinitializing Weld failed - giving up, please make sure your project contains at least one bean class with a bean defining annotation and retry

java.lang.UnsupportedOperationException: UT010042: This method cannot be called from a servlet context listener that has been added programatically
    at io.undertow.servlet.spec.ServletContextImpl.ensureNotProgramaticListener(ServletContextImpl.java:1018) ~[undertow-servlet-2.3.8.Final.jar:2.3.8.Final]
    at io.undertow.servlet.spec.ServletContextImpl.setInitParameter(ServletContextImpl.java:439) ~[undertow-servlet-2.3.8.Final.jar:2.3.8.Final]
    at com.sun.faces.util.Util.getCdiBeanManager(Util.java:1484) ~[jakarta.faces-4.0.4.jar:4.0.4]
    at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:124) ~[jakarta.faces-4.0.4.jar:4.0.4]
    at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:187) ~[undertow-servlet-2.3.8.Final.jar:2.3.8.Final]
    at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:219) ~[undertow-servlet-2.3.8.Final.jar:2.3.8.Final]
    at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:187) ~[undertow-servlet-2.3.8.Final.jar:2.3.8.Final]
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42) ~[undertow-servlet-2.3.8.Final.jar:2.3.8.Final]
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) ~[undertow-servlet-2.3.8.Final.jar:2.3.8.Final]
    at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:255) ~[undertow-servlet-2.3.8.Final.jar:2.3.8.Final]
    at org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory.createManager(UndertowServletWebServerFactory.java:329) ~[spring-boot-3.2.0-M3.jar:3.2.0-M3]
    at org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory.getWebServer(UndertowServletWebServerFactory.java:298) ~[spring-boot-3.2.0-M3.jar:3.2.0-M3]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:188) ~[spring-boot-3.2.0-M3.jar:3.2.0-M3]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162) ~[spring-boot-3.2.0-M3.jar:3.2.0-M3]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:602) ~[spring-context-6.1.0-M5.jar:6.1.0-M5]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.0-M3.jar:3.2.0-M3]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) ~[spring-boot-3.2.0-M3.jar:3.2.0-M3]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.2.0-M3.jar:3.2.0-M3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-3.2.0-M3.jar:3.2.0-M3]
BalusC commented 9 months ago

Right. I initially invoked it in FacesInitializer, but then I stumbled upon a race condition which caused this all to fail when Weld initializer is invoked after Faces initialier. There is no defined order in how ServletContainerInitialier instances are invoked. So I moved it to ConfigureListener last moment but this indeed doesn't anymore work that way. I'll have to further improve this.

BalusC commented 9 months ago

PR created ^^. This time I retested.

I only wish adding tests is easier. Since move of Mojarra specific tests to TCK I cannot anymore add new (automated!) tests specifically for bugfix versions.

arjantijms commented 9 months ago

Since move of Mojarra specific tests to TCK I cannot anymore add new (automated!) tests specifically for bugfix versions.

That should still be possible, but only need to be done in the .Next version of the TCK. So e.g. currently not for the 4.0.x series TCK.

BalusC commented 9 months ago

Sure but they are not executed during PRs.

BalusC commented 9 months ago

Merged into 4.0: https://github.com/eclipse-ee4j/mojarra/pull/5324 Merged 4.0 into 4.1: https://github.com/eclipse-ee4j/mojarra/commit/9934c0f7cfb5765acc17f564e4628f1c9d985759 Merged 4.1 into 5.0: https://github.com/eclipse-ee4j/mojarra/commit/967a9e75302498a071996e005d864e26503c6869