Spring 工具套件和 Gradle - 设置以使用来自 STS 内部的正确资源
Spring Tools Suite and Gradle - Setup to use correct resources from inside STS
我在 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 或单元 tests/integration 从命令行测试(通过 gradle 构建),一切似乎都使用了正确的资源。这让我相信 STS/Eclipse 处理 gradle.
的方式存在问题
有人知道如何配置 STS 在使用 gradle 时使用正确的资源源文件夹吗?
我想我的问题可能与(或相同?), https://issuetracker.springsource.com/browse/STS-3882, https://issues.gradle.org/browse/GRADLE-1777
我也尝试了此处找到的解决方案,但这似乎只能修复 Maven 构建:
I think my problem may be related to...
是的,它是相关的,但在我看来并不相同。该问题是由运行时类路径不正确引起的。此问题是来自 eclipse 项目构建器的错误,因此它是一个编译时问题。
虽然这些问题是密切相关的。根据您的观点,您可以说它们是相同的(测试和编译时类路径的错误混合)。
这里,具体来说,问题是 eclipse 构建器试图将它在源文件夹中找到的所有资源复制到项目的单个输出文件夹中。每个源文件夹都有一个 'application.properties'。构建器警告它无法复制其中的一些,因为一个会覆盖另一个。
我认为这个问题可能有解决方案。但这是一个真正应该来自 Gradle + ( BuildShip | STS Gradle 工具) 而不是来自你的解决方案。
在 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 进行。
我不确定这是否值得,因为您可能仍然会受到运行时类路径问题的影响(因为这些文件夹仍将添加到您的运行时类路径中,您的运行时类路径最终将有两个appication.properties 个资源,其中一个 'shadow' 另一个。参见:https://bugs.eclipse.org/bugs/show_bug.cgi?id=482315)
我想说,正确的做法是 add a comment 我链接的问题,希望他们尽快修复它,因为你只能通过破解 build.gradle 来做这么多文件修改 .classpath(这不能解决运行时类路径问题,但为了解决运行时类路径问题,他们必须配置源文件夹以定位单个输出文件夹,类似于 m2e 所做的)。
我想将此添加为对@Kris 的回答的评论,但它太长了。
我通过将下面的代码添加到我的 build.gradle
文件中解决了运行时 class 路径问题。该代码为 Spring 启动应用程序 class 生成一个 Eclipse 启动配置,并且仅包含 runtime
class 路径(即没有测试 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")
添加到我的测试应用程序 class 并将 @ActiveProfiles("test")
添加到我的测试 classes.
我在 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 或单元 tests/integration 从命令行测试(通过 gradle 构建),一切似乎都使用了正确的资源。这让我相信 STS/Eclipse 处理 gradle.
的方式存在问题有人知道如何配置 STS 在使用 gradle 时使用正确的资源源文件夹吗?
我想我的问题可能与(或相同?)
我也尝试了此处找到的解决方案,但这似乎只能修复 Maven 构建:
I think my problem may be related to...
是的,它是相关的,但在我看来并不相同。该问题是由运行时类路径不正确引起的。此问题是来自 eclipse 项目构建器的错误,因此它是一个编译时问题。
虽然这些问题是密切相关的。根据您的观点,您可以说它们是相同的(测试和编译时类路径的错误混合)。
这里,具体来说,问题是 eclipse 构建器试图将它在源文件夹中找到的所有资源复制到项目的单个输出文件夹中。每个源文件夹都有一个 'application.properties'。构建器警告它无法复制其中的一些,因为一个会覆盖另一个。
我认为这个问题可能有解决方案。但这是一个真正应该来自 Gradle + ( BuildShip | STS Gradle 工具) 而不是来自你的解决方案。
在 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 进行。
我不确定这是否值得,因为您可能仍然会受到运行时类路径问题的影响(因为这些文件夹仍将添加到您的运行时类路径中,您的运行时类路径最终将有两个appication.properties 个资源,其中一个 'shadow' 另一个。参见:https://bugs.eclipse.org/bugs/show_bug.cgi?id=482315)
我想说,正确的做法是 add a comment 我链接的问题,希望他们尽快修复它,因为你只能通过破解 build.gradle 来做这么多文件修改 .classpath(这不能解决运行时类路径问题,但为了解决运行时类路径问题,他们必须配置源文件夹以定位单个输出文件夹,类似于 m2e 所做的)。
我想将此添加为对@Kris 的回答的评论,但它太长了。
我通过将下面的代码添加到我的 build.gradle
文件中解决了运行时 class 路径问题。该代码为 Spring 启动应用程序 class 生成一个 Eclipse 启动配置,并且仅包含 runtime
class 路径(即没有测试 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")
添加到我的测试应用程序 class 并将 @ActiveProfiles("test")
添加到我的测试 classes.