【问题标题】:Splitting all output directories in Gradle拆分 Gradle 中的所有输出目录
【发布时间】:2017-06-15 23:04:33
【问题描述】:

Gradle 4.0 昨天发布了,我为此更新了我的项目。

现在我收到以下警告:

Gradle 现在为每种 JVM 语言使用单独的输出目录,但是 此构建假定来自源的所有类的单个目录 放。此行为已被弃用并计划删除 在 Gradle 5.0 中

我想为每种语言使用单独的输出目录。我需要进行哪些更改才能实现这一目标?


我尝试过的事情:

  • gradle clean 后跟 gradle build
  • 删除构建目录然后运行gradle build
  • 删除 gradle 和 build 目录然后运行gradle

相关GitHubissue


Gradle 插件:

  • java
  • 日食
  • 想法
  • org.springframework.boot

【问题讨论】:

  • 您使用的是哪些 Gradle 插件?
  • java、eclipse、idea、org.springframework.boot
  • 你试过在 Spring Boot 项目中提问吗?
  • 不。不过我很确定是他们……

标签: java gradle build.gradle


【解决方案1】:

Gradle 4.0 为每种 JVM 语言引入了多个 sourceSets,以启用远程构建缓存。使用java 插件,您的build/classes/main 应变为build/classes/java/mainbuild/classes/test 应变为build/classes/java/test,等等。

您看到的警告在 DefaultSourceSets.java 中定义

因此,如果您的项目或您的build.gradle 中的任何插件调用DefaultSourceSetOutput.getClassesDir()(或访问classesDir),您会收到此警告。

解决方案 1

使用

sourceSets.main.output.classesDir = new File(buildDir, "classes/main")

对应于:

@Override
public boolean isLegacyLayout() {
    return classesDir!=null;
}

@Override
public void setClassesDir(File classesDir) {
    setClassesDir((Object)classesDir);
}

@Override
public void setClassesDir(Object classesDir) {
    this.classesDir = classesDir;
    this.classesDirs.setFrom(classesDir);
}

请注意,SourceSetOutput.javagetClassesDir() 标记为已弃用。

因此,在您项目中的所有插件都支持 Gradle 4.0 之前,您应该坚持使用解决方法并忽略弃用警告。

另一个问题是测试文件。 如果您不想使用新布局build/classes/mainbuild/classes/java/test),您也应该调整测试路径:

sourceSets.main.output.classesDir = new File(buildDir, "classes/main")
sourceSets.test.output.classesDir = new File(buildDir, "classes/test")

更新 如果检测到 Gradle 4.x,IDEA 的用户可能会注意到 IDE 开始使用单独的 out 目录进行构建。如果您在 IDEA 之外运行应用程序,那将不可能 重新加载热门应用程序。要修复该添加并重新导入:

subprojects {
    apply plugin: 'idea'
    // Due to Gradle 4.x changes (separate output directories per JVM language)
    // Idea developers refuse to reuse Gradle classpath and use own 'out/' directory.
    // Revert to old behavior to allow Spring Devtool to work with using fast Idea compiler.
    // https://youtrack.jetbrains.com/issue/IDEA-175172
    // Alternatively use native Gradle builds or bootRun.addResources = true
    // To use this feature push Ctrl+Shift+F9 to recompile!
    // Be aware that Idea put resources into classes/ directory!!
    idea.module.inheritOutputDirs = false
    idea.module.outputDir = sourceSets.main.output.classesDir
    idea.module.testOutputDir = sourceSets.test.output.classesDir
}

请注意,IDEA 将资源与 .class 文件放在同一目录中,因此您的 Gradle 类路径可能会损坏。只需对使用 IDEA 内置构建命令(Ctrl+Shift+F10 等)的模块执行 gradle clean

【讨论】:

  • 出于其他原因,我们已经在使用 setClassesDir,但我们还是收到了警告。我实际上尝试删除我们对它的调用,认为这可能是警告的原因,哈哈。
  • @Trejkaz 原因是setClassesDir 现在产生完全相同的警告:github.com/gradle/gradle/blob/…
  • 也许我的意思是setClassesDirs,考虑到上下文。但是我们当前的构建不再有任何一个调用,我仍然看到相同的警告。 :) (我应该注意,我认为对我们来说实际上发生的事情是,一些 plugin 正在调用已弃用的方法之一......)
  • 您在哪里声明这是官方推荐的解决方案?
  • @Alex 这是官方不推荐 / 弃用的方式,应该不惜一切代价避免,除非你明白你在做什么))现代Idea 应该了解多语言 Gradle 构建,我需要验证这一点并抛出旧的解决方法。
【解决方案2】:

这是由于 Gradle 4.0 中引入的更改:如果有多个语言源,它现在使用单独的输出目录。

要返回旧行为并消除警告,请将其插入您的 build.gradle:

// Change the output directory for the main source set back to the old path sourceSets.main.output.classesDir = new File(buildDir, "classes/main")

参考:https://docs.gradle.org/4.0/release-notes.html#multiple-class-directories-for-a-single-source-set

【讨论】:

  • 顺便说一句,忘了提,但是当插件赶上 Gradle 4.0 中引入的更改并将新的构建目录添加到它们的定义中时,这些警告可能会消失。即:对于java插件,从src/main/java` -> build/classes/mainsrc/main/java` -> build/classes/java/main
【解决方案3】:

我的情况有点具体,因为输出类目录用于构造命令行执行的类路径条目。但也许这会对某人有所帮助。

我决定连接所有输出目录。我所做的改变是形式

sourceSets.integrationTest.output.classesDir

ext {
    classpathSeparator = System.properties['os.name'].toLowerCase().contains('windows')?";":":"
}
...
sourceSets.integrationTest.output.classesDirs.join(classpathSeparator)

【讨论】:

    【解决方案4】:

    例如,如果你混合使用 Java、Kotlin 和 Groovy,项目结构应该如下所示:

    root/
        src/
           main/
                java/
                kotlin/
                groovy/
           test/
                java/
                kotlin/
                groovy/
    

    在你build.gradle中你必须指定特定语言所需的插件。

    apply plugin: 'java'
    apply plugin: 'groovy'
    apply plugin: 'kotlin'
    

    【讨论】:

    • 您只解释了单独的输出目录是什么,而不是如何实现。这仍然没有解释如何在 Gradle 构建文件中设置输出目录或如何摆脱警告。
    • 我也怀疑输出目录应该是源目录(src)的子目录。
    • 我已包括:apply plugin: 'java',正如@mantono 所说,它没有禁用警告。
    猜你喜欢
    • 2022-10-05
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    相关资源
    最近更新 更多