2015-05-03 2 views
16

У меня есть странная проблема с Spring MVC и тимелеафом. Когда я запускаю свое веб-приложение, время от времени я получаю случайный сбой. Иногда все работает просто отлично, но иногда я получаю что-то вроде этого:Случайный сбой Spring MVC thymeleaf

javax.servlet.ServletException: Servlet.init() for servlet dispatcher threw exception 
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) 
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) 
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537) 
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085) 
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658) 
    org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:277) 
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2407) 
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2396) 
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    java.lang.Thread.run(Thread.java:745) 
root cause 

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'viewResolver' defined in com.myapp.configuration.WebConfiguration: Unsatisfied dependency expressed through constructor argument with index 0 of type [org.thymeleaf.spring4.SpringTemplateEngine]: : No qualifying bean of type [org.thymeleaf.spring4.SpringTemplateEngine] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.thymeleaf.spring4.SpringTemplateEngine] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} 
    org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) 
    org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) 
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1111) 
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1006) 
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) 
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) 
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) 
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) 
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762) 
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) 
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) 
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:663) 
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:535) 
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:489) 
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) 
    javax.servlet.GenericServlet.init(GenericServlet.java:158) 
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) 
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) 
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537) 
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085) 
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658) 
    org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:277) 
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2407) 
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2396) 
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    java.lang.Thread.run(Thread.java:745) 
root cause 

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.thymeleaf.spring4.SpringTemplateEngine] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} 
    org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1308) 
    org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054) 
    org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949) 
    org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) 
    org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) 
    org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) 
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1111) 
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1006) 
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) 
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) 
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) 
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) 
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762) 
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) 
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) 
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:663) 
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:535) 
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:489) 
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) 
    javax.servlet.GenericServlet.init(GenericServlet.java:158) 
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) 
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) 
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537) 
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085) 
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658) 
    org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:277) 
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2407) 
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2396) 
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    java.lang.Thread.run(Thread.java:745) 

Он говорит мне, что я не имею SpringTemplateEngine боб, но у меня есть это в моей конфигурации:

... 
imports 
... 
@Configuration 
@EnableWebMvc 
@ComponentScan("com.myapp.controllers") 
public class WebConfiguration extends WebMvcConfigurerAdapter { 

    private static final String TEMPLATE_RESOLVER_PREFIX = "/WEB-INF/templates/"; 
    private static final String TEMPLATE_RESOLVER_SUFFIX = ".html"; 
    private static final String TEMPLATE_RESOLVER_TEMPLATE_MODE = "HTML5"; 

    @Bean 
    public ViewResolver viewResolver(SpringTemplateEngine templateEngine) { 
     ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); 
     viewResolver.setTemplateEngine(templateEngine); 

     return viewResolver; 
    } 

    @Bean 
    public TemplateEngine templateEngine(TemplateResolver templateResolver) { 
     SpringTemplateEngine templateEngine = new SpringTemplateEngine(); 
     templateEngine.setTemplateResolver(templateResolver); 

     return templateEngine; 
    } 

    @Bean 
    public TemplateResolver templateResolver() { 
     TemplateResolver templateResolver = new ServletContextTemplateResolver(); 
     templateResolver.setPrefix(TEMPLATE_RESOLVER_PREFIX); 
     templateResolver.setSuffix(TEMPLATE_RESOLVER_SUFFIX); 
     templateResolver.setTemplateMode(TEMPLATE_RESOLVER_TEMPLATE_MODE); 

     return templateResolver; 
    } 

    @Override 
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { 
     configurer. 
} 

Я также thymeleaf в моем .pom:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>groupId</groupId> 
    <artifactId>MyApp</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>war</packaging> 
    <name>MyApp</name> 

    <dependencies> 
     <!-- Spring --> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-context</artifactId> 
      <version>4.1.4.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-webmvc</artifactId> 
      <version>4.1.4.RELEASE</version> 
     </dependency> 

     <!-- Spring Security --> 
     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-core</artifactId> 
      <version>4.0.0.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-web</artifactId> 
      <version>4.0.0.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.security</groupId> 
      <artifactId>spring-security-config</artifactId> 
      <version>4.0.0.RELEASE</version> 
     </dependency> 

     <!-- Servlet --> 
     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>servlet-api</artifactId> 
      <version>2.5</version> 
      <scope>provided</scope> 
     </dependency> 

     <!-- Thymleaf --> 
     <dependency> 
      <groupId>org.thymeleaf</groupId> 
      <artifactId>thymeleaf</artifactId> 
      <version>2.1.4.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.thymeleaf</groupId> 
      <artifactId>thymeleaf-spring4</artifactId> 
      <version>2.1.4.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>org.thymeleaf.extras</groupId> 
      <artifactId>thymeleaf-extras-springsecurity4</artifactId> 
      <version>2.1.2.RELEASE</version> 
     </dependency> 

    </dependencies> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-war-plugin</artifactId> 
       <version>2.5</version> 
       <configuration> 
        <failOnMissingWebXml>false</failOnMissingWebXml> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 
</project> 

Самое странное, что он разбился полностью случайным образом. Он работает отлично, но после создания пары он начинает сбой с каждой следующей сборки. Когда он начинает сбой, я удаляю maven build «target» directory и Invalidate cache и Restart IntelliJ Idea. Вы знаете, что не так?

PS. Я использую IntellijIdea 13.1.6.

+1

Вы используете web.xml и можете ли вы показать его нам? Отладить построение 'TemplateEngine', он даже построен? – Zarathustra

ответ

7

Возможно, вы столкнулись с проблемой тонкой зависимости.

Это advised to declare inter-beans dependencies like this:

... 
imports 
... 
@Configuration 
@EnableWebMvc 
@ComponentScan("com.myapp.controllers") 
public class WebConfiguration extends WebMvcConfigurerAdapter { 

    private static final String TEMPLATE_RESOLVER_PREFIX = "/WEB-INF/templates/"; 
    private static final String TEMPLATE_RESOLVER_SUFFIX = ".html"; 
    private static final String TEMPLATE_RESOLVER_TEMPLATE_MODE = "HTML5"; 

    @Bean 
    public ViewResolver viewResolver() { 
     ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); 
     viewResolver.setTemplateEngine(templateEngine()); 

     return viewResolver; 
    } 

    @Bean 
    public TemplateEngine templateEngine() { 
     SpringTemplateEngine templateEngine = new SpringTemplateEngine(); 
     templateEngine.setTemplateResolver(templateResolver()); 

     return templateEngine; 
    } 

    @Bean 
    public TemplateResolver templateResolver() { 
     TemplateResolver templateResolver = new ServletContextTemplateResolver(); 
     templateResolver.setPrefix(TEMPLATE_RESOLVER_PREFIX); 
     templateResolver.setSuffix(TEMPLATE_RESOLVER_SUFFIX); 
     templateResolver.setTemplateMode(TEMPLATE_RESOLVER_TEMPLATE_MODE); 

     return templateResolver; 
    } 
+0

фактически работает! Вы даже не представляете, как я вам благодарен;) – Sayaki

+0

Это также сработало для меня, но мне нужно сделать одно изменение, вернуть тип метода templateEngine, который я изменил с «TemplateEngine» на «SpringTemplateEngine», и он отлично подходит для меня. – asifaftab87

2

Первое, что я бы проверить, что вы не получили несколько версий одной и той же библиотеки на пути к классам, так как это может привести к очень запутанные вопросы.

Maven должен разрешить это, но я знаю, что у IDEA есть некоторые проблемы с конфликтующими версиями зависимостей при использовании Gradle, так что это может быть и для Maven.

Чтобы проверить это, разверните «Внешние библиотеки» «папка» в представлении проекта и убедитесь, что у вас есть только одна запись для каждой библиотеки.