我们正在合并我们的两个 Scala 项目,因为它们共享很多功能。我正在设置新的回购协议,并具有以下
build.sbt
:
ThisBuild / scalaVersion := "2.13.10"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.15" % Test
lazy val project1 = (project in file("project1"))
.dependsOn(core)
.settings(
name := "Project 1",
assembly / mainClass := Some("project1.Main"),
assembly / assemblyJarName := "project1.jar",
)
lazy val project2 = (project in file("project2"))
.dependsOn(core)
.settings(
name := "Project 2",
assembly / mainClass := Some("project2.Main"),
assembly / assemblyJarName := "project2.jar",
)
lazy val core = (project in file("core"))
.settings(
name := "Core",
)
基本上,项目 1 和项目 2 应该都依赖于 Core,而不是相互依赖。
我的
src
目录是这样的:
src
main/scala
core
Core.scala
project1
Main.scala
project2
Main.scala
test/scala
core
TestCore.scala
project1
TestProject1.scala
project2
TestProject2.scala
目前,
Core.scala
是:
package core
object Core {
def hello() = {
println("hello from core!")
}
}
project1/Main.scala
是:
package project1
import core.Core
object Main {
def main(args: Array[String]): Unit = {
hello()
Core.hello()
}
def hello() = { println("hello from project 1!") }
}
同样,
project2/Main.scala
是:
package project2
import core.Core
object Main {
def main(args: Array[String]): Unit = {
hello()
Core.hello()
}
def hello() = { println("hello from project 2!") }
}
我可以从项目根目录在 sbt 终端中运行这两个主要类,方法是输入
run
并选择我想使用的主要类,或者输入 runMain <main_class>
(这两个主要类是 project1.Main
和project2.Main
)。但是,如果我切换到其中一个子项目(例如,通过输入 project project1
)然后输入 run
,sbt 将不再能够检测到主类。此外,如果我使用 assembly
编译项目,我无法运行 project1.jar
或 project2.jar
,因为它们也找不到它们的主类。为什么会这样?
此外,我注意到我仍然可以将
project2
导入项目 1,将 project1
导入项目 2,即使我只为 dependsOn
设置了 core
。这是预期的行为吗?
你混淆了完全不同的概念、子项目和包。
如果你想有子项目
lazy val project1 = (project in file("project1"))
lazy val project2 = (project in file("project2"))
lazy val core = (project in file("core"))
那么项目结构应该完全不同
core
src
main/scala
Core.scala
test/scala
TestCore.scala
project1
src
main/scala
Main.scala
test/scala
TestProject1.scala
project2
src
main/scala
Main.scala
test/scala
TestProject2.scala
https://www.scala-sbt.org/1.x/docs/Directories.html
https://www.scala-sbt.org/1.x/docs/Multi-Project.html
如果你放
package core
object Core
package project1
object Main
package project2
object Main
到相同的
src/main/scala
然后core
,project1
,project2
是包,而不是子项目,你有唯一的项目。
当然你可以同时拥有子项目和包。那么项目结构就可以了
core <-- this is a subproject
src
main/scala
core <-- this is a package
Core.scala
test/scala
core
TestCore.scala
project1
src
main/scala
project1
Main.scala
test/scala
project1
TestProject1.scala
project2
src
main/scala
project2
Main.scala
test/scala
project2
TestProject2.scala
但是子项目名和包名一般是没有联系的
原则上您可以修改项目结构,使其与默认不同
https://www.scala-sbt.org/1.x/docs/Howto-Customizing-Paths.html
如果我切换到其中一个子项目(例如,通过输入
)然后输入project project1
,sbt 将不再能够检测到主类run
那是因为现在您的子项目
project1
、project2
、core
(在build.sbt
中声明)是空的。你把所有东西都放在属于的单
src/main/scala
lazy val root = (project in file("."))
如果您不手动创建它,默认情况下会隐式创建它。