Kri*_*rzl 5 tomcat primefaces mojarra spring-boot jakarta-migration
我尝试将 Spring Boot 应用程序从 Spring Boot 2.7.8 迁移到 3.0.6。该应用程序使用 jsf mojarra 和 primefaces 作为 GUI。该应用程序在 spring boot 2.7.8 上运行良好\nSpring boot 3 使用 spring 6,它需要 java 17 和 tomcat 10。因此我必须将 java EE 迁移到 jakarta EE 10 和 jakarta Faces 4。\n不幸的是,应用程序服务器不支持迁移后开始。
\nError : Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI? Caused by: java.lang.NullPointerException: Cannot invoke "jakarta.faces.context.FacesContext.getExternalContext()" because "context" is null
完整的堆栈跟踪:
\n[2023-05-12 13:53:48,821] jakarta.faces copyInjectionProviderFromFacesContext 错误 - 无法从初始化时 FacesContext 获取 InjectionProvider。此容器是否实现 Mojarra 注入 SPI?\n[2023-05-12 13:53:48,824] ERROR jakarta.faces logNoFactory - L\xe2\x80\x99application n\xe2\x80\x99a pas \xc3\xa9t\xc3 \xa9 首字母\xc3\xa9e 更正\xc3\xa9marrage。Fabrique 不可能本地化:jakarta.faces.context.FacesContextFactory。正在尝试查找备份。\n[2023-05-12 13:53:48,824] 错误 org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/etcsst] 日志 - Servlet.init() for servlet [FacesServlet] 抛出异常\njava.lang.IllegalStateException:找不到工厂 jakarta.faces.context.FacesContextFactory 的备份。\n 在 jakarta.faces.FactoryFinderInstance.notNullFactory(FactoryFinderInstance.java:496) ~[jakarta.jakartaee-api-10.0.0.jar:?]\n 在 jakarta.faces.FactoryFinderInstance.getFactory(FactoryFinderInstance.java:190) 〜[jakarta.jakartaee-api-10.0.0.jar:?]\n 在 jakarta.faces.FactoryFinder.getFactory(FactoryFinder.java:263) 〜[jakarta.jakartaee-api-10.0.0.jar:?]\ n 在 jakarta.faces.webapp.FacesServlet.acquireFacesContextFactory(FacesServlet.java:493) ~[jakarta.jakartaee-api-10.0.0.jar:?]\n 在 jakarta.faces.webapp.FacesServlet.init(FacesServlet.java :342) ~[jakarta.jakartaee-api-10.0.0.jar:?]\n 位于 org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:944) ~[tomcat-embed-core-10.1。 8.jar:10.1.8]\n 位于 org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:808) ~[tomcat-embed-core-10.1.8.jar:10.1.8]\n 位于org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedContext.load(TomcatEmbeddedContext.java:84) ~[spring-boot-3.0.6.jar:3.0.6]\n 在 java.util.stream.ForEachOps$ForEachOp $OfRef.accept(ForEachOps.java:183) ~[?:?]\n 位于 java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[?:?]\n 位于 java.util.stream .ReferencePipeline$Head.forEach(ReferencePipeline.java:762) ~[?:?]\n 在 java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276) ~[?:?]\n 在 java .util.TreeMap$ValueSpliterator.forEachRemaining(TreeMap.java:3215) ~[?:?]\n 在 java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[?:?]\n 在 java .util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[?:?]\n 位于 java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[?:?]\n在 java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[?:?]\n 在 java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?: ?]\n 在 java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[?:?]\n 在 org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedContext.lambda$deferredLoadOnStartup$0(TomcatEmbeddedContext .java:67) ~[spring-boot-3.0.6.jar:3.0.6]\n 位于 org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedContext。\n
pom 文件:
\n<?xml version="1.0" encoding="UTF-8"?>\n<project xmlns="maven.apache.org/POM/4.0.0" xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="maven.apache.org/POM/4.0.0 maven.apache.org/xsd/maven-4.0.0.xsd">\n <modelVersion>4.0.0</modelVersion>\n</project>\n <parent>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-parent</artifactId>\n <version>3.0.6</version>\n </parent>\n <groupId>...</groupId>\n <artifactId>...</artifactId>\n <version>3.5.2-SNAPSHOT</version>\n <name>etcsst-cloud</name>\n <packaging>war</packaging>\n\n <properties>\n <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n <java.version>17</java.version>\n <log4j2.version>2.20.0</log4j2.version>\n </properties>\n <dependencies>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-aop</artifactId>\n <exclusions>\n <exclusion>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-logging</artifactId>\n </exclusion>\n </exclusions>\n </dependency>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-data-jpa</artifactId>\n </dependency>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-batch</artifactId>\n </dependency>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-security</artifactId>\n </dependency>\n <dependency>\n <groupId>org.springframework.security</groupId>\n <artifactId>spring-security-ldap</artifactId>\n </dependency>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-oauth2-client</artifactId>\n </dependency>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-validation</artifactId>\n </dependency>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-web</artifactId>\n <exclusions>\n <exclusion>\n <groupId>org.springframework</groupId>\n <artifactId>spring-webmvc</artifactId>\n </exclusion>\n </exclusions>\n </dependency>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-log4j2</artifactId>\n </dependency>\n <!-- Additional JSF libs: Sun's JSF API and Impl. (Mojarra), PrimeFaces and Jasper -->\n <dependency>\n <groupId>org.apache.logging.log4j</groupId>\n <artifactId>log4j-1.2-api</artifactId>\n <version>${log4j2.version}</version>\n </dependency>\n <dependency>\n <groupId>jakarta.platform</groupId>\n <artifactId>jakarta.jakartaee-api</artifactId>\n <version>10.0.0</version>\n <scope>provided</scope>\n </dependency>\n <dependency>\n <groupId>jakarta.platform</groupId>\n <artifactId>jakarta.jakartaee-web-api</artifactId>\n <version>10.0.0</version>\n <!-- scope provided should be enough ? -->\n <scope>provided</scope>\n </dependency>\n\n <dependency>\n <groupId>org.glassfish</groupId>\n <artifactId>jakarta.faces</artifactId>\n <!--\n probleme : server starts with 3.0.4, but 3.0.4 is not compatible with jakarta.jakartaee-web-api 10, which is needed for tomcat 10\n with version 4.0.1, the server doesn't start, the context not loaded,\n Error : Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI?\n -->\n <version>4.0.1</version>\n <!-- <version>3.0.4</version> -->\n </dependency>\n <dependency>\n <groupId>jakarta.servlet.jsp.jstl</groupId>\n <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>\n <version>3.0.0</version>\n <exclusions>\n <exclusion>\n <groupId>jakarta.servlet</groupId>\n <artifactId>jakarta.servlet-api</artifactId>\n </exclusion>\n </exclusions>\n </dependency>\n <dependency>\n <groupId>org.primefaces</groupId>\n <artifactId>primefaces</artifactId>\n <version>11.0.0</version>\n <classifier>jakarta</classifier>\n </dependency>\n <dependency>\n <groupId>org.primefaces.extensions</groupId>\n <artifactId>primefaces-extensions</artifactId>\n <classifier>jakarta</classifier>\n <version>11.0.6</version>\n </dependency>\n <dependency>\n <groupId>com.google.code.gson</groupId>\n <artifactId>gson</artifactId>\n <version>2.10.1</version>\n </dependency>\n\n <dependency>\n <groupId>org.apache.tomcat.embed</groupId>\n <artifactId>tomcat-embed-jasper</artifactId>\n </dependency>\n\n <!-- file upload -->\n <dependency>\n <groupId>commons-fileupload</groupId>\n <artifactId>commons-fileupload</artifactId>\n <version>1.5</version>\n </dependency>\n <dependency>\n <groupId>commons-io</groupId>\n <artifactId>commons-io</artifactId>\n <version>2.11.0</version>\n </dependency>\n\n <dependency>\n <groupId>org.apache.commons</groupId>\n <artifactId>commons-lang3</artifactId>\n <version>3.12.0</version>\n </dependency>\n\n <dependency>\n <groupId>joda-time</groupId>\n <artifactId>joda-time</artifactId>\n <version>2.10.10</version>\n </dependency>\n <dependency>\n <groupId>commons-lang</groupId>\n <artifactId>commons-lang</artifactId>\n <version>2.4</version>\n </dependency>\n <!-- mailing -->\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-mail</artifactId>\n </dependency>\n\n <!-- TODO remove after successful migration -->\n <!--spring property management f\xc3\xbcr spring boot upgrade-->\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-properties-migrator</artifactId>\n <scope>runtime</scope>\n </dependency>\n ...\n </dependencies>\n</project>\n
Run Code Online (Sandbox Code Playgroud)\nJsf Servlet 配置:
\nimport jakarta.faces.webapp.FacesServlet;\n\nimport jakarta.servlet.ServletContext;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;\nimport org.springframework.boot.web.servlet.ServletContextInitializer;\nimport org.springframework.boot.web.servlet.ServletRegistrationBean;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.stereotype.Component;\nimport org.springframework.web.context.request.RequestContextListener;\nimport com.sun.faces.vendor.WebContainerInjectionProvider;\nimport lombok.extern.slf4j.Slf4j;\nimport ch.sbb.rsw.estamigration.spring.RestoreSpringSessionListener;\n\n@Configuration\n@Component\n@Slf4j\npublic class JsfServletConfigurator implements ServletContextInitializer {\n\n @Value("${javax.faces.PROJECT_STAGE}") // = Development, Production\n private String jsfProjectStage;\n\n @Value("${server.servlet.context-path}") // /etcsst\n private String dispatcherServletPath; // /etcsst, wird seit spring boot 2.0.9 n\xc3\xb6tig\n\n @Override\n public void onStartup(ServletContext servletContext) {\n log.debug("servlet configurator. jsf project stage : '" + jsfProjectStage + "'");\n\n // kommentare aus xhtml-seiten kommen nicht in output\n servletContext.setInitParameter("jakarta.faces.FACELETS_SKIP_COMMENTS", "true");\n servletContext.setInitParameter("primefaces.THEME", "nova-light");\n servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());\n servletContext.setInitParameter("jakarta.faces.PROJECT_STAGE", jsfProjectStage);\n// sandbox zone, nothing helps\n// servletContext.setInitParameter("com.sun.faces.config.ConfigManager_INJECTION_PROVIDER_TASK", "com.sun.faces.vendor.WebContainerInjectionProvider");\n// servletContext.setAttribute("com.sun.faces.config.ConfigManager_INJECTION_PROVIDER_TASK", "com.sun.faces.vendor.WebContainerInjectionProvider");\n// servletContext.setAttribute("com.sun.faces.config.ConfigManager_INJECTION_PROVIDER_TASK", new WebContainerInjectionProvider());\n// servletContext.setInitParameter("jakarta.faces.CONFIG_FILES", "/META-INF/faces-config.xml");\n// servletContext.setAttribute("jakarta.faces.CONFIG_FILES", "/META-INF/faces-config.xml");\n// servletContext.setInitParameter("com.sun.faces.injectionProvider", "com.sun.faces.vendor.WebContainerInjectionProvider");\n // source : stackoverflow.com/questions/73112899/spring-boot-3-and-jsf-with-jakarta-not-working\n// servletContext.setAttribute(com.sun.faces.RIConstants.FACES_INITIALIZER_MAPPINGS_ADDED, Boolean.TRUE); // constant fehlt in 4.0.1, comes from 3.0.0\n// servletContext.setAttribute("com.sun.faces.facesInitializerMappingsAdded", Boolean.TRUE);\n\n // because of Annotation ReinitAfterPassivation. \n servletContext.addListener(RestoreSpringSessionListener.class);\n }\n\n @Bean\n public ServletRegistrationBean<FacesServlet> jsfServletRegistrationBean() {\n FacesServlet facesServlet = new FacesServlet();\n ServletRegistrationBean<FacesServlet> servletRegistrationBean = new ServletRegistrationBean<FacesServlet>(facesServlet, "*.xhtml", "/logout",\n // urls for oauth2/SSO\n "/oauth2/authorization/*", "/login/oauth2/code/*");\n servletRegistrationBean.setLoadOnStartup(1);\n servletRegistrationBean.setName("FacesServlet");\n return servletRegistrationBean;\n }\n\n @Bean\n // returns /etcsst, needed from spring boot 2.0.9\n public DispatcherServletPath jsfServletPathBean() {\n return () -> dispatcherServletPath;\n }\n\n @Bean\n public RequestContextListener requestContextListener() {\n return new RequestContextListener();\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\nfaces-config.xml:
\n<?xml version="1.0" encoding="UTF-8"?>\n<faces-config\n xmlns="https://jakarta.ee/xml/ns/jakartaee"\n xmlns:xsi="www.w3.org/2001/XMLSchema-instance"\n xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee\n https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_4_0.xsd"\n version="4.0">\n \n <application>\n <!-- \n RswSpringBeanFacesELResolver is an extension of SpringBeanFacesELResolver. Checks user roles, reads mask labels from database\n -->\n <el-resolver>\n ch.sbb.rsw.etcsst.web.util.RswSpringBeanFacesELResolver\n </el-resolver>\n \n <locale-config>\n <default-locale>de</default-locale>\n <supported-locale>fr</supported-locale>\n <supported-locale>it</supported-locale>\n <supported-locale>en</supported-locale>\n </locale-config>\n <message-bundle>EtcsstResources</message-bundle>\n <resource-bundle>\n <base-name>EtcsstResources</base-name>\n <var>Msgs</var>\n </resource-bundle>\n </application>\n\n <lifecycle>\n <phase-listener>ch.sbb.rsw.estamigration.jsf.MultipleFormSubmitPreventionPhaseListener</phase-listener>\n </lifecycle>\n\n <factory>\n <!-- Doesn't help. The RswExceptionHandlerFactory was already defined here and worked before upgrade. \n After upgrade, a display in constructor doesn't longer appear in log, so the class is no longer loaded after upgrade \n defining FacesContextFactoryImpl here has no effect\n -->\n <faces-context-factory>com.sun.faces.context.FacesContextFactoryImpl</faces-context-factory>\n <exception-handler-factory>\n ch.sbb.rsw.estamigration.exception.RswExceptionHandlerFactory\n </exception-handler-factory>\n </factory>\n\n <!-- NAVIGATION RULES -->\n <navigation-rule>\n <from-view-id>/*</from-view-id>\n <navigation-case>\n <from-outcome>home</from-outcome>\n <to-view-id>/pages/index.xhtml</to-view-id>\n </navigation-case>\n <navigation-case>\n <from-outcome>login</from-outcome>\n <to-view-id>/login.xhtml</to-view-id>\n </navigation-case>\n </navigation-rule>\n\n <converter>\n <converter-for-class>ch.sbb.rsw.etcsst.model.Aktor</converter-for-class>\n <converter-class>ch.sbb.rsw.etcsst.web.converter.AktorConverter</converter-class>\n </converter>\n ... here more converters\n \n</faces-config>\n
Run Code Online (Sandbox Code Playgroud)\n如果我使用版本 3.0.4 代替 org.glassfish:jakarta.faces:4.0.1,服务器启动正常,但由于 3.0.4 与 jakarta EE 10 不兼容,第一次尝试显示 xhtml 时会失败-page, 3.0.4 尝试调用 jakarta EE 10 中缺少的 jakarta EE 9 的类/方法\n调试 FactoryFinderInstance,缺少 faces 上下文(但在 3.0.4 中存在)
\n我尝试将工厂类定义为 META-INF/services 中的服务,\n例如,名为 jakarta.faces.context.FacesContextFactory 的文件,其内容org.primefaces.context.PrimeFacesContextFactory
\n定义的类将被加载,但每个如此注入的类都会出现错误Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI?
,服务器仍然没有开始
我也尝试在 faces-config.xml 中定义工厂类,请参阅下面的整个文件,它没有任何效果
\n <factory>\n <!-- Doesn't help. The RswExceptionHandlerFactory was already defined here and worked before upgrade. \n After upgrade, a display in constructor doesn't longer appear in log, so the class is no longer loaded after upgrade \n defining FacesContextFactoryImpl here has no effect\n -->\n\n <faces-context-factory>com.sun.faces.context.FacesContextFa
我用 myFaces 替换了 mojarra。我可以使用基于这篇文章的 hello world-example 来解决问题: https ://prog.world/jakarta-faces-and-spring-boot/
归档时间: |
|
查看次数: |
2065 次 |
最近记录: |