【问题标题】:Spring Tools Suite and Gradle - Setup to use correct resources from inside STSSpring Tools Suite 和 Gradle - 设置以使用 STS 内部的正确资源
【发布时间】:2016-03-24 04:01:44
【问题描述】:

我在 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 下找到的资源。

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

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

如果我从命令行(通过 gradle build)将应用程序作为 JAR 或单元测试/集成测试运行,一切似乎都使用了正确的资源。这让我相信这是 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

【问题讨论】:

    标签: gradle spring-tool-suite


    【解决方案1】:

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

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

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

    这里,具体来说,问题在于 Eclipse 构建器试图将它在源文件夹中找到的所有资源复制到项目的单个输出文件夹中。每个源文件夹都有一个“application.properties”。构建器警告说它不能复制其中一些,因为一个会覆盖另一个。

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

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

    例如,这是 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 所做的)。

    【讨论】:

    • 我在 Eclipse bugzilla 票证中添加了一条评论,引用了这个问题:bugs.eclipse.org/bugs/show_bug.cgi?id=482315#c8
    • 好吧,我看到您已经与这个运行时类路径问题作斗争了很长一段时间。感谢您对问题的验证。我认为我的设置肯定有问题,因为找到相关问题并不容易,并且在创建新项目时我会立即看到这个问题。现在我只是在 STS 之外运行。
    【解决方案2】:

    我会将此作为评论添加到@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") 添加到我的测试类中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-29
      • 2018-02-05
      • 2014-03-13
      • 2020-02-01
      • 2011-08-06
      • 2018-01-04
      • 1970-01-01
      • 2011-01-21
      相关资源
      最近更新 更多