我目前正在接管旧的 Scala 应用程序,主要目标是用 Java 编写新功能,但利用旧的通用代码。到目前为止,存储库看起来或多或少像这样:
├──common-scala-module-1
│ ├── src
│ │ ├── scala
│ │ │ ├── **/*.scala
│ │ ├── test
│ │ │ ├── **/*.scala
├──common-scala-module-2
│ ├── src
│ │ ├── scala
│ │ │ ├── **/*.scala
│ │ ├── test
│ │ │ ├── **/*.scala
├──scala-module-3
│ ├── src
│ │ ├── scala
│ │ │ ├── **/*.scala
│ │ ├── test
│ │ │ ├── **/*.scala
├──scala-module-4
│ ├── src
│ │ ├── scala
│ │ │ ├── **/*.scala
│ │ ├── test
│ │ │ ├── **/*.scala
├── build.sbt
├── .gitignore
└── (other scala files that doesn't matter for this problem)
所有这 4 个都会生成 jar 模块,但对 生产 代码真正重要的模块来自
scala-module-3
和 scala-module-4
(取决于两个公共模块中的类)。我需要开始编写新代码(新模块,如scala-module-3
),但从现在开始用 Java 编写。然而,如果出现这种需要,我仍然需要维护旧代码。我有两个主要问题,我想获得架构建议(我在问题后的括号中写下了我目前认为最好的路径):
注意:我确实在多个项目中拥有相当广泛的 Java 背景,并且我确实了解 Scala 基础知识(比如它利用 JVM 技术,并且即使我刚刚开始将 Java 代码突然放入存储库,SBT 也应该可以工作)。我只是在寻找架构建议,以便了解权衡并让我(也许有一天其他人)的生活更轻松,因为这个应用程序现在将 Scala 抛在了后面(除了错误/维护之外)。
您的首要问题不是在 Maven 或 Gradle 之间进行选择。
您的主要问题是您不能在未来的 Java 代码中直接使用任何这些 Scala 依赖项(它编译为 JVM 字节码的事实并不重要,因为您不会用字节码编写未来的包)。
您无法直接使用任何这些依赖项的原因是:
implicit
/ given
,更不用说宏了。因此,暴露given
就像在黑色的深渊中尖叫,却得不到任何回应,即毫无意义。您可能尝试的一件合理的事情:
common-scala-module-1
、common-scala-module-2
等<P>
,创建额外的 <P>-javaapi
子项目,即 common-scala-module-1-javaapi
、common-scala-module-2-javaapi
等。<P>-javaapi
子项目内部:
<P>
提供的所有功能,但按照惯用的Java编写。支持FactoryFactories
和一页又一页的重复泛型。<P>
<P>-javaapi
(-javaapi
是一个混合的 Scala/Java 项目,因此可能更好地使用 SBT 构建它)-javaapi
包中的纯 Java API。这应该有效,因为:
scala.jdk.CollectionConverters
等转换所有集合是微不足道的。-javaapi
包应该可以正常工作。最后,您将获得一堆包
common-scala-module-1-javaapi
... common-scala-module-N-javaapi
,它们不仅在字节码级别上几乎与任何 Java 包没有区别,而且在导出类型、接口和文档级别上也是如此。
除非你的代码是紧密耦合的混乱,导致你无法在没有
also修改和重新运行所有非通用模块的情况下测试
common-scala-module-N
,那么最好创建一个具有单独 java-module-0
、 的单独存储库java-module-1
等并使用 Maven(或 Gradle)构建它们。