Gradle - Groovy 和 Java 类依赖关系 - 编译

2022-09-04 06:33:27

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

当我不使用src / java作为main>groovy>sourceSet部分中的srcDir之一时,我会收到一个错误,说在时髦的文件/类中找不到类/符号。在ANT中,我们很容易先调用编译时髦目标,然后再调用编译java目标,但在Gradle中,我试图找到的是相同的目标。

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

我的:1.有没有其他方法可以做?对于 ex,以下方法应该有效:

   compileJava {
     dependsOn compileGroovy
   }

但是,这进入了一个无限循环。

使用doFirst进行编译Java任务怎么样:

compileJava {
      doFirst {
            compileGroovy
      }
}

这也不起作用。






build.gradle 这是有效的,但是编译Java在某种意义上变得无用,即使源代码有N no。src/java 或 src/java-test etc 树中的 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'
      }
   }
}

其他链接:如何让Gradle在Java测试之前编译Groovy测试


答案 1

Groovy(基本)插件使任务依赖于相应的任务,因为从Groovy调用Java比从Groovy调用Java更常见。如果你需要它反过来(或两种方式),联合编译是一个很好的解决方案。以下是一些改进(相对于您的版本)联合编译设置:GroovyCompileJavaCompile

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")
}

由于任务及其相应的任务写入同一输出目录,因此 Java 编译现在将在其编译类路径上具有已编译的 Groovy 代码。JavaCompileGroovyCompile

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


答案 2