【发布时间】:2014-06-09 06:38:10
【问题描述】:
默认的 scala 插件任务流在 Scala 之前编译 Java,因此在 Java 中导入 Scala 源代码会导致“错误:找不到符号”。
【问题讨论】:
标签: java scala compiler-errors gradle cross-compiling
默认的 scala 插件任务流在 Scala 之前编译 Java,因此在 Java 中导入 Scala 源代码会导致“错误:找不到符号”。
【问题讨论】:
标签: java scala compiler-errors gradle cross-compiling
我找到了以下 sourceSet 配置来解决问题:
sourceSets {
main {
scala {
srcDirs = ['src/main/scala', 'src/main/java']
}
java {
srcDirs = []
}
}
这是因为 scala 源集可以同时包含 java 和 scala 源。
【讨论】:
src/main/scala,将剩余的 Java 代码(如果有)放入 src/main/java。
compileScala.options 而不是 compileJava.options 才能影响联合编译 Java 代码的 Java 编译选项。 (Scala 编译选项通过compileScala.scalaCompileOptions 控制。)您可能希望将任何此类配置应用于所有编译任务(例如tasks.withType(ScalaCompile) { options ... })。
srcDirs 中包含 src/main/java,那么将 Java srcDirs 设置为空数组很重要。
如果你的java代码使用了Lombok等外部库,使用scala编译器构建java类会失败,因为scala编译器不知道注解。
我的解决方案是改变任务依赖,在Java之前编译Scala。
tasks.compileJava.dependsOn compileScala
tasks.compileScala.dependsOn.remove("compileJava")
现在任务compileScala 在compileJava 之前运行,就是这样。
如果你的java代码依赖scala代码,你需要多做两步,
分离scala和java的输出文件夹,
sourceSets {
main {
scala {
outputDir = file("$buildDir/classes/scala/main")
}
java {
outputDir = file("$buildDir/classes/java/main")
}
}
将 scala 输出添加为 compileJava 的依赖项,
dependencies {
compile files("$sourceSets.main.scala.outputDir")
}
【讨论】:
对于 gradle kotlin dsl 你可以使用这块
sourceSets {
main {
withConvention(ScalaSourceSet::class) {
scala {
setSrcDirs(listOf("src/main/scala", "src/main/java"))
}
}
java {
setSrcDirs(emptyList<String>())
}
}
test {
withConvention(ScalaSourceSet::class) {
scala {
setSrcDirs(listOf("src/test/scala", "src/test/java"))
}
}
java {
setSrcDirs(emptyList<String>())
}
}
}
【讨论】:
在这里发布未来的更新,因为它可以节省我一天的时间。
gradle 6 不支持任务依赖修改,但是你可以这样做:
// to compile Java after Scala
tasks.compileScala.classpath = sourceSets.main.compileClasspath
tasks.compileJava.classpath += files(sourceSets.main.scala.classesDirectory)
这里是documentation。
【讨论】: