PlayRunHook does not work in multi module projects - scala

We need a base play framework projects which contains other play and scala projects as module. Those inner independent projects can have different javascript frameworks and build system like webpack, gulp, etc.
So I tried the PlayRunHook from https://www.playframework.com/documentation/2.4.x/SBTCookbook . Single project hooking working as expected. But, unable to get it right on multi module project. Some code samples...
Project Structure
base/build.sbt
name := """base"""
version := "1.0-SNAPSHOT"
lazy val commonSettings = Seq(
scalaVersion := "2.11.6",
libraryDependencies ++= Seq(
jdbc,
cache,
ws,
specs2 % Test
),
resolvers ++= Seq(
"scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"
)
)
lazy val root = (project in file("."))
.settings(commonSettings : _*)
.enablePlugins(PlayScala)
.dependsOn(scraper)
.aggregate(scraper)
.dependsOn(slider)
.aggregate(slider)
lazy val scraper = (project in file("modules/scraper"))
.settings(commonSettings : _*)
.enablePlugins(PlayScala)
lazy val slider = (project in file("modules/slider"))
.settings(commonSettings : _*)
.enablePlugins(PlayScala)
routesGenerator := InjectedRoutesGenerator
base/modules/scraper/build.sbt
import play.sbt.PlayImport.PlayKeys.playRunHooks
import WebPack._
name := """scraper"""
version := "1.0-SNAPSHOT"
lazy val frontendDirectory = baseDirectory {_ / "frontend"}
playRunHooks <+= frontendDirectory.map(WebPack.apply)
routesGenerator := InjectedRoutesGenerator
libraryDependencies ++= Seq(
"com.corundumstudio.socketio" % "netty-socketio" % "1.7.8"
)
resolvers ++= Seq(
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
)
base/modules/slider/build.sbt
name := """slider"""
version := "1.0-SNAPSHOT"
scalaVersion := "2.11.6"
routesGenerator := InjectedRoutesGenerator
base/modules/scraper/project/WebPack.scala
import java.net.InetSocketAddress
import play.sbt.PlayRunHook
import sbt._
object WebPack {
def apply(base: File): PlayRunHook = {
object WebpackHook extends PlayRunHook {
var process: Option[Process] = None
override def beforeStarted(): Unit = {
if (isWindows) {
Process("cmd /c npm run compile", base).run
} else {
Process("npm run compile", base).run
}
}
override def afterStarted(addr: InetSocketAddress): Unit = {
if (isWindows) {
Some(Process("cmd /c npm start", base).run)
} else {
Some(Process("npm start", base).run)
}
}
private def isWindows: Boolean = {
System.getProperty("os.name").startsWith("Windows")
}
override def afterStopped(): Unit = {
process.foreach(_.destroy())
process = None
}
}
WebpackHook
}
}
But I am getting
...../base/modules/scraper/build.sbt:10: error: not found: object WebPack
import WebPack._
^
sbt.compiler.EvalException: Type error in expression
at sbt.compiler.Eval.checkError(Eval.scala:384)
at sbt.compiler.Eval.compileAndLoad(Eval.scala:183)
at sbt.compiler.Eval.evalCommon(Eval.scala:152)
at sbt.compiler.Eval.evalDefinitions(Eval.scala:122)
at sbt.EvaluateConfigurations$.evaluateDefinitions(EvaluateConfigurations.scala:271)
at sbt.EvaluateConfigurations$.evaluateSbtFile(EvaluateConfigurations.scala:109)
at sbt.Load$.sbt$Load$$loadSettingsFile$1(Load.scala:712)
at sbt.Load$$anonfun$sbt$Load$$memoLoadSettingsFile$1$1.apply(Load.scala:717)
at sbt.Load$$anonfun$sbt$Load$$memoLoadSettingsFile$1$1.apply(Load.scala:716)
at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)
at scala.collection.AbstractMap.getOrElse(Map.scala:58)
at sbt.Load$.sbt$Load$$memoLoadSettingsFile$1(Load.scala:716)
at sbt.Load$$anonfun$loadFiles$1$2.apply(Load.scala:723)
at sbt.Load$$anonfun$loadFiles$1$2.apply(Load.scala:723)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
at scala.collection.immutable.List.foreach(List.scala:318)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
at scala.collection.AbstractTraversable.map(Traversable.scala:105)
at sbt.Load$.loadFiles$1(Load.scala:723)
at sbt.Load$.discoverProjects(Load.scala:734)
at sbt.Load$.discover$1(Load.scala:545)
at sbt.Load$.discoverAndLoad$1(Load.scala:554)
at sbt.Load$.loadTransitive(Load.scala:570)
at sbt.Load$.loadProjects$1(Load.scala:442)
at sbt.Load$.loadUnit(Load.scala:446)
at sbt.Load$$anonfun$18$$anonfun$apply$11.apply(Load.scala:281)
at sbt.Load$$anonfun$18$$anonfun$apply$11.apply(Load.scala:281)
at sbt.BuildLoader$$anonfun$componentLoader$1$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.apply(BuildLoader.scala:91)
at sbt.BuildLoader$$anonfun$componentLoader$1$$anonfun$apply$4$$anonfun$apply$5$$anonfun$apply$6.apply(BuildLoader.scala:90)
at sbt.BuildLoader.apply(BuildLoader.scala:140)
at sbt.Load$.loadAll(Load.scala:334)
at sbt.Load$.loadURI(Load.scala:289)
at sbt.Load$.load(Load.scala:285)
at sbt.Load$.load(Load.scala:276)
at sbt.Load$.apply(Load.scala:130)
at sbt.Load$.defaultLoad(Load.scala:36)
at sbt.BuiltinCommands$.doLoadProject(Main.scala:481)
at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:475)
at sbt.BuiltinCommands$$anonfun$loadProjectImpl$2.apply(Main.scala:475)
at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:58)
at sbt.Command$$anonfun$applyEffect$1$$anonfun$apply$2.apply(Command.scala:58)
at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:60)
at sbt.Command$$anonfun$applyEffect$2$$anonfun$apply$3.apply(Command.scala:60)
at sbt.Command$.process(Command.scala:92)
at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:98)
at sbt.MainLoop$$anonfun$1$$anonfun$apply$1.apply(MainLoop.scala:98)
at sbt.State$$anon$1.process(State.scala:184)
at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:98)
at sbt.MainLoop$$anonfun$1.apply(MainLoop.scala:98)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
at sbt.MainLoop$.next(MainLoop.scala:98)
at sbt.MainLoop$.run(MainLoop.scala:91)
at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:70)
at sbt.MainLoop$$anonfun$runWithNewLog$1.apply(MainLoop.scala:65)
at sbt.Using.apply(Using.scala:24)
at sbt.MainLoop$.runWithNewLog(MainLoop.scala:65)
at sbt.MainLoop$.runAndClearLast(MainLoop.scala:48)
at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:32)
at sbt.MainLoop$.runLogged(MainLoop.scala:24)
at sbt.StandardMain$.runManaged(Main.scala:53)
at sbt.xMain.run(Main.scala:28)
at xsbt.boot.Launch$$anonfun$run$1.apply(Launch.scala:109)
at xsbt.boot.Launch$.withContextLoader(Launch.scala:128)
at xsbt.boot.Launch$.run(Launch.scala:109)
at xsbt.boot.Launch$$anonfun$apply$1.apply(Launch.scala:35)
at xsbt.boot.Launch$.launch(Launch.scala:117)
at xsbt.boot.Launch$.apply(Launch.scala:18)
at xsbt.boot.Boot$.runImpl(Boot.scala:41)
at xsbt.boot.Boot$.main(Boot.scala:17)
at xsbt.boot.Boot.main(Boot.scala)
[error] sbt.compiler.EvalException: Type error in expression
[error] Use 'last' for the full log.
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore?
I am experimenting play framework, and I am fairly new to this. Thanks in advance

In sbt keep only one build.sbt file and one project directory (with *.sbt and *.scala config files)
Copy WebPack.scala to project directory.
Move your root project to subproject (base).
Rewrite build.sbt
import play.sbt.PlayImport.PlayKeys.playRunHooks
name := """root"""
version := "1.0-SNAPSHOT"
val scraperDir = "modules/scraper"
val sliderDir = "modules/slider"
lazy val commonSettings = Seq(
scalaVersion := "2.11.7",
libraryDependencies ++= Seq(
jdbc,
cache,
ws,
specs2 % Test
),
resolvers ++= Seq(
"scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"
)
)
lazy val base = projectName("base","base").settings(
playRunHooks += WebPack.apply(file(scraperDir))
)
.dependsOn(scraper,slider)
lazy val scraper = projectName("scraper", scraperDir).settings(
libraryDependencies ++= Seq(
"com.corundumstudio.socketio" % "netty-socketio" % "1.7.8"
),
resolvers ++= Seq(
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots")
)
lazy val slider = projectName("slider", sliderDir)
def projectName(name: String, path: String): Project =
Project(name,file(path))
.settings(
commonSettings,
routesGenerator := InjectedRoutesGenerator
)
.enablePlugins(PlayScala)

Related

sbt run Play as a sumodule

I was wondering if I can run Play in development as a submodule?
Here is the project structure:
Root
submodule1
submodule2(Play)
submodule3
......
There is only one build.sbt file under the root level, which specified the structure of the project.
Previously, I had the Play module as a separate project, which has its own build.sbt, and I could simply run it in development mode with sbt run.
However, after I combined the Play module with the other modules into one project, sbt "project projectName" run can still start the Play module in development mode, but when I tried to hit any endpoint, I got injection error, such as No implementation for models.services.UserService was bound.
Here is a portion of the build.sbt. emberconflagration is the Play project.
lazy val root = project
.in(file("."))
.aggregate(embercore)
.aggregate(emberdataset)
.aggregate(emberconflagration)
.aggregate(emberservice)
.aggregate(embersession)
.aggregate(emberetl)
.aggregate(embermodel)
.aggregate(emberclient)
.aggregate(emberserver)
.aggregate(emberservermongo)
.aggregate(emberstreaming)
.settings(commonSettings: _*)
.settings(name := "ember-conflagration-root")
lazy val embercore = (project in file("./embercore"))
.settings(commonSettings: _*)
.settings(testSettings: _*)
.settings(
name := "embercore",
libraryDependencies ++= Seq(
Libraries.scalatest,
Libraries.play_json
),
resolvers ++= Seq(
"Apache Repository" at "https://repository.apache.org/content/repositories/releases/",
"Cloudera Repository" at "https://repository.cloudera.com/artifactory/cloudera-repos/",
Resolver.sonatypeRepo("public")
),
javaOptions in assembly += "-xmx6g"
)
lazy val emberservice = (project in file("./emberservice"))
.settings(commonSettings: _*)
.settings(testSettings: _*)
.settings(
name := "emberservice",
libraryDependencies ++= Seq(
Libraries.scalatest,
Libraries.play_json,
Libraries.scala_j
),
resolvers ++= Seq(
"Apache Repository" at "https://repository.apache.org/content/repositories/releases/",
"Cloudera Repository" at "https://repository.cloudera.com/artifactory/cloudera-repos/",
Resolver.sonatypeRepo("public")
),
javaOptions in assembly += "-xmx6g"
)
.dependsOn(embercore)
lazy val emberdataset = (project in file("./emberdataset"))
.settings(commonSettings: _*)
.settings(testSettings: _*)
.settings(
name := "emberdataset",
libraryDependencies ++= Seq(
Libraries.scalatest,
Libraries.spark_core_conflP,
Libraries.spark_mllib_conflP,
Libraries.spark_sql_conflP,
Libraries.mysql_connector,
Libraries.spark_xml
),
resolvers ++= Seq(
"Apache Repository" at "https://repository.apache.org/content/repositories/releases/",
"Cloudera Repository" at "https://repository.cloudera.com/artifactory/cloudera-repos/",
Resolver.sonatypeRepo("public")
),
javaOptions in assembly += "-xmx6g"
)
.dependsOn(embercore)
lazy val embersession = (project in file("./embersession"))
.enablePlugins(LauncherJarPlugin)
.settings(commonSettings: _*)
.settings(testSettings: _*)
.settings(
name := "embersession",
libraryDependencies ++= Seq(
Libraries.scalatest,
Libraries.h2o_sparkling_water_core
exclude ("com.fasterxml.jackson.core", "jackson-core")
exclude ("com.fasterxml.jackson.core", "jackson-databind")
exclude ("javax.servlet", "servlet-api"),
// exclude ("org.apache.spark", "spark-sql_2.11") // Comment out for standard build. Uncomment for EmberSession assembly.
// exclude ("org.apache.spark", "spark-core_2.11") // Comment out for standard build. Uncomment for EmberSession assembly.
// exclude ("org.apache.spark", "spark-mllib_2.11") // Comment out for standard build. Uncomment for EmberSession assembly.
// exclude ("org.apache.hadoop", "hadoop-common"), // Comment out for standard build. Uncomment for EmberSession assembly.
Libraries.jackson_scala,
Libraries.duke,
Libraries.scala_library,
Libraries.spark_core_conflP,
Libraries.spark_mllib_conflP,
Libraries.spark_sql_conflP
),
mainClass in assembly := Some("com.metistream.ember.embersession.Test"),
javaOptions in assembly += "-xmx6g",
resolvers ++= Seq(
"Apache Repository" at "https://repository.apache.org/content/repositories/releases/",
"Cloudera Repository" at "https://repository.cloudera.com/artifactory/cloudera-repos/",
Resolver.sonatypeRepo("public")
),
assemblyShadeRules in assembly ++= Seq(
ShadeRule.rename("com.esotericsoftware.kryo.**" -> "emberkryo.#1").inAll,
ShadeRule.rename("com.fasterxml.jackson.**" -> "emberjackson.#1").inAll,
ShadeRule.rename("play.api.**" -> "emberplay.play.api.#1").inAll
),
assemblyMergeStrategy in assembly := {
case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLines
case PathList("reference.conf") => MergeStrategy.concat
case PathList("META-INF", xs # _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
)
.dependsOn(embercore, emberdataset, emberservice)
lazy val emberconflagration = (project in file("security-layer"))
.enablePlugins(PlayScala)
.settings(commonSettings: _*)
.settings(testSettings: _*)
.settings(
name := "ember-conflagration",
libraryDependencies ++= Seq(
jdbc,
cache,
ws,
filters,
Libraries.play2_reactivemongo,
Libraries.mockito,
Libraries.embed_mongo,
Libraries.play_silhouette,
Libraries.silhouette_password,
Libraries.silhouette_persistence,
Libraries.silhouette_crypto,
Libraries.silhouette_testkit,
Libraries.scala_guice,
Libraries.ficus,
Libraries.mleap_runtime,
Libraries.google_api_dataproc,
Libraries.scalaj_http,
Libraries.google_core,
Libraries.google_client,
Libraries.google_sqladmin,
Libraries.google_cloud_compute,
Libraries.google_api_services,
Libraries.google_cloud_storage,
Libraries.postgresql_connector,
Libraries.jersey_media_glass,
Libraries.jersey_core_glass,
Libraries.jackson_xml,
Libraries.jackson_scala,
Libraries.janino,
Libraries.play_json_extensions,
Libraries.hapi_base,
Libraries.hapi_structures_v21,
Libraries.hapi_structures_v22,
Libraries.hapi_structures_v23,
Libraries.hapi_structures_v231,
Libraries.hapi_structures_v24,
Libraries.hapi_structures_v25,
Libraries.hapi_structures_v251,
Libraries.hapi_structures_v26,
Libraries.play_quartz_extension,
Libraries.elastic4s_core,
Libraries.elastic4s_http,
Libraries.scalatest,
specs2 % Test,
Libraries.uimaj_core,
Libraries.spark_core_confl,
Libraries.spark_mllib_confl,
Libraries.spark_sql_confl,
Libraries.unbound_id,
Libraries.swagger
),
coverageExcludedPackages := "<empty>;Reverse.*;router\\..*",
// Assembly Settings
assemblyShadeRules in assembly ++= Seq(
ShadeRule
.rename("com.google.common.**" -> "my_guava.#1")
.inLibrary("com.google.api-client" % "google-api-client" % "1.22.0")
),
mainClass in assembly := Some("play.core.server.ProdServerStart"),
fullClasspath in assembly += Attributed.blank(PlayKeys.playPackageAssets.value),
assemblyMergeStrategy in assembly := {
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case PathList("META-INF", xs # _*) => MergeStrategy.first
case x => MergeStrategy.first
},
projectDependencies := {
Seq(
(projectID in emberdataset).value.excludeAll(ExclusionRule(organization = "org.slf4j"),
ExclusionRule(organization = "io.netty"))
)
},
fork in run := false,
resolvers ++= Seq(
"elasticsearch-releases" at "https://artifacts.elastic.co/maven",
"sonatype snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/",
Resolver.bintrayRepo("iheartradio", "maven"),
"Atlassian Releases" at "https://maven.atlassian.com/public/",
Resolver.url("Typesafe Ivy releases", url("https://repo.typesafe.com/typesafe/ivy-releases"))(
Resolver.ivyStylePatterns)
),
javaOptions in assembly += "-xmx6g"
)
.dependsOn(embercore, emberdataset, emberetl)
I think it is just your particular app that doesn't work. This is possibly because you have multiple packages which are colliding with each other. Here's an example that works.
Directory structure
./build.sbt
./mod1
./mod1/src
./mod1/src/main
./mod1/src/main/scala
./mod1/src/main/scala/Hello.scala
./mod2
./mod2/app
./mod2/app/controllers
./mod2/app/controllers/HomeController.scala
./mod2/app/modules/MainModule.scala
./mod2/conf
./mod2/conf/application.conf
./mod2/conf/logback.xml
./mod2/conf/messages
./mod2/conf/routes
./mod3
./mod3/src
./mod3/src/main
./mod3/src/main/scala
./mod3/src/main/scala/Hello.scala
./project/plugins.sbt
Important files:
build.sbt
name := """root"""
organization := "com.example"
version := "1.0-SNAPSHOT"
lazy val mod1 = project in file("mod1")
lazy val mod2 = (project in file("mod2"))
.enablePlugins(PlayScala)
.settings(
name := """myplayproject""",
organization := "com.example",
version := "1.0-SNAPSHOT",
scalaVersion := "2.12.6",
libraryDependencies += guice,
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.2" % Test
)
lazy val mod3 = project in file("mod3")
lazy val root = (project in file("."))
.aggregate(mod1)
.aggregate(mod2)
.aggregate(mod3)
HomeController.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
trait MyServiceLike {
def getString: String
}
class MyService extends MyServiceLike {
override def getString: String = "hello"
}
#Singleton
class HomeController #Inject()(cc: ControllerComponents, myService: MyServiceLike) extends AbstractController(cc) {
def index() = Action { implicit request: Request[AnyContent] =>
Ok(myService.getString)
}
}
project/plugins.sbt
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.16")
mod2/conf/application.conf
play.modules.enabled += "modules.MainModule"
mod2/app/modules/MainModule.scala
package modules
import controllers.MyService
import controllers.MyServiceLike
import play.api.Configuration
import play.api.Environment
import play.api.inject.Binding
import play.api.inject.Module
class MainModule extends Module {
override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = Seq(
bind[MyServiceLike].to[MyService]
)
}
Run
Then, you can run by starting sbt:
project mod2
run

How to set the Main class to run using sbt-assembly plugin for SBT multi-projects

Here's my project structure on the filesystem:
rootProj
+- masterProj
+- proj1
...
+- projN
I'm trying to use sbt-assembly plugin to create a fat jar. I want to set the main class as
masterProj/core/Main.scala
in order to get a runnable fat jar when assemble from rootProj directory executing the assemby command
How can I set mainClass in rootProj/build.sbt ?
I set
mainClass in assembly := Some("core.Main") // fully qualified path
but when I try to run the jar after assembling
rootProj$ java -jar target/scala-2.10/rootProj-assembly-0.1-SNAPSHOT.jar
I get this error
Exception in thread "main" java.lang.NoClassDefFoundError: core/Main
Caused by: java.lang.ClassNotFoundException: core.Main
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Any hint?
Here's my build.sbt
import AssemblyKeys._
assemblySettings
name := "deals-backend"
version := Common.version
scalaVersion := Common.scalaVersion
resolvers ++= Seq(
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots",
"Sonatype repository" at "https://oss.sonatype.org/service/local/staging/deploy/maven2"
)
scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation", "-feature")
retrieveManaged := true
lazy val dealsClassifier = Project( "deals-classifier", file("deals-classifier") )
lazy val dealsEntities = Project( "deals-entities-pub", file("deals-entities-pub") )
lazy val dealsDbPre = Project( "deals-db-pre", file("deals-db-pre") )
lazy val dealsDbPub = Project( "deals-db-pub", file("deals-db-pub") )
lazy val dealsSolrClient = Project( "deals-solr-client", file("deals-solr-client") ).dependsOn(dealsDbPub % "test->test;compile->compile")
lazy val dealsMasterSpray = Project( "deals-master-spray", file("deals-master-spray") )
.dependsOn(dealsClassifier, dealsEntities, dealsDbPre, dealsDbPub, dealsSolrClient)
.settings(mainClass in (Compile, run) := Some("core.Main"))
lazy val root = project.in( file(".") ).aggregate(dealsClassifier, dealsEntities, dealsDbPre, dealsDbPub, dealsSolrClient, dealsMasterSpray)
run in Compile <<= (run in Compile in dealsMasterSpray)
mainClass in (Compile, assembly) := Some("deals-master-spray.core.Main")

Trying to cross compile a project to Scala 2.11 fails with "error while loading Object, Missing dependency 'object scala in compiler mirror'"

I'm trying to compile my project to Scala 2.10 and 2.11 so that I can release versions for both scala versions, but every time I try to do it it fails with the following message:
#( 04/26/14# 7:40 )( mauricio#Mauricios-MacBook-Pro ):~/projects/scala/postgresql-netty#scala-2.11✔
sbt compile
[info] Loading project definition from /Users/mauricio/projects/scala/postgresql-netty/project
[info] Set current project to db-async-base (in build file:/Users/mauricio/projects/scala/postgresql-netty/)
[info] Compiling 61 Scala sources and 1 Java source to /Users/mauricio/projects/scala/postgresql-netty/db-async-common/target/scala-2.11/classes...
[error] error while loading Object, Missing dependency 'object scala in compiler mirror', required by /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/jre/lib/rt.jar(java/lang/Object.class)
scala.reflect.internal.MissingRequirementError: object scala in compiler mirror not found.
at scala.reflect.internal.MissingRequirementError$.signal(MissingRequirementError.scala:17)
at scala.reflect.internal.MissingRequirementError$.notFound(MissingRequirementError.scala:18)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:53)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:66)
at scala.reflect.internal.Mirrors$RootsBase.getPackage(Mirrors.scala:173)
at scala.reflect.internal.Definitions$DefinitionsClass.ScalaPackage$lzycompute(Definitions.scala:161)
at scala.reflect.internal.Definitions$DefinitionsClass.ScalaPackage(Definitions.scala:161)
at scala.reflect.internal.Definitions$DefinitionsClass.ScalaPackageClass$lzycompute(Definitions.scala:162)
at scala.reflect.internal.Definitions$DefinitionsClass.ScalaPackageClass(Definitions.scala:162)
at scala.reflect.internal.Definitions$DefinitionsClass.init(Definitions.scala:1375)
at scala.tools.nsc.Global$Run.<init>(Global.scala:1278)
at xsbt.CachedCompiler0$$anon$2.<init>(CompilerInterface.scala:113)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:113)
at xsbt.CachedCompiler0.run(CompilerInterface.scala:99)
at xsbt.CompilerInterface.run(CompilerInterface.scala:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:102)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:48)
at sbt.compiler.AnalyzingCompiler.compile(AnalyzingCompiler.scala:41)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply$mcV$sp(AggressiveCompile.scala:99)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:99)
at sbt.compiler.AggressiveCompile$$anonfun$3$$anonfun$compileScala$1$1.apply(AggressiveCompile.scala:99)
at sbt.compiler.AggressiveCompile.sbt$compiler$AggressiveCompile$$timed(AggressiveCompile.scala:166)
at sbt.compiler.AggressiveCompile$$anonfun$3.compileScala$1(AggressiveCompile.scala:98)
at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:143)
at sbt.compiler.AggressiveCompile$$anonfun$3.apply(AggressiveCompile.scala:87)
at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:39)
at sbt.inc.IncrementalCompile$$anonfun$doCompile$1.apply(Compile.scala:37)
at sbt.inc.IncrementalCommon.cycle(Incremental.scala:99)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:38)
at sbt.inc.Incremental$$anonfun$1.apply(Incremental.scala:37)
at sbt.inc.Incremental$.manageClassfiles(Incremental.scala:65)
at sbt.inc.Incremental$.compile(Incremental.scala:37)
at sbt.inc.IncrementalCompile$.apply(Compile.scala:27)
at sbt.compiler.AggressiveCompile.compile2(AggressiveCompile.scala:157)
at sbt.compiler.AggressiveCompile.compile1(AggressiveCompile.scala:71)
at sbt.compiler.AggressiveCompile.apply(AggressiveCompile.scala:46)
at sbt.Compiler$.apply(Compiler.scala:75)
at sbt.Compiler$.apply(Compiler.scala:66)
at sbt.Defaults$.sbt$Defaults$$compileTaskImpl(Defaults.scala:743)
at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:735)
at sbt.Defaults$$anonfun$compileTask$1.apply(Defaults.scala:735)
at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:42)
at sbt.std.Transform$$anon$4.work(System.scala:64)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
at sbt.Execute.work(Execute.scala:244)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:30)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
[error] (db-async-common/compile:compile) scala.reflect.internal.MissingRequirementError: object scala in compiler mirror not found.
[error] Total time: 2 s, completed Apr 26, 2014 7:43:49 PM
My build file looks like this:
import sbt._
import Keys._
object ProjectBuild extends Build {
val commonName = "db-async-common"
val postgresqlName = "postgresql-async"
val mysqlName = "mysql-async"
lazy val root = Project(
id = "db-async-base",
base = file("."),
settings = Configuration.baseSettings,
aggregate = Seq(common, postgresql, mysql)
)
lazy val common = Project(
id = commonName,
base = file(commonName),
settings = Configuration.baseSettings ++ Seq(
name := commonName,
libraryDependencies := Configuration.commonDependencies
)
)
lazy val postgresql = Project(
id = postgresqlName,
base = file(postgresqlName),
settings = Configuration.baseSettings ++ Seq(
name := postgresqlName,
libraryDependencies ++= Configuration.implementationDependencies
)
) aggregate (common) dependsOn (common)
lazy val mysql = Project(
id = mysqlName,
base = file(mysqlName),
settings = Configuration.baseSettings ++ Seq(
name := mysqlName,
libraryDependencies ++= Configuration.implementationDependencies
)
) aggregate (common) dependsOn (common)
}
object Configuration {
val commonVersion = "0.2.13"
val projectScalaVersion = "2.11.0"
val specs2Dependency = "org.specs2" %% "specs2" % "2.3.11" % "test"
val logbackDependency = "ch.qos.logback" % "logback-classic" % "1.0.13" % "test"
val commonDependencies = Seq(
"org.slf4j" % "slf4j-api" % "1.7.5",
"joda-time" % "joda-time" % "2.3",
"org.joda" % "joda-convert" % "1.5",
"io.netty" % "netty-all" % "4.0.18.Final",
"org.javassist" % "javassist" % "3.18.1-GA",
specs2Dependency,
logbackDependency
)
val implementationDependencies = Seq(
specs2Dependency,
logbackDependency
)
val baseSettings = Defaults.defaultSettings ++ Seq(
scalacOptions :=
Opts.compile.encoding("UTF8")
:+ Opts.compile.deprecation
:+ Opts.compile.unchecked
:+ "-feature"
,
scalacOptions in doc := Seq("-doc-external-doc:scala=http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/"),
scalaVersion := projectScalaVersion,
crossScalaVersions := Seq(projectScalaVersion, "2.10.4"),
javacOptions := Seq("-source", "1.6", "-target", "1.6", "-encoding", "UTF8"),
organization := "com.github.mauricio",
version := commonVersion,
parallelExecution := false,
publishArtifact in Test := false,
publishMavenStyle := true,
pomIncludeRepository := {
_ => false
},
publishTo <<= version {
v: String =>
val nexus = "https://oss.sonatype.org/"
if (v.trim.endsWith("SNAPSHOT"))
Some("snapshots" at nexus + "content/repositories/snapshots")
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
},
pomExtra := (
<url>https://github.com/mauricio/postgresql-async</url>
<licenses>
<license>
<name>APACHE-2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>git#github.com:mauricio/postgresql-netty.git</url>
<connection>scm:git:git#github.com:mauricio/postgresql-netty.git</connection>
</scm>
<developers>
<developer>
<id>mauricio</id>
<name>Maurício Linhares</name>
<url>https://github.com/mauricio</url>
</developer>
</developers>
)
)
}
And if you'd like to pull the source to check it's at this branch on Github.
Any info on trying to fix this would be very helpful.
The problem is very simple, in your Build.scala, you did almost all right, but in commons project you had overridden default commonDependencies. By default it contains dependency to scala-library.
This piece of code
lazy val common = Project(
id = commonName,
base = file(commonName),
settings = Configuration.baseSettings ++ Seq(
name := commonName,
libraryDependencies := Configuration.commonDependencies // #1
)
)
at the element marked as #1 should have
libraryDependencies ++= Configuration.commonDependencies
Ps. I've sent you a pull request with the fix.
I was getting this error when trying to use the Oracle Java 9 jvm on Ubuntu with sbt. Using the Java 8 jvm worked for me, though.
I think you answered before your questions Multimodule project build with SBT breaks with weird error
In this build add a line "org.scala-lang" % "scala-library" % projectScalaVersion,:
val commonDependencies = Seq(
..
"org.joda" % "joda-convert" % "1.5",
"org.scala-lang" % "scala-library" % projectScalaVersion,
"io.netty" % "netty-all" % "4.0.18.Final",
...
)
In Build.scala I would add autoScalaLibrary := true:
lazy val common = Project(
id = commonName,
base = file(commonName),
settings = Configuration.baseSettings ++ Seq(
...
autoScalaLibrary := true,
...
)
)
This problem was solved for me when using intellij, by closing the project and reimporting it, and selecting sbt as the build system in settings.
Why oh why did I choose SBT?? Now I'm stuck with a very brittle build system. Thank God that atleast intellij does it right.
sbt version: 0.13.15
scala version: 2.12.1

Play sub-projects: how to convert to build.sbt

I've a working multi-module Play 2.2 application which is organized like this...
myApp
+ app
+ conf
+ project
+ build.properties
+ Build.scala
+ plugin.sbt
... where Build.scala contains the following statements:
import sbt._
import Keys._
import play.Project._
object ApplicationBuild extends Build {
val appName = "myApp"
val appVersion = "1.0-SNAPSHOT"
val authDependencies = Seq(
"se.radley" %% "play-plugins-salat" % "1.3.0"
)
val mainDependencies = Seq(
"se.radley" %% "play-plugins-salat" % "1.3.0"
)
lazy val auth = play.Project(
appName + "-auth",
appVersion,
authDependencies,
path = file("modules/auth")).settings(
lessEntryPoints <<= baseDirectory(customLessEntryPoints),
routesImport += "se.radley.plugin.salat.Binders._",
templatesImport += "org.bson.types.ObjectId",
testOptions in Test := Nil,
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
)
lazy val main = play.Project(
appName,
appVersion,
mainDependencies).settings(
scalacOptions += "-language:reflectiveCalls",
routesImport += "se.radley.plugin.salat.Binders._",
templatesImport += "org.bson.types.ObjectId",
testOptions in Test := Nil,
lessEntryPoints <<= baseDirectory(customLessEntryPoints),
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
).dependsOn(auth).aggregate(auth)
def customLessEntryPoints(base: File): PathFinder = {
(base / "app" / "assets" / "stylesheets" / "bootstrap" * "bootstrap.less") +++
(base / "app" / "assets" / "stylesheets" * "*.less")
}
}
object Resolvers {
val scalaSbt = Resolver.url("Scala Sbt", url("http://repo.scala-sbt.org/scalasbt/sbt-plugin-snapshots"))(Resolver.ivyStylePatterns)
val sonatype = Resolver.sonatypeRepo("snapshots")
}
Now reading the Play 2.2 documentation it looks like I should convert my project to build.sbt:
The following example uses a build.scala file to declare a play.Project. This approach was the way Play applications were defined prior to version 2.2. The approach is retained in order to support backward compatibility. We recommend that you convert to the build.sbt based approach or, if using a build.scala, you use sbt’s Project type and project macro.
Is there any working example that describes how to replace project/build.scala with build.sbt? I read some short articles here and there... but I was unable to get a working Play project.
There is no urgent need to convert your build to build.sbt. build.sbt is simpler, but basically just gets compiled into Build.scala.
The other answer to this question will work, but is perhaps a little verbose. Start with the SBT documentation:
http://www.scala-sbt.org/0.13.0/docs/Getting-Started/Multi-Project.html
Now, create specify your main project and sub projects, and put your main project settings into your main build.sbt file:
lazy val auth = project.in(file("modules/auth"))
lazy val main = project.in(file(".")).dependsOn(auth).aggregate(auth)
playScalaSettings
name := "myApp"
version := "1.0-SNAPSHOT"
libraryDependencies += "se.radley" %% "play-plugins-salat" % "1.3.0"
scalacOptions += "-language:reflectiveCalls"
routesImport += "se.radley.plugin.salat.Binders._"
templatesImport += "org.bson.types.ObjectId"
testOptions in Test := Nil
lessEntryPoints <<= baseDirectory(customLessEntryPoints)
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
object Resolvers {
val scalaSbt = Resolver.url("Scala Sbt", url("http://repo.scala-sbt.org/scalasbt/sbt-plugin-snapshots"))(Resolver.ivyStylePatterns)
val sonatype = Resolver.sonatypeRepo("snapshots")
}
And now, in modules/auth/build.sbt, put your settings for the auth module:
name := "myApp-auth"
lessEntryPoints <<= baseDirectory(customLessEntryPoints)
routesImport += "se.radley.plugin.salat.Binders._"
templatesImport += "org.bson.types.ObjectId"
testOptions in Test := Nil
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
Anyway, it might need a bit of tweaking, but hopefully you get the point.
if using a build.scala, you use sbt’s Project type and project macro
Replace play.Project with Project and fix the arguments according to the ScalaDoc, it should be something like
lazy val auth = Project(
appName + "-auth",
file("modules/auth")).settings(
version := appVersion,
libraryDependencies ++= authDependencies,
lessEntryPoints <<= baseDirectory(customLessEntryPoints),
routesImport += "se.radley.plugin.salat.Binders._",
templatesImport += "org.bson.types.ObjectId",
testOptions in Test := Nil,
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
)
lazy val main = Project(
appName,
file("app")).settings(
version := appVersion,
libraryDependencies ++= mainDependencies,
scalacOptions += "-language:reflectiveCalls",
routesImport += "se.radley.plugin.salat.Binders._",
templatesImport += "org.bson.types.ObjectId",
testOptions in Test := Nil,
lessEntryPoints <<= baseDirectory(customLessEntryPoints),
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
).dependsOn(auth).aggregate(auth)
Same definitions can be used in build.sbt instead. I would also extract common settings:
val commonSettings = Seq(
version := appVersion,
routesImport += "se.radley.plugin.salat.Binders._",
templatesImport += "org.bson.types.ObjectId",
testOptions in Test := Nil,
lessEntryPoints <<= baseDirectory(customLessEntryPoints),
resolvers ++= Seq(Resolvers.sonatype, Resolvers.scalaSbt)
)
lazy val auth = Project(
appName + "-auth",
file("modules/auth")).settings(commonSettings: _*).settings(
libraryDependencies ++= authDependencies
)
lazy val main = Project(
appName,
file("app")).settings(commonSettings: _*).settings(
libraryDependencies ++= mainDependencies,
scalacOptions += "-language:reflectiveCalls"
).dependsOn(auth).aggregate(auth)

Play sub-projects do not compile

Here is the layout of my multi-project Play 2.2 application - I'm still trying to convert to build.sbt:
myApp
+ app
+ build.sbt
+ conf
| + routes
+ project
| + build.properties
| + Build.scala
| + plugin.sbt
+ modules
+ myModule
+ app
+ build.sbt
+ conf
+ routes
myApp/build.sbt:
name := "myApp"
version := "1.0-SNAPSHOT"
organization := "com.mydomain"
lazy val myModule = project.in(file("modules/myModule"))
lazy val main = project.in(file(".")).dependsOn(myModule).aggregate(myModule)
play.Project.playScalaSettings
resolvers ++= Seq(
Resolvers.typesafe,
Resolvers.sonatype
)
myApp/projects/Build.scala:
import sbt._
object Resolvers {
val sonatype = Resolver.sonatypeRepo("snapshots")
val typesafe = "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
}
myApp/modules/myModule/build.sbt:
name := "myModule"
libraryDependencies ++= Seq(
"com.typesafe.play" %% "play" % "2.2.1" % "provided",
"org.reactivemongo" %% "reactivemongo" % "0.10.0-SNAPSHOT",
"org.reactivemongo" %% "play2-reactivemongo" % "0.10.0-SNAPSHOT"
)
resolvers ++= Seq(
Resolvers.typesafe,
Resolvers.sonatype
)
I'm facing with two problems when trying to compile the project above:
1) Even if only the sub-project has dependencies (the main project is just a container for many sub-projects), I have to specify the resolvers also in the main build file myApp/build.sbt; if I don't, the project doesn't compile. This is not a blocking problem.. but I'd like to understand why.
2) Then, as soon as I try to compile the project, I always get the following error:
[error] /home/j3d/Projects/myApp/conf/routes:9: not found: value myModule
[error] -> /myModule myModule.Routes
[error] /home/j3d/Projects/myApp/conf/routes: not found: value myModule
[error] /home/j3d/Projects/myApp/conf/routes:12: not found: value myModule
[error] GET /assets/*file controllers.Assets.at(path="/public", file)
[error] /home/j3d/Projects/myApp/conf/routes:9: not found: value handler
[error] -> /myModule myModule.Routes
[error] four errors found
[error] (main/compile:compile) Compilation failed
[error] Total time: 12 s, completed Dec 1, 2013 6:34:55 PM
Here is myApp/conf/routes...
GET / controllers.Application.index
-> /myModule myModule.Routes
GET /assets/*file controllers.Assets.at(path="/public", file)
... and finally here is myApp/modules/myModule/conf/myModule.routes:
GET /myModule/greetings controllers.myModule.Greetings.hello
Am I missing something?
Figured out how to make it work and here below is my solution. First of all I've defined default settings and resolvers for all projects [myApp/project/Build.scala]:
import sbt._
import Keys._
object ApplicationBuild extends Build {
val defaultResolvers = Seq(
Resolver.sonatypeRepo("snapshots"),
"Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
)
val defaultSettings = Defaults.defaultSettings ++ Seq(
scalacOptions += "-language:reflectiveCalls",
resolvers ++= defaultResolvers
)
}
Then I've just imported ApplicationBuild.defaultSettings into every build.sbt. Here is the main project build file [myApp/build.sbt]...
name := "myApp"
version := "1.0-SNAPSHOT"
lazy val auth = project.in(file("modules/myModule"))
lazy val main = project.in(file(".")).dependsOn(myModule).aggregate(myModule)
ApplicationBuild.defaultSettings
playScalaSettings
... and here the sub-project build file [myApp/modules/myModule/build.sbt]:
name := "myModule"
ApplicationBuild.defaultSettings
playScalaSettings
libraryDependencies ++= Seq(
"org.reactivemongo" %% "play2-reactivemongo" % "0.10.0-SNAPSHOT",
"org.reactivemongo" %% "reactivemongo" % "0.10.0-SNAPSHOT"
)
It just works and hope it helps ;-)