java - 在 Gradle 构建中兼顾 Scala、Antlr 和 Java

标签 java scala gradle antlr

我有一个项目,设置如下: 1.src/main/antlr下的antlr文件 2.src/main/scala下的Scala文件 3、src/main/java下的java文件

Java 代码依赖于 Scala 生成的类,而这些类又依赖于 Antlr 生成的源。

复制此布局以进行测试。除了我正在尝试的调整(如链接文件中所示)之外,我没有定义其他源集。

我们使用 Antlr 3,因此无法使用 Gradle 附带的插件。不过我们确实使用了 Scala 插件。根据许多建议,我已经颠倒了 Scala 和 Java 编译之间的依赖关系,并修改了 Scala srcDirs 以包含 $buildDir/generated/src ,Antlr 任务在该目录下转储其输出以及 Java 源代码,从而使 scalac 进行联合编译。

我现在面临的问题是“测试”任务看不到任何生成的文件,即使我在构建目录下看到生成的类。奇怪的部分似乎是测试编译成功,但 scala/Antlr 类似乎不在类路径上。

这是我的 gradle 构建脚本。

sourceCompatibility = '1.6'
apply plugin: 'java'
apply plugin: 'scala'

configurations {
    antlr3
    scalaBuild
}

sourceSets {
    test {
        java{
            runtimeClasspath = sourceSets.test.runtimeClasspath + files("${buildDir}/jars")
        }
    }
}

def antlrSource = "src/main/antlr"
def antlrOutput = "$buildDir/generated/src"

dependencies {
    antlr3 (
        [group: 'org.antlr', name: 'antlr', version: '3.3']
    )
    compile (
        [group: 'org.scala-lang', name: 'scala-library', version: '2.9.2'],
        [group: 'com.googlecode.kiama', name: 'kiama_2.9.2', version: '1.2.0'],
        [group: 'net.sf.jgrapht', name: 'jgrapht', version: '0.8.3'],           
        [group: 'org.antlr', name: 'antlr-runtime', version: '3.3'],
        [group: 'org.antlr', name: 'stringtemplate', version: '3.2.1'],
        [group: 'com.beust', name: 'jcommander', version: '1.7']
    )
    testCompile (
        [group: 'org.scalatest', name: 'scalatest_2.9.2', version: '1.8'],
        [group: 'org.antlr', name: 'gunit', version: '3.3']
    )
}

test.doFirst {
    configurations.testRuntime.each{ println it }
}

task generateGrammarSource {
    description = "Generates Java sources from Antlr3 grammars."
    inputs.dir file(antlrSource)
    outputs.dir file(antlrOutput)
} << {
  mkdir(antlrOutput)
  sourceSets.main.scala.srcDirs = sourceSets.main.scala.srcDirs + ["src/main/java", antlrOutput]
  sourceSets.main.java.srcDirs = []

  def grammars = fileTree(antlrSource).include("**/*.g")

  ant.java(classname: 'org.antlr.Tool', fork: true, classpath: "${configurations.antlr3.asPath}") {
     arg(line: "-o ${antlrOutput}")
     arg(line: grammars.files.join(" "))
  }
}

task extraJar(type: Jar, dependsOn: compileScala) {
    archiveName = "duplicate-classes.jar"
    destinationDir = file("${buildDir}/jars")
    from "${buildDir}/classes"
}

artifacts {
    scalaBuild extraJar
}

compileScala.taskDependencies.values = compileScala.taskDependencies.values - 'compileJava'
compileJava.dependsOn(compileScala)
compileScala.dependsOn generateGrammarSource

有人可以指导我解决这个问题吗?

最佳答案

构建脚本有几种味道:

  1. 目前尚不清楚为什么将 files("${buildDir}/jars") 添加到测试运行时类路径。
  2. 它是 sourceSets.test.runtimeClasspath,而不是 sourceSets.test.java.runtimeClasspath
  3. 任务 generateGrammarSource 的类型应为 JavaExec,而不是调用 ant.java 的任务操作。
  4. Scala 源目录需要在配置阶段而不是执行阶段进行配置。
  5. 目前尚不清楚为什么 compileScala->compileJava 依赖项会颠倒。在当前的构建中,这绝对是不必要的,因为在“删除”源目录以支持联合编译后,compileJava 没有任何事情可做。

也就是说,如果没有可重现的示例,很难说到底是什么导致了当前的问题。我要做的第一个改进是在任务操作之外的顶层声明 Scala 源目录。这解决了上面的 4。

关于java - 在 Gradle 构建中兼顾 Scala、Antlr 和 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20505086/

相关文章:

android - Jenkins android 构建失败并显示消息 : FATAL: The Gradle wrapper has not been found in these directories

spring-boot - Spring Boot应用程序部署到外部tomcat中的类未找到异常

java - 用于 Java 项目的 Hudson 和 CruiseControl 有什么区别?

java - 为什么我们不在 bindView 中使用 moveToFirst()?

java - 将对象分配给java中的另一个对象

scala - Scala试试,其他,除 block

scala - 玩!斯卡拉 : How to disable actor modules loaded at the start of the application when testing?

java - jSTL的c :url tag?的目的是什么

scala - 当参数 `list.indexWhere` 为负数时出现 `from` 的奇怪结果

android - 无法访问普通类中的 flavor 类