简体   繁体   English

如何从 Gradle 中的 JAR 中排除资源并通过 IntelliJ 运行

[英]How to exclude resources from the JAR in Gradle and also run via IntelliJ

I recently started work on a 7+ year old project which uses Ant/Ivy for dependency & build management.我最近开始从事一个已有 7 年历史的项目,该项目使用 Ant/Ivy进行依赖和构建管理。 I'm tasked with converting this to Gradle but the structure is a bit unconventional:我的任务是将其转换为 Gradle ,但结构有点不同寻常:

|- projectRoot
  |- folderA
  |- folderB
  |- projectX
    |- conf
    | |- file1.txt
    |
    |- core
    |  |- src
    |  | |- App.java
    |  |
    |  |- test
    |    |- AppTest.java
    |
    |- res
    | |- file2.txt
    |
    |- ivybuild.xml
    |- ivysettings.xml

The Ivy build process is fairly straight forward, the resulting dist folder looks like this: Ivy 构建过程相当简单,生成的 dist 文件夹如下所示:

|- dist
  |- proj.jar
  |- lib
  |  |- dep1.jar
  |  |- dep2.jar
  |
  |- conf
  |  |- file1.txt
  |- res
     |- file2.txt

No resources are build in to the resulting JAR as some configurations are applied from a separate repository during deployment, thus the resources must stay external to the JAR.由于某些配置在部署期间从单独的存储库应用,因此生成的 JAR 中没有构建资源,因此资源必须保留在 JAR 外部。

I'm struggling to find a way to achieve this while also letting the IDE (Intellij IDEA) successfully locate the resources during debugging and running tests.我正在努力寻找一种方法来实现这一目标,同时让 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')
}

With the above I'm able to run/test the project successfully as all files from 'conf' and 'res' are copied into 'build/resources/main' which allows both debugging and tests to locate them.通过以上内容,我能够成功运行/测试项目,因为来自“conf”和“res”的所有文件都被复制到“build/resources/main”中,这允许调试和测试来定位它们。 It copies both resource directories to the output lib folder and these are added to the classpath in the run script.它将两个资源目录复制到输出 lib 文件夹,并将它们添加到运行脚本中的类路径。

The above works except that the resources are still being copied into the built JAR.上面的工作除了资源仍然被复制到构建的 JAR 中。 These override the external folder configurations so it will not do.这些覆盖了外部文件夹配置,所以它不会做。

jar {
    processResources {
        exclude("*")
    }
}

If I now run just assemble then the built project is exactly how I want it, however the IDE now cannot run the debugger or tests successfully as it cannot locate the files missing under build/resources/main如果我现在只运行assemble那么构建的项目正是我想要的,但是 IDE 现在无法成功运行调试器或测试,因为它无法找到build/resources/main下丢失的文件

I have also tried the idea plugin to set the resource paths but to no avail.我也尝试过idea插件来设置资源路径但无济于事。

Is there a way?有办法吗?

Excluding Resources from the JAR with Gradle使用 Gradle 从 JAR 中排除资源

Example build.gradle示例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")
        }
    }
}

  • Resources are found during gradle rungradle run期间找到资源
  • Resources are found during gradle testgradle test期间找到资源
  • Built JAR does not contain the resources内置的 JAR 不包含资源
  • Resources copied into example.zip/lib/conf & .../lib/res资源复制到example.zip/lib/conf & .../lib/res
  • Resource content are added to the classpath in the generated build scripts资源内容添加到生成的构建脚本中的类路径
  • Running tests via IntelliJ UI does work ( right click -> run tests eg)通过 IntelliJ UI 运行测试确实有效(例如right click -> run tests

BUT :但是

  • Running via IntelliJ UI does not work ( right click -> run main() eg)通过 IntelliJ UI 运行不起作用(例如right click -> run main()

Resolution :分辨率

  • The IntelliJ Gradle Plugin allows right click -> run and right click -> debug IntelliJ Gradle 插件允许right click -> runright click -> debug
  • The above adds a configuration to IntelliJ run panel as a decent substitute以上为 IntelliJ 运行面板添加了一个配置作为一个不错的替代品

FYI: As a gradle newbie, I have recently been caught by this when trying just exclude a few src/main/resources files from the jar仅供参考:作为一个 gradle 新手,我最近在尝试从 jar 中排除一些 src/main/resources 文件时被这个问题所吸引

// Exclude all resources from the jar
jar {
    processResources.exclude('*')
}

Actually does more than exclude from the jar - it excludes from the build entirely, in that they do not exist in build/resources/;实际上不仅仅是从 jar 中排除 - 它完全从构建中排除,因为它们不存在于 build/resources/ 中; so may impact your testing etc.所以可能会影响你的测试等。

In Kotlin DSL在 Kotlin DSL 中

tasks.jar.configure {
    exclude("**/node_modules/")
    exclude("web/package*.json")
    exclude("web/*.config.js")
    archiveFileName.set("my.jar")
    ...
}

I got a solution, and it doesn't impact the testing.我得到了一个解决方案,它不会影响测试。

jar {
    exclude { FileTreeElement el -> el.file.toPath().startsWith("$buildDir/resources/main") }
}

For me, this works:对我来说,这有效:

tasks.withType<Jar> {
    exclude("application-*.yml") // for src/main/resources/application-*.yml, this is already from root directory.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM