【问题标题】:Thymeleaf fails on gradle buildThymeleaf 在 gradle 构建上失败
【发布时间】:2014-05-18 21:53:01
【问题描述】:

使用 Spring Boot 和 Thymeleaf 构建应用程序,在 IntelliJ 中一切正常,但是当我通过 gradle clean build 构建时,我得到了错误。

这是我的目录结构:

???? src
├─── ???? generated
├─── ???? main
│   ├─── ???? java
│   ├─── ???? resources
│   │   └─── ???? assets
│   │       ├─── ???? css
│   │       ├─── ???? js
│   │       └─── ???? templates
│   │           └─── *.html
│   └─── ???? webapp
└─── ???? test
    ├─── ???? groovy
    │   └─── unit & integration tests here
    ├─── ???? resources
    └─── ???? unit

这是我的 gradle 文件:

apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'jacoco'
apply plugin: 'war'
apply plugin: 'maven'

def generatedResources = "$buildDir/generated-resources/main"

configurations {
    querydslapt
}

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-snapshot" }
        mavenLocal()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC4")
    }
}


repositories {
    mavenCentral()
    maven {url "http://repo.spring.io/libs-snapshot"}
    maven {url 'http://repo.spring.io/milestone' }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:1.0.0.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-data-jpa:1.0.1.RELEASE")
    compile("org.springframework.boot:spring-boot:1.0.1.RELEASE")
    compile("org.springframework:spring-orm:4.0.0.RC1")
    compile("org.hibernate:hibernate-entitymanager:4.2.1.Final")
    compile("com.h2database:h2:1.3.172")
    compile("joda-time:joda-time:2.3")
    compile("org.thymeleaf:thymeleaf-spring4")
    compile("org.codehaus.groovy.modules.http-builder:http-builder:0.7.1")
    compile('org.codehaus.groovy:groovy-all:2.2.1')
    compile('org.jadira.usertype:usertype.jodatime:2.0.1')
    compile('com.mysema.maven:maven-apt-plugin:1.0.2')
    compile('com.mysema.querydsl:querydsl-apt:3.3.2')
    compile('com.mysema.querydsl:querydsl-jpa:3.3.2')

    querydslapt "com.mysema.querydsl:querydsl-apt:3.3.2"
    testCompile('org.spockframework:spock-core:0.7-groovy-2.0') {
        exclude group: 'org.codehaus.groovy', module: 'groovy-all'
    }
    testCompile('org.codehaus.groovy.modules.http-builder:http-builder:0.7+')
    testCompile("junit:junit")
}

jacocoTestReport {
    group = "Reporting"
    description = "Generate Jacoco coverage reports after running tests."
}

sourceSets {

    generated {
        java {
            srcDirs = ['src/main/generated']
        }
    }
    main {
        //let's register an output folder on the main SourceSet:
    output.dir(generated, builtBy: 'generateQueryDSL')
        java {
            srcDirs = []
        }
        groovy {
            srcDirs = ['src/main/groovy', 'src/main/java']
        }
        resources {
            srcDirs = ['src/main/resources']
        }

        output.resourcesDir = "build/classes/main"
    }

    test {
        java {
            srcDirs = []
        }
        groovy {
            srcDirs = ['src/test/groovy', 'src/test/java']
        }
        resources {
            srcDirs = ['src/test/resources']
        }

        output.resourcesDir = "build/classes/test"
    }
}


task generateQueryDSL(type: JavaCompile, group: 'build', description: 'Generates the QueryDSL query types') {
    source = sourceSets.main.java
    classpath = configurations.compile + configurations.querydslapt
    options.compilerArgs = [
            "-proc:only",
            "-processor", "com.mysema.query.apt.jpa.JPAAnnotationProcessor"
    ]
    destinationDir = sourceSets.generated.java.srcDirs.iterator().next()
}

compileJava {
    dependsOn generateQueryDSL
    source generateQueryDSL.destinationDir
}

compileGeneratedJava {
    dependsOn generateQueryDSL
    options.warnings = false
    classpath += sourceSets.main.runtimeClasspath
}

clean {
    delete sourceSets.generated.java.srcDirs
}

idea {
    module {
        sourceDirs += file('src/main/generated')
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}

我的 UI 配置如下:

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
    ...

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController( "/home" ).setViewName( "index" );
        ...
    } 

    // removed to try and find the css/js/images
    // @Override
    // public void addResourceHandlers(ResourceHandlerRegistry registry) {
    //     registry.addResourceHandler( "/resources/**" ).addResourceLocations( "/resources/" );
    // }      

    ...
}

这是一个示例测试:

@SpringApplicationConfiguration
class TreasuryStatusEvaluatorTest extends Specification {

    @Shared
    def ConfigurableApplicationContext context

    @Shared
    private StatusRepository statusRepository

    void setupSpec() {
        Future future = Executors.newSingleThreadExecutor().submit(
                new Callable() {
                    @Override
                    public ConfigurableApplicationContext call() throws Exception {
                        return (ConfigurableApplicationContext) SpringApplication.run(OFAC.class)
                    }
                })
        context = future.get(60, TimeUnit.SECONDS)
        treasuryStatusEvaluator = context.getBean(TreasuryStatusEvaluator.class)
        statusRepository = context.getBean(StatusRepository.class)
    }

    void cleanupSpec() {
        if (context != null) {
            context.close()
        }
    }
...
}

这是一个典型的html页面:

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <meta name="description" content=""/>  

    <link href="/resources/static/css/bootstrap.css" rel="stylesheet"/>
    <link href="/resources/static/css/bootstrap.min.css" rel="stylesheet"/>
    <link href="/resources/static/css/bootstrap-responsive.css" rel="stylesheet"/>
    <link href="/resources/static/css/bootstrap-responsive.min.css" rel="stylesheet"/>
    <link href="/resources/static/css/ofac.css" rel="stylesheet"/>
    <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet"/>

    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
</head>
<body>
<div id="wrap">
...

<script src="/resources/static/js/libs/jquery.min.js"></script>
<script src="/resources/static/js/libs/bootstrap/bootstrap.min.js"></script>
</body>
</html>

这些测试在 IntelliJ 中运行或作为应用程序运行,一切正常。但是当我从命令行运行测试时,会出现以下错误:

Caused by: java.lang.IllegalStateException: Cannot find template location: class path resource [templates/] (please add some templates or check your Thymeleaf configuration)

我发现在 spring-boot 中,thymeleaf:https://github.com/spring-projects/spring-boot/issues/424 的目录结构存在问题,并且似乎需要一个模板目录。我没有使用任何模板,只是 html。

更新 #1: 我移动了 src/main/resources/* 下的 html

更新 #2: 我将 css/js/libs 移动到 src/main/resources/static 我尝试将它们放在 src/main/static 下,但这也不起作用

【问题讨论】:

  • 你试过使用 1.0.0.RELEASE 版本的 spring-boot 吗?我看到了 RC 之间的一些相当大的变化。我自己仍然了解springboot autoconfig,但是如果您使用starter-web,它可能会在src/main/resources/templates 中寻找视图文件。不确定 intellij 是如何工作的,可能在 intellij 中正确完成了一些额外的配置。请参阅:stackoverflow.com/questions/22770220/…

标签: gradle thymeleaf spring-boot


【解决方案1】:

现在有一个 1.0.1.RELEASE 的 Spring Boot,所以你应该使用它(它可能只是解决你的问题)。不过,通常情况下,只要您将模板放在“classpath:/templates”中(这些 html 文件就是 Thymeleaf 所谓的“模板”),我就不会期望您需要 Thymeleaf 配置。如果您希望它们位于其他位置,可以使用spring.thymeleaf.prefix 指定模板位置(请参阅docs here)。

如果您更喜欢自己完全配置 Thmyeleaf,那么您需要使用模板解析器的常规 bean 名称(“defaultTemplateResolver”),以便 Boot 知道您在做什么。详细信息在 ThymeleafAutoConfiguration 中 - 文档中明确指出了其中的一些功能,但似乎没有。

【讨论】:

  • 所以我更改为 1.0.1.RELEASE,移动了我所有的 html、样式表,并删除了 Bean templateResolver 和 Bean templateEngine。请参阅上面的更新问题。但是,现在无论我将它们放在 /src/main/resources/ 下的什么位置,都不会显示 CSS/JS/图像。我现在收到诸如“NetworkError:404 Not Found - “localhost:9001/resources/assets/css/…”之类的错误,当网络资产位于 WEB-INF/ 下时,tomcat 可以找到它们,但现在这些资源(减去 html 文件)找不到
  • 你查看documentation了吗?我更喜欢“src/main/resources/static”,但这取决于你。
  • 感谢您提供文档链接,我认为它确认我的资产位于正确的位置 (/src/main/resources/static/css...)。我没有定义 ServletContext,所以我认为这意味着我的 html 应该查看 js/css/etc 的根目录。但是无论我定义的路径如何,或者我将资源放在哪里都找不到。我用找不到 css 或 javascript 的示例 html 更新了我的问题。
  • 链接错误(resources/static/css 作为资源映射不存在)。试试 /css 等
  • 谢谢,我很难理解 servlet 上下文。一旦我尝试创建 WAR 并进行部署,这是否需要更改?
【解决方案2】:

如果你遇到同样的异常

Caused by: java.lang.IllegalStateException: Cannot find template location: class path resource [templates/] (please add some templates or check your Thymeleaf configuration)

但是使用SpringBoot 1.2.0-RELEASE,可能只是需要创建一个目录src/main/resources/templates。

我从 SpringBoot 1.1.9 升级到 1.2.0 并开始出现此异常。添加目录修复它。

【讨论】:

    【解决方案3】:

    或者,如果您遇到此异常并且不想使用thymeleaf,您可以使用...禁用它

    config/application.yml

    spring.groovy.template.check-template-location: false
    

    更多最新版本的 spring,实际上会在堆栈跟踪中告诉你这一点......

    Caused by: java.lang.IllegalStateException: Cannot find template location: classpath:/templates/ (please add some templates, check your Groovy configuration, or set spring.groovy.template.check-template-location=false)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-22
      • 2014-03-30
      • 1970-01-01
      相关资源
      最近更新 更多