简体   繁体   中英

How to use object/type from one subproject in another in multi-project build in SBT?

I have the following multi-project folder structure:

/ComponentA/ComponentA.scala
/ComponentA/build.sbt
/ComponentB/ComponentB.scala
/ComponentB/build.sbt
/project/Build.scala
main.scala

In the root object main.scala the following should happen: ComponentA returns a String message that ComponentB reads in and prints out.

Here are the contents of the files:

ComponentA

object ComponentA {
  def main(args: Array[String]) {
    var myMessage : String = "this message should be passed to ComponentB";
    println("Message to forward: %s \n\n\n ".format(myMessage))
    return myMessage;
  }
}

ComponentB

object ComponentB {
  def main(args: Array[String]) {
    println("\n\n\n Inside ComponentB! \n\n\n ")
    println("Message received: %s \n\n\n ".format(args(0)))
  }
}

Build.scala

import sbt._
import Keys._

object RootBuild extends Build {
  lazy val root = Project(id = "root", base = file("."))
    .dependsOn(ComponentA, ComponentB)

  lazy val ComponentA = Project(id = "ComponentA", base = file("ComponentA"))

  lazy val ComponentB = Project(id = "ComponentB", base = file("ComponentB"))
    .dependsOn(ComponentA)

}

main.scala

object ComponentB {
  def main(args: Array[String]) {

    println("\n\n\n Inside main! \n\n\n ")

    // THIS SHOULD HAPPEN:
    // ComponentB(ComponentA());

  }
}

Is this possible with that project structure? If so, how will the code be for main.scala ?

The following build.sbt in the root project should let you create that project structure.

lazy val ComponentA = project

lazy val ComponentB = project dependsOn ComponentA

lazy val root = project in file(".") dependsOn (ComponentA, ComponentB) aggregate (ComponentA, ComponentB)

You'll have to fix a few issues in the component objects so they compile, but the project's classpath should be fine.

It is however a common approach to have a root project an aggregate for submodules so in your case root should not have dependsOn with another separate project ComponentAB that would dependsOn ComponentB (and hence ComponentA as ComponentB already depends on it).

The code below should be taken with a great care and only for the sake of the question.

ComponentA/ComponentA.scala

object ComponentA {
  def apply(): String = {
    var myMessage = "this message should be passed to ComponentB"
    println(s"Message to forward: $myMessage\n\n\n")
    myMessage
  }
}

ComponentB/ComponentB.scala

object ComponentB {
  def apply(msg: String) = {
    println("\n\n\n Inside ComponentB! \n\n\n ")
    println("Message received: $msg\n\n\n")
  }
}

Main.scala

object MainObject {
  def main(args: Array[String]) {
    println("\n\n\n Inside main! \n\n\n ")
    //ComponentB(ComponentA())
    ComponentA()
  }
}

With the files, when you do run you should get the following output:

[root]> run
[info] Running ComponentB



 Inside main!



Message to forward: this message should be passed to ComponentB



[success] Total time: 0 s, completed Jan 20, 2014 9:59:32 PM

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