We're combining two of our Scala projects because they share a lot of functionality. I'm setting up the new repo, and have the following 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",
)
Basically, Project 1 and Project 2 should both depend on Core, but not on each other.
My src
directory looks like this:
src
main/scala
core
Core.scala
project1
Main.scala
project2
Main.scala
test/scala
core
TestCore.scala
project1
TestProject1.scala
project2
TestProject2.scala
For the moment, Core.scala
is:
package core
object Core {
def hello() = {
println("hello from core!")
}
}
project1/Main.scala
is:
package project1
import core.Core
object Main {
def main(args: Array[String]): Unit = {
hello()
Core.hello()
}
def hello() = { println("hello from project 1!") }
}
and similarly, project2/Main.scala
is:
package project2
import core.Core
object Main {
def main(args: Array[String]): Unit = {
hello()
Core.hello()
}
def hello() = { println("hello from project 2!") }
}
I can run both of these main classes in the sbt terminal from the project root, either by entering run
and selecting the main class I'd like to use, or entering runMain <main_class>
(the two main classes are project1.Main
and project2.Main
). However, if I switch to one of the subprojects (for example, by entering project project1
) and then enter run
, sbt is no longer able to detect a main class. Additionally, if I compile the project using assembly
, I can't run either project1.jar
or project2.jar
because they can't find their main classes either. Why exactly is this happening?
Furthermore, I noticed that I can still import project2
into Project 1 and project1
into Project 2, even though I've only set dependsOn
for core
. Is this expected behavior?
You're confusing completely different notions, subprojects and packages.
If you want to have subprojects
lazy val project1 = (project in file("project1"))
lazy val project2 = (project in file("project2"))
lazy val core = (project in file("core"))
then the project structure should be completely different
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
If you put
package core
object Core
package project1
object Main
package project2
object Main
to the same directory src/main/scala
then core
, project1
, project2
are packages, not subprojects and you have the only project.
Surely you can have both subprojects and packages. Then the project structure can be
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
but generally there is no connection between subproject names and package names.
In principle you can modify the project structure so that it will differ from default
https://www.scala-sbt.org/1.x/docs/Howto-Customizing-Paths.html
if I switch to one of the subprojects (for example, by entering
project project1
) and then enterrun
, sbt is no longer able to detect a main class
That's because now your subprojects project1
, project2
, core
(declared in build.sbt
) are empty. You put everything to the single directory src/main/scala
that belongs to
lazy val root = (project in file("."))
which is created implicitly by default if you don't create it manually.
Maven: difference module - java package