简体   繁体   中英

How can I specify a mainClass in build.sbt that resides in another module?

For some reason, our project got reorganized with the main class thrown in another module

I've specified the mainClass as below in the build.sbt but I still get a class not found error:

mainClass in Compile := Some("com.so.questions.sbt.Main")

However, this is bound to fail since it's going to look for the Main class in the src folder. However, this module lives outside of (sibling of) src :

MyScalaProject
+-MyModule
|+-src
| +-com.so.questions.sbt
|  +-Main
|+-build.sbt <-- build.sbt specific to this module, currently blank
+-src
| +-<other folders>
+-build.sbt  <-- build.sbt currently housing all config

How can I change the project scope in build.sbt to find and correctly load the main class?

That is, is it possible to do sbt run at the top level and have the main class be found with this structure?

It should work.

The FQCN specification for mainClass should be location independent to my understanding.

The real question that comes to mind is how you are loading your sub-module. Here are some sbt definitions that should help point you in the right direction ( replace the <> tags with your own project Ids) :

// Define a submodule ref to be able to include it as a dependency
lazy val subModuleRef = ProjectRef(file("MyModule"),<MyModule SBT NAME>)

// Define a submodule project to be able to orchestrate it's build 
lazy val subModule = Project(
  id = <MyModule SBT NAME>,
  base = file("MyModule"),
).addSbtFiles(file("build.sbt"))

// Define the top-level project, depending and subModule Ref for code
// inclusion and aggregating the subModule for build orchestration
lazy val scalaProject = Project(
  id = <MyScalaProject NAME>,
  base = file("."),
  aggregate = Seq(subModule),
  settings = commonSettings
).dependsOn(subModuleRef).

Let's say that you have the MyModule module/folder containing the main class and some other module called MyCoreModule (just to illustrate the whole build.sbt):

// any stuff that you want to share between modules
lazy val commonSettings = Seq(
    scalaVersion  := "2.12.8",
    version       := "1.0-SNAPSHOT"
)

lazy val root = (project in file("."))
  .settings(commonSettings: _*)
  .settings(
    name := "parent-module"
  )
  .aggregate(core, app)
  .dependsOn(app) // <-- here is the config that will allow you to run "sbt run" from the root project

lazy val core = project.in(file("MyCoreModule"))
  .settings(commonSettings: _*)
  .settings(
    name := "core"
  )

lazy val app = project.in(file("MyModule"))
  .dependsOn(core)
    .settings(commonSettings: _*)
  .settings(
    name := "app"
    )

// define your mainClass from the "app" module
mainClass in Compile := (mainClass in Compile in app).value

Btw, sbt.version=1.2.7

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM