Spring Boot with JSF; Could not find backup for factory javax.faces.context.FacesContextFactory

匿名 (未验证) 提交于 2019-12-03 01:17:01

问题:

I'm having some problems with Spring Boot and JSF. The servlet appears to start up correctly, but when I attempt to access a resource I get the following exception

java.lang.IllegalStateException: Could not find backup for factory javax.faces.context.FacesContextFactory.      at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:1011)     at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:343)     at javax.faces.webapp.FacesServlet.init(FacesServlet.java:302)     at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)     at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:884)     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:134)     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)     at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:683)     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1720)     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)     at java.lang.Thread.run(Thread.java:724) 

My Application class is as follows

@Configuration @EnableAutoConfiguration @ComponentScan public class Application extends SpringBootServletInitializer {      public static void main(String[] args) {         SpringApplication.run(Application.class);     }      @Override     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {         return application.sources(Application.class);     }      @Bean     public FacesServlet facesServlet() {         return new FacesServlet();     }      @Bean     public ServletRegistrationBean facesServletRegistration() {         ServletRegistrationBean registration = new ServletRegistrationBean(             facesServlet(), "*.xhtml");         registration.setName("Christmas");         return registration;     }      @Bean     public ServletListenerRegistrationBean jsfConfigureListener() {         return new ServletListenerRegistrationBean(             new ConfigureListener());     } } 

I have no web.xml or faces-config.xml, and my pom.xml is as follows

4.0.0com.x.y.zproject0.0.1-SNAPSHOTjarorg.springframework.bootspring-boot-starter-parent1.1.5.RELEASEorg.springframework.bootspring-boot-maven-pluginorg.springframework.bootspring-boot-starter-weborg.springframeworkspring-weborg.primefacesprimefaces5.0com.sun.facesjsf-api2.1.11com.sun.facesjsf-impl2.1.11

I have a suspicion that there are some conflicts in the dependencies relating to the jsf api, but I can't seem to figure out where. Any help on fixing this issue would be greatly appreciated.

回答1:

To get JSF working on Spring Boot without a web.xml or faces-config.xml you need to force it to load its configuration files via an init parameter on the ServletContext. An easy way to do that is to implement ServletContextAware:

public class Application implements ServletContextAware {      // ...      @Override     public void setServletContext(ServletContext servletContext) {         servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());                } } 

JSF's ConfigureListener also has a dependency on JSP, so you'll need to add a dependency on Jasper to your pom:

org.apache.tomcat.embedtomcat-embed-jasper

It's not directly related to your problem, but you don't need to declare FacesServlet as a bean. The ServletRegistrationBean is sufficient.

This leaves Application.java looking as follows:

import javax.faces.webapp.FacesServlet; import javax.servlet.ServletContext;  import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.context.embedded.ServletListenerRegistrationBean; import org.springframework.boot.context.embedded.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.context.ServletContextAware;  import com.sun.faces.config.ConfigureListener;  @Configuration @EnableAutoConfiguration @ComponentScan public class Application implements ServletContextAware {      public static void main(String[] args) {         SpringApplication.run(Application.class);     }      @Bean     public ServletRegistrationBean facesServletRegistration() {         ServletRegistrationBean registration = new ServletRegistrationBean(             new FacesServlet(), "*.xhtml");         registration.setLoadOnStartup(1);         return registration;     }      @Bean     public ServletListenerRegistrationBean jsfConfigureListener() {         return new ServletListenerRegistrationBean(             new ConfigureListener());     }      @Override     public void setServletContext(ServletContext servletContext) {         servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());            } } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!