1. Java 源代码

Java 源代码 

sbt 支持编译 Java 源代码,但依赖跟踪仅限于已编译的类文件中的依赖项。

用法 

  • 默认情况下,compile 将编译 src/main/java 下的源代码。
  • 默认情况下,testCompile 将编译 src/test/java 下的源代码。

通过设置 javacOptions 将选项传递给 Java 编译器。

javacOptions += "-g:none"

与 Scala 编译器的选项一样,sbt 不会解析这些参数。多元素选项(例如 -source 1.5)的指定方式如下

javacOptions ++= Seq("-source", "1.5")

您可以使用 compileOrder 设置指定 Scala 和 Java 源代码的构建顺序。可能的值来自 CompileOrder 枚举:MixedJavaThenScalaScalaThenJava。如果您的 Scala 和 Java 源代码之间存在循环依赖关系,则需要使用默认的 Mixed,它将 Java 和 Scala 源代码都传递给 scalac,然后使用 javac 编译 Java 源代码。如果您没有循环依赖关系,则可以使用另外两个选项之一来加快构建速度,方法是将 Java 源代码不传递给 scalac。例如,如果您的 Scala 源代码依赖于您的 Java 源代码,但您的 Java 源代码不依赖于您的 Scala 源代码,则可以执行以下操作

compileOrder := CompileOrder.JavaThenScala

要为主要源代码和测试源代码指定不同的顺序,请按配置对设置进行作用域限定

// Java then Scala for main sources
Compile / compileOrder := CompileOrder.JavaThenScala

// allow circular dependencies for test sources
Test / compileOrder := CompileOrder.Mixed

请注意,在增量编译设置中,在 Java 源代码和 Scala 源代码之间确保完全隔离是不切实际的,因为它们共享同一个输出目录。因此,之前编译的未参与当前重新编译的类可能会被拾取。但是,干净编译始终会提供完整的检查。

混合模式编译中已知的问题 

如果 Java 源代码中的定义不是字面量,Scala 编译器不会识别 Java 源代码中的编译时常量变量(Java 规范 4.12.4)。此问题有几个症状,在 Scala 问题单 SI-5333 中进行了描述。

  1. 当用作 Java 注释的参数时,常量变量的选择将被拒绝(需要编译时常量表达式)。
  2. 常量变量的选择不会被其值替换,而是作为实际的字段加载进行编译(Scala 规范 4.1 定义了常量表达式应替换为其值)。

从 Scala 2.11.4 开始,在 Scala 类中使用 Java 定义的注释时会出现类似的问题。Scala 编译器在解析来自源代码的注释 @interface 时无法识别 @Retention 注释,因此将使用可见性 RUNTIME 发射注释(SI-8928)。

忽略 Scala 源代码目录 

默认情况下,sbt 将 src/main/scalasrc/main/java 包含在其未管理的源代码目录列表中。对于仅 Java 的项目,可以通过修改 unmanagedSourceDirectories 来忽略不必要的 Scala 目录。

// Include only src/main/java in the compile configuration
Compile / unmanagedSourceDirectories := (Compile / javaSource).value :: Nil

// Include only src/test/java in the test configuration
Test / unmanagedSourceDirectories := (Test / javaSource).value :: Nil

但是,如果 Scala 目录为空,则保留它们不会有任何危害。