开发者社区 问答 正文

Gradle:如何从jar中排除资源并通过IDEA运行

我最近在一个7年以上的项目中开始了新工作,该项目使用Ant / Ivy进行依赖关系和构建管理。

我的任务是将其转换为Gradle,但结构有点不合常规。

它的布局是这样的:

|- 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中,这使得调试和测试都可以找到它们。它将两个资源目录都复制到输出lib文件夹,并将它们添加到运行脚本中的classpath中。

除了将资源仍复制到已构建的.jar中之外,上述工作正常。这些将覆盖外部文件夹配置,因此不会。

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

如果我现在只运行assemble构建的项目,那正是我想要的,但是IDE现在无法运行调试器或测试成功,因为它无法找到下面缺少的文件build/resources/main

我也尝试过idea插件设置资源路径,但无济于事。

有办法吗?

展开
收起
垚tutu 2019-12-19 16:46:51 1111 分享 版权
阿里云 AI 助理回答

在将Ant/Ivy项目迁移到Gradle时,遇到的资源处理问题确实需要细致调整以确保IDE和构建过程都能正常工作。根据你的描述,你希望保持资源文件外部于生成的JAR,并且让IDE能够找到这些资源以便于调试和测试。以下是一些建议来解决这个问题:

1. 配置sourceSets与processResources

你已经正确地设置了sourceSets来指定资源目录,但可能需要进一步细化processResources任务来确保资源被正确复制到构建目录,同时不包含在最终的JAR中。

sourceSets {
    main {
        java {
            srcDirs 'core/src'
        }
        resources {
            srcDirs 'conf', 'res'
            // 可以考虑排除不需要打包进jar的资源
        }
    }
    test {
        java {
            srcDirs 'core/test'
        }
    }
}

// 复制资源到特定位置,而不是默认的JAR结构内
processResources {
    from('conf') {
        into('build/resources/main/conf')
    }
    from('res') {
        into('build/resources/main/res')
    }
    // 确保这些资源不会被包含进JAR
    exclude '**/*'
}

2. 自定义jar任务排除资源

你已经尝试了通过jar任务的processResources排除所有资源,但是这影响到了IDE识别资源。可以尝试更精确地控制JAR内容,而不是完全排除资源。

jar {
    // 排除特定资源目录,如果它们被错误地包含
    exclude 'conf/**'
    exclude 'res/**'
}

3. 配置IDEA插件

确保IDEA插件配置正确地指向资源目录。你可以使用idea插件来帮助设置正确的模块结构。

apply plugin: 'idea'

idea {
    module {
        // 明确指定资源目录
        resourceDirs += file('conf')
        resourceDirs += file('res')
    }
}

4. 调整运行/测试配置

对于IDE中的运行和测试配置,确保它们知道如何访问这些外部资源。在IntelliJ IDEA中,可以通过修改运行配置的“Working Directory”或添加VM选项(例如 -Djava.resource.path=lib/conf:lib/res)来指导IDE查找资源。

5. 使用Task来管理资源复制

如果你需要更精细的控制,可以创建自定义任务来专门处理资源的复制逻辑,确保在不同环境下(如开发、测试、部署)资源都被正确处理。

结论

通过上述步骤,你应该能实现资源在构建过程中被正确处理,既不在最终的JAR包中,又能在IDE中被正确识别用于调试和测试。关键是平衡好Gradle配置与IDE集成,确保资源路径对两者都是透明且可访问的。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答