Spring Download and JSF / Primary / Richfaces

I was in contact with Spring for only a few months and recently came to Spring Boot while looking at the manual section. The guides were very simple to complete and were made for an initial understanding of the basic (and amazing) design idea, which was to be able to create and deploy enterprise-level applications with minimal configuration, supporting a wide range of Spring / JEE. I am really interested in using Spring Boot for test projects, because with them they are much easier and faster to set up and run and are still very close to my production environment. I am currently trying to create a project using Spring Boot and Primefaces as my chosen technology of choice, but this installation is apparently not ready out of the box, as is the case with Thymeleaf, for which it has its own binary code in the classpath enough . I tried to include the following gradle / maven artifacts, without success:

  • primefaces
  • Jsf-api
  • JSF-real
  • el api

Spring A loaded Tomcat server starts without visible errors, but after trying to open a page, such as / view, in a browser, the embedded server displays the following error message: HTTP Status 500 - Circular view path: would dispatch back to the current handler URL again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.) HTTP Status 500 - Circular view path: would dispatch back to the current handler URL again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)

After searching in several different places, I still cannot find any resources / tutorials on how to set up such a project. Here is the contents of my build.gradle file:

 buildscript { repositories { maven { url "http://repo.spring.io/libs-snapshot" } } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC4") } } apply plugin: 'java' apply plugin: 'idea' apply plugin: 'spring-boot' idea { module { downloadJavadoc = true } } group = 'com.hello' version = '0.0.1-SNAPSHOT' repositories { mavenCentral() mavenLocal() maven { url "http://repository.primefaces.org" } } dependencies { compile("org.springframework.boot:spring-boot-starter-web") // compile ("org.thymeleaf:thymeleaf-spring4") compile group: 'org.primefaces', name: 'primefaces', version: '4.0' compile group: 'com.sun.faces', name: 'jsf-api', version: '2.2.2' compile group: 'com.sun.faces', name: 'jsf-impl', version: '2.2.2' compile group: 'javax.el', name: 'el-api', version: '1.0' } task wrapper(type: Wrapper) { gradleVersion=1.10 } 

My main class:

 package com.hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @EnableAutoConfiguration @ComponentScan @Configuration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 

and my implementation of WebMvcConfigurerAdapter:

 package com.hello; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("view"); registry.addViewController("/view").setViewName("view"); } } 

Along with my view.html file (I also tried view.xhtml), these are all the files I created for this project, as I am trying to do a minimal setup.

If someone can understand what I'm doing wrong (or not at all), help will be greatly appreciated. Are additional files / beans needed for JSF configuration in this case? If so, where and how should such files be placed?

This question has also been posted in the official Spring forums: http://forum.spring.io/forum/spring-projects/boot/746552-spring-boot-and-jsf-primefaces-richfaces


EDIT: After enabling the M. Deinum bean configuration for JSF and removing the WebMvcConfigurerAdapter definition (associated with Spring MVC), Spring Boot seems to match requests to the FacesServlet instance, now I get the following error message: HTTP Status 500 - Servlet.init() for servlet FacesServlet threw exception

the main reason:
 java.lang.IllegalStateException: Could not find backup for factory javax.faces.context.FacesContextFactory 

Code for the new JsfConfig bean:

 package com.hello; import com.sun.faces.config.ConfigureListener; 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.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; import javax.faces.webapp.FacesServlet; @Configuration public class JsfConfig { @Bean public FacesServlet facesServlet() { return new FacesServlet(); } @Bean public ServletRegistrationBean facesServletRegistration() { ServletRegistrationBean registration = new ServletRegistrationBean(facesServlet(), "*.xhtml"); registration.setName("FacesServlet"); return registration; } @Bean public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() { return new ServletListenerRegistrationBean<ConfigureListener>(new ConfigureListener()); } @Bean public ViewResolver getViewResolver(){ InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/templates/"); resolver.setSuffix(".xhtml"); return resolver; } } 
+7
spring spring-boot jsf primefaces
source share
5 answers

After looking at this question louvelg about another problem after setting up FacesServlet using Spring Boot, I got it working with JSF / primefaces by adding a couple of configuration files as well as ServletRegistrationBean from spring -web. Web.xml and faces-config.xml files view of Spring wound The idea of โ€‹โ€‹loading a minimal setup without a ton of xml files, but this is the minimal setup I could find with JSF, if anyone knows a better / cleaner way to do this, please let me know.

Here are the dependencies in the gradle.build file:

 compile group: "org.springframework.boot", name: "spring-boot-starter" compile group: "org.springframework", name: "spring-web", version: "4.0.2.RELEASE" compile group: "org.apache.tomcat.embed", name: "tomcat-embed-core", version: tomcatVersion compile group: "org.apache.tomcat.embed", name: "tomcat-embed-logging-juli", version: tomcatVersion compile group: "org.apache.tomcat.embed", name: "tomcat-embed-jasper", version: tomcatVersion compile group: "org.primefaces", name: "primefaces", version: "4.0" compile group: "com.sun.faces", name: "jsf-api", version: "2.1.21" compile group: "com.sun.faces", name: "jsf-impl", version: "2.1.21" 

where tomcatVersion is "7.0.34". Key changes here are:

  • Removing spring-boot-starter-web , which also includes Spring MVC, as pointed out by M. Deinum
  • Including spring-boot-starter (easier start-up) and spring-web
  • Explicitly including tomcat-embed dependencies as spring-boot-starter-web no longer exists.

Here is the new contents of my main class:

 package com.hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 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 javax.faces.webapp.FacesServlet; @Configuration @ComponentScan @EnableAutoConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public ServletRegistrationBean servletRegistrationBean() { FacesServlet servlet = new FacesServlet(); return new ServletRegistrationBean(servlet, "*.xhtml"); } } 

@EnableAutoConfiguration if you want Spring Boot to automatically configure Tomcat and xhtml ServletRegistrationBean requests display your FacesServlet.

The WEB-INF / faces-config.xml file in my webapp directory:

 <?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd" version="2.2"> <application> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> </application> </faces-config> 

and the web.xml file also in webapp / WEB-INF:

 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> </web-app> 

Servlet definitions seem redundant, but for some reason, if I delete them from the web.xml file or the registration of the bean servlet, the xhtml page rendering does not work properly or does not work at all. EDIT: it turns out that the servlet mapping in the web.xml file is not necessary, it was just an IDE problem, in my case Intellij Idea is not aware of the servlet mapping that is defined in the bean servlet registration, so he complained about the lack of mappings for the expected servlet, but the application works without problems. Nevertheless.

Thanks to everyone who contributed.

+5
source share

You are using JSF, which is not going to work with Spring MVC - these are different technologies. You will need to configure JSF correctly. To do this, you need to add FacesServlet and ConfigureListener faces. This is necessary for JSF to be configured correctly, usually the ConfigureListener will be detected automatically, but the built-in versions really do not.

 @Configuration public class JsfConfig { @Bean public FacesServlet facesServlet() { return new FacesServlet(); } @Bean public ServletRegistrationBean facesServletRegistration() { ServletRegistrationBean registration = new ServletRegistrationBean(facesServlet(), "*.xhtml"); registration.setName("FacesServlet") return registration; } @Bean public ListenerRegistationBean jsfConfigureListener() { return new ListenerRegistrationBean(new ConfigureListener()); } } 

Something like that. Perhaps I would advise you to disable the automatic configuration for DispatcherServlet, etc., since you are using JSF, not Spring MVC.

 @EnableAutoConfiguration(exclude={WebMvcAutoConfiguration.class,DispatcherServletAutoConfiguration } 
+6
source share

I followed this post and I was getting the same error. This is a bit of a hack, but at the moment this is the best I can get.

Add this to the src / main / webapp / WEB-INF folder in the web.xml file.

 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> </servlet> </web-app> 

This should fix the factory backup problem.

I ran into additional problems after getting this error

 It appears the JSP version of the container is older than 2.1 and unable to locate the EL RI expression factory, com.sun.el.ExpressionFactoryImpl. If not using JSP or the EL RI, make sure the context initialization parameter, com.sun.faces.expressionFactory, is properly set. 

So I added this dependency

 compile "org.glassfish.web:el-impl:2.2" 

And so when things started working for me.

I'm still working on not needing web.xml. Because it's really a kind of hack for how Spring Boot should work. The further progress that I am doing on this, I will try to remember in order to send an answer to this answer, but if I do not, I will add to this example the application that I created.

https://github.com/Zergleb/Spring-Boot-JSF-Example

+2
source share

I also ran into this problem. I found a slightly different solution without [@EnableAutoConfiguration]:

[pom.xml]

  <?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> ... <!-- http://stackoverflow.com/questions/25479986/spring-boot-with-jsf-could-not-find-backup-for-factory-javax-faces-context-face/25509937#25509937 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.4.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- JSF --> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.faces</artifactId> <version>2.2.11</version> </dependency> <!-- JSR-330 --> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> <!-- JSP API --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <!-- Spring web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> ... </dependencies> <build> <outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory> </build> </project> 

and Java configuration class:

 ... @Configuration public class JsfConfig extends SpringBootServletInitializer { @Bean public ServletRegistrationBean servletRegistrationBean() { FacesServlet servlet = new FacesServlet(); ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet, "*.xhtml"); return servletRegistrationBean; } @Bean public EmbeddedServletContainerFactory servletContainer() { TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); factory.setPort(8080); factory.setSessionTimeout(10, TimeUnit.MINUTES); return factory; } } 

[WEB-INF / web.xml]

 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> </servlet> </web-app> 

[faces-config.xml]

 <?xml version='1.0' encoding='UTF-8'?> <faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"> <application> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> </application> </faces-config> 
+2
source share

This line in the code registers the controller, which upon receiving the request for /view redirects to the view with the logical name view .

 registry.addViewController("/view").setViewName("view"); 

Then the recognizing view will take a logical name, apply the prefix and suffix and find the definition of the view, for example view.xhtml .

The problem is that a default view extender is added that does not add a suffix or prefix.

See WebMvcAutoConfiguration.defaultViewResolver() for code that defines a default view qualifier.

The default viewer attempts to load a view named /view , which starts the same controller again, creating a loop.

Try either to comment on this line addViewController , or define your own view recognizer, for example, as follows:

 @Bean public ViewResolver getViewResolver(){ InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".xhtml"); return resolver; } 
0
source share

All Articles