Java 如何从Gradle中的JAR中排除资源并通过IntelliJ运行
我最近开始从事一个7年以上的项目,该项目使用Ant/Ivy进行依赖关系和构建管理。我的任务是将其转换为Gradle,但结构有点非传统:Java 如何从Gradle中的JAR中排除资源并通过IntelliJ运行,java,gradle,build,resources,Java,Gradle,Build,Resources,我最近开始从事一个7年以上的项目,该项目使用Ant/Ivy进行依赖关系和构建管理。我的任务是将其转换为Gradle,但结构有点非传统: |- projectRoot |- folderA |- folderB |- projectX |- conf | |- file1.txt | |- core | |- src | | |- App.java | | | |- test | |- AppTest
|- projectRoot
|- folderA
|- folderB
|- projectX
|- conf
| |- file1.txt
|
|- core
| |- src
| | |- App.java
| |
| |- test
| |- AppTest.java
|
|- res
| |- file2.txt
|
|- ivybuild.xml
|- ivysettings.xml
Ivy构建过程非常简单,生成的dist文件夹如下所示:
|- dist
|- proj.jar
|- lib
| |- dep1.jar
| |- dep2.jar
|
|- conf
| |- file1.txt
|- res
|- file2.txt
由于在部署期间从单独的存储库应用了一些配置,因此结果JAR中没有内置资源,因此这些资源必须位于JAR外部
我正在努力找到一种方法来实现这一点,同时让IDE(Intellij IDEA)在调试和运行测试期间成功地定位资源
sourceSets {
main {
java {
srcDir 'core/src'
}
resources {
srcDir 'conf'
srcDir 'res'
}
}
test {
java {
srcDir 'core/test'
}
}
}
processResources {
from 'conf' into 'lib/conf'
from 'res' into 'lib/res'
}
startScripts {
classpath += files('conf')
classpath += files('res')
}
有了以上这些,我能够成功地运行/测试项目,因为来自'conf'和'res'的所有文件都被复制到'build/resources/main'中,这允许调试和测试找到它们。它将两个资源目录复制到output lib文件夹,并将它们添加到运行脚本中的类路径中
除了仍在将资源复制到构建的JAR中之外,上面的方法是有效的。这些将覆盖外部文件夹配置,因此不会执行此操作
jar {
processResources {
exclude("*")
}
}
如果我现在只运行assembly
,那么生成的项目正是我想要的,但是IDE现在无法成功运行调试器或测试,因为它无法找到build/resources/main
我还尝试了idea
插件来设置资源路径,但没有成功
有办法吗 使用Gradle从JAR中排除资源
示例build.gradle
plugins {
id 'java'
id 'application'
}
// Project specifics
version '1.0-SNAPSHOT'
group 'com.example'
sourceCompatibility = 1.8
project.mainClassName = "core.ExampleApp"
dependencies {
testCompile 'junit:junit:4.12'
}
// Define the project source paths
sourceSets {
main.java {
srcDir 'core/src'
}
test.java {
srcDir 'core/test'
}
}
// Exclude all resources from the jar
jar {
processResources.exclude('*')
}
// Allows the 'test' task to see the directories on the classpath
test {
classpath += files('conf')
classpath += files('res')
}
// Allows the 'run' task to see the directories on the classpath
run {
classpath += files('conf')
classpath += files('res')
}
// Adds the directories to classpath in the start scripts
// They will have '$APP_DIR/lib/' prepended so they need to be copied into 'dist/lib/'
startScripts {
run {
classpath += files('conf')
classpath += files('res')
}
}
// Copy 'conf' and 'res' into the 'dist/lib' directory
distributions {
main {
contents {
from('conf').into("lib/conf")
from('res').into("lib/res")
}
}
}
- 在
gradle运行期间找到资源
- 在
gradle测试期间可以找到资源
- 构建的JAR不包含资源
- 资源复制到
&example.zip/lib/conf
../lib/res
- 资源内容被添加到生成的构建脚本中的类路径中
- 通过IntelliJ UI运行测试确实有效(
右键单击->运行测试
- 通过IntelliJ UI运行不起作用(
例如)右键单击->运行main()
- IntelliJ Gradle插件允许
和右键单击->运行
右键单击->调试
- 上面为IntelliJ run panel添加了一个配置,作为一个不错的替代
// Exclude all resources from the jar
jar {
processResources.exclude('*')
}
实际上不仅仅是从jar中排除,它完全从构建中排除,因为它们不存在于build/resources/中;因此可能会影响您在Kotlin DSL中的测试等
tasks.jar.configure {
exclude("**/node_modules/")
exclude("web/package*.json")
exclude("web/*.config.js")
archiveFileName.set("my.jar")
...
}
我找到了一个解决方案,它不会影响测试
jar {
exclude { FileTreeElement el -> el.file.toPath().startsWith("$buildDir/resources/main") }
}