Spring Tools Suite和Gradle - 设置从STS内部使用正确的资源

时间:2015-12-17 15:52:02

标签: gradle spring-tool-suite

我在Spring Tools Suite(3.7.2 RELEASE)中安装了Spring Boot Gradle项目,其中包含以下源文件夹:

- src/integration-test/java
- src/integration-test/resources 
- src/main/java
- src/main/resources
- src/test/java
- src/test/resources`

每当我从STS中运行应用程序或单元测试时,我发现STS正在使用src/integration-test/resources下的资源。

我在STS中看到存在于所有3个资源源文件夹中的文件的重复资源警告。例如,我在所有3个源文件夹中都有一个application.properties,我看到如下:

The resource is a duplicate of src/integration-test/resources/application.properties and was not copied to the output folder

如果我从命令行运行应用程序作为JAR或单元测试/集成测试(通过gradle构建),一切似乎都使用正确的资源。这让我相信STS / Eclipse如何处理gradle是一个问题。

有人知道在使用gradle时如何配置STS以使用正确的资源来源文件夹吗?

我认为我的问题可能与(或与?相同)Spring Boot incorrectly loads test configuration when running from eclipse+gradlehttps://issuetracker.springsource.com/browse/STS-3882https://issues.gradle.org/browse/GRADLE-1777

有关

我也试过这里找到的解决方案,但这似乎只能修复Maven构建: Spring Tool Suite finds spring-boot integration test configuration and does not start main application

2 个答案:

答案 0 :(得分:2)

  

我认为我的问题可能与......有关。

是的,这是相关的,但在我看来并不相同。该问题是由运行时类路径不正确引起的。这个问题是来自eclipse项目构建器的错误,因此它是一个编译时问题。

但问题密切相关。根据您的观点,您可以说它们是相同的(测试和编译时类路径的混合不正确)。

具体来说,问题是eclipse构建器尝试将它在源文件夹中找到的所有资源复制到项目的单个输出文件夹中。每个源文件夹都有一个'application.properties'。构建器警告它无法复制其中一些因为会覆盖另一个。

我认为这个问题可能有一个解决方案。但它确实应该来自Gradle +(BuildShip | STS Gradle Tooling),而不是来自你。

在Eclipse中可以单独配置每个源文件夹以定位特定的输出文件夹。 Maven + M2E正在这样做,但是Gradle +(BuildsShip | STS Gradle Tooling)combdos没有。

例如,这是maven配置测试资源文件夹时放入eclipse .classpath文件的内容:

    <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
         <attributes>
            <attribute name="maven.pomderived" value="true"/>
         </attributes>
     </classpathentry>

注意它是如何显式设置该条目的输出文件夹(与项目的默认输出文件夹不同)。

您可以通过以类似方式修改gradle项目的.classpath来自行解决问题。通过手动或从build.gradle进行操作。

我不确定这是否值得,因为您可能仍会受到运行时类路径问题的影响(因为这些文件夹仍将添加到您的运行时类路径中,您的运行时类路径最终会有两个应用程序。属性资源,将“遮蔽”另一个属性资源。请参阅:https://bugs.eclipse.org/bugs/show_bug.cgi?id=482315

我想说,对于我链接的问题,正确的做法是add a comment,并希望他们尽快修复它,因为只有通过黑客攻击build.gradle文件来修改.classpath(这不能解决运行时类路径问题,但为了解决运行时类路径问题,他们必须配置源文件夹以定位单个输出文件夹,类似于m2e所做的那样)。

答案 1 :(得分:0)

我会将此作为评论添加到@Kris的答案,但这太长了。

我已经通过将以下代码添加到我的build.gradle文件中解决了运行时类路径问题。该代码为Spring Boot应用程序类生成Eclipse启动配置,并且仅包含runtime类路径(即没有测试JAR)。

我的项目使用Gradle 'eclipse'插件生成Eclipse项目文件(然后我将其导入Eclipse)。运行eclipseClasspath Gradle目标将在项目的根目录中生成启动文件。

def mainClassName = "com.example.MyApplication"
task eclipseApplicationLaunch {
    group "IDE"
    description "Generate an Eclipse launch configuration file for the Spring Boot application class"
}
eclipseApplicationLaunch << {
    def writer = new FileWriter("${mainClassName.substring(mainClassName.lastIndexOf(".")+1)}.launch")
    def xml = new groovy.xml.MarkupBuilder(writer)
    xml.doubleQuotes = true 

    xml.launchConfiguration(type: "org.eclipse.jdt.launching.localJavaApplication") { 
        listAttribute(key:"org.eclipse.debug.core.MAPPED_RESOURCE_PATHS") {
            listEntry(value:"/${project.name}/src/main/java/${mainClassName.replace(".","/")}.java")
        }
        listAttribute(key:"org.eclipse.debug.core.MAPPED_RESOURCE_TYPES") {
            listEntry(value:"1")
        }
        listAttribute(key:"org.eclipse.jdt.launching.CLASSPATH") {
            listEntry(value:"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<runtimeClasspathEntry containerPath=\"org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/\" javaProject=\"${project.name}\" path=\"1\" type=\"4\"/>\r\n")
            listEntry(value:"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<runtimeClasspathEntry path=\"3\" projectName=\"${project.name}\" type=\"1\"/>\r\n")
            configurations.runtime.resolvedConfiguration.resolvedArtifacts.each { artifact ->
                def filePath = artifact.file.canonicalPath.replace("\\","/")
                listEntry(value:"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n<runtimeClasspathEntry externalArchive=\"${filePath}\" path=\"3\" type=\"2\"/>\r\n")
            }
        }
        booleanAttribute(key:"org.eclipse.jdt.launching.DEFAULT_CLASSPATH", value:"false")
        stringAttribute(key:"org.eclipse.jdt.launching.MAIN_TYPE", value:"${mainClassName}")
        stringAttribute(key:"org.eclipse.jdt.launching.PROGRAM_ARGUMENTS", value:"--spring.profiles.active=local --spring.config.location=conf/")
        stringAttribute(key:"org.eclipse.jdt.launching.PROJECT_ATTR", value:"${project.name}")
        stringAttribute(key:"org.eclipse.jdt.launching.VM_ARGUMENTS", value:"-Djava.net.preferIPv4Stack=true")
    }
    writer.close()
}
eclipseClasspath.dependsOn eclipseApplicationLaunch

我没有按照Kris的建议修改Eclipse .classpath文件。相反,我已将@Profile("test")添加到我的测试应用程序类中,并将@ActiveProfiles("test")添加到我的测试类中。