2015-05-03 14 views
16

Mam problem ze sprężyną MVC i thymeleaf. Kiedy uruchamiam moją aplikację internetową, od czasu do czasu pojawia się losowa awaria. Czasami wszystko działa dobrze, ale czasami mam coś takiego:Wiosna MVC thymeleaf losowa katastrofa

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) 

Mówi mi, że nie mam SpringTemplateEngine fasoli, ale mam to w mojej konfiguracji:

... 
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. 
} 

Mam też thymeleaf w moim .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> 

Najdziwniejsze jest to, że rozbija się całkowicie losowo. Działa dobrze, ale po kilku kompilacjach zaczyna się z każdym kolejnym kompilacją. Kiedy zacznie się on zawie-rać, usuwam katalog "docelowy" z maven i unieważniam pamięć podręczną i restartuję IntelliJ Idea. Masz pojęcie, co jest nie tak?

PS. Używam IntellijIdea 13.1.6.

+1

Czy używasz pliku web.xml i czy możesz go nam pokazać? Debuguj konstrukcję 'TemplateEngine', czy jest ona nawet skonstruowana? – Zarathustra

Odpowiedz

7

Być może trafiasz na subtelny problem zależności.

Jest 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

faktycznie działa! Nawet nie potrafisz sobie wyobrazić, jak jestem ci wdzięczny;) – Sayaki

+0

To również zadziałało, ale muszę dokonać jednej zmiany, zwrócić typ szablonu templateEngine, który zmieniłem z "TemplateEngine" na "SpringTemplateEngine" i działa dobrze dla mnie. – asifaftab87

2

Pierwszą rzeczą, którą mogę sprawdzić, że nie masz wiele wersji tej samej biblioteki na ścieżce klasy, ponieważ może to spowodować problemy naprawdę mylące.

Maven ma rozwiązać ten problem, ale wiem, że IDEA ma pewne problemy ze sprzecznymi wersjami zależności podczas używania programu Gradle, więc może tak być również w przypadku Mavena.

Aby to sprawdzić, rozwiń folder "Zewnętrzne biblioteki" w widoku projektu i sprawdź, czy masz tylko jedną pozycję dla każdej biblioteki.