【问题标题】:Gradle - Groovy and Java class dependency - CompileGradle - Groovy 和 Java 类依赖 - 编译
【发布时间】:2014-04-05 06:21:13
【问题描述】:

我的项目同时包含 Java(N 个文件)和 Groovy 代码(仅 1 个文件)。 Java 编译依赖于这个单个 Groovy 文件的类文件进行 Java 编译(compileJava 任务成功)。

当我不使用 src/java 作为 main>groovy> sourceSet 部分中的 srcDir 之一时,我收到一条错误消息,指出在 groovy 文件/类中找不到类/符号。在 ANT 中,我们很容易首先调用 compile-groovy 目标,然后再调用 compile-java 目标,但在 Gradle 中同样是我想要找到的。

我阅读了一些帖子,发现如果我将 main>java 部分设为 NULL 并为 main>java 指定 srcDir,即 main>groovy sourceSet 部分中的 src/java,那么它编译得很好。

我的?s: 1、有没有其他办法?例如,以下应该有效:

   compileJava {
     dependsOn compileGroovy
   }

不过,这会进入无限循环。

如何使用 doFirst 来执行 compileJava 任务:

compileJava {
      doFirst {
            compileGroovy
      }
}

这也不行。





build.gradle 这行得通,但是compileJava在某种意义上在这里变得无用,即使源代码有N号。 src/java 或 src/java-test 等树中的 java 文件。我知道这个构建脚本可以工作,但如果他/她不熟悉为什么 Groovy 的 sourceSet 必须将“src/java”作为其 srcDir 值,那么从逻辑上讲,它可能会给开发人员带来一些困惑。

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

sourceSets {
   main {
      groovy {
         srcDir 'src/groovy'
         srcDir 'src/java'
      }
      java {
       //The following needs to be commented out OR Gradle will always pick compileJava before compileGroovy
       //srcDir 'src/java'
       //srcDir 'src/java-test'
      }
   }
   test {
      groovy {
         srcDir 'test/groovy'
      }
      java {
         srcDir 'test/java'
      }
      resources {
         srcDir 'test/resources'
         srcDir 'conf'
      }
   }
   integrationTest {
      groovy {
         srcDir 'src/groovy-test'
      }
      java {
         srcDir 'src/java-test'
      }
      resources {
         srcDir 'test/resources'
         srcDir 'conf'
      }
   }
}

其他链接: How to make Gradle compile Groovy tests before Java tests

【问题讨论】:

  • 如果您使用默认设置,但将您的 Java 文件移动到 src/main/groovy 中是否有效?
  • 你的意思是,如果我在 sourceSets>main>groovy 中提到 src/java 并保持 sourceSets>main>java 不变(包含 src/java,因为它是 srcDir),那么它就不起作用。但是,如果您打算将所有 java 文件/with com/../.. 文件夹树从 src/java 移动到 src/groovy,那么它会起作用,因为 src/java 下没有 .java 然后即使提到 sourceSets>main>java srcDir = "src/java" 也不会做任何事情,对吧?

标签: java class groovy compilation gradle


【解决方案1】:

Groovy(基础)插件使GroovyCompile 任务依赖于相应的JavaCompile 任务,因为从Groovy 调用Java 比其他方式更常见。如果您需要相反的方式(或两种方式),联合编译是一个很好的解决方案。这是一个稍微改进的(在您的版本之上)联合编译设置:

sourceSets {
    main {
        groovy {
            // override the default locations, rather than adding additional ones
            srcDirs = ['src/groovy', 'src/java'] 
        }
        java {
            srcDirs = [] // don't compile Java code twice 
        }
    }
}

如果您更喜欢使用 Java->仅使用 Groovy 依赖项进行单独编译,则应该可以使用以下方法:

// since you aren't using the default locations
sourceSets {
    main {
        groovy {
            srcDirs = ['src/groovy']
        }
        java {
            srcDirs = ['src/java']
        }
    }
}

// remove GroovyCompile->JavaCompile task dependencies
tasks.withType(GroovyCompile) {
    dependsOn = [] 
}

// add JavaCompile->GroovyCompile task dependencies
tasks.withType(JavaCompile) { task ->  
    dependsOn task.name.replace("Java", "Groovy")
}

因为JavaCompile 任务及其对应的GroovyCompile 任务写入同一个输出目录,Java 编译现在将在其编译类路径中包含已编译的 Groovy 代码。

PS:不支持从另一个任务调用一个任务,如果你尝试可能会发生坏事。相反,您应该始终处理任务关系(dependsOnfinalizedBymustRunAftershouldRunAfter)。

【讨论】:

  • 正是我想要的。谢谢皮特。
  • 不幸的是,在较新的 gradle 版本中,仅更改依赖项不再起作用,因为现在 Java 和 Groovy 编译器有单独的输出目录。 Groovy 编译器仍然首先运行,但是 Java 编译器不会拾取已编译的 Groovy 类。 (我想避免联合编译,因为生成的字节码对于 Java 类略有不同,我希望它尽可能接近旧的构建版本。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 1970-01-01
  • 2014-10-07
  • 2017-09-11
  • 2018-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多