I am trying to create a Play application with a back end and a front end(using Scala.js). I separated the code into client and server folders.
For creating a Multi Project Build I looked at this http://www.scala-sbt.org/release/docs/Multi-Project.html and make my build.sbt like this:
name := """ScalaWeb"""
version := "1.0-SNAPSHOT"
lazy val commonSettings = Seq(
scalaVersion := "2.11.7",
libraryDependencies ++= Seq(
jdbc,
cache,
ws,
specs2 % Test
),
libraryDependencies ++= Seq(
"org.sorm-framework" % "sorm" % "0.3.19",
"org.scala-lang" % "scala-compiler" % scalaVersion.value force(),
"com.h2database" % "h2" % "1.3.148"
),
libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.1.0",
/*libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.1.0",
libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.12"
libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.1.3"*/
resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases",
// Play provides two styles of routers, one expects its actions to be injected, the
// other, legacy style, accesses its actions statically.
routesGenerator := InjectedRoutesGenerator,
scalacOptions += "-Ylog-classpath",
// use this if you just want jawn's parser, and will implement your own facade
libraryDependencies += "org.spire-math" %% "jawn-parser" % "0.8.3",
// use this if you want jawn's parser and also jawn's ast
libraryDependencies += "org.spire-math" %% "jawn-ast" % "0.8.3",
//for reading Json libraries
libraryDependencies += "org.scalaj" %% "scalaj-http" % "2.2.1"
)
lazy val server = (project in file("server")).settings(
commonSettings: _*
).enablePlugins(PlayScala)
lazy val client = (project in file("client")).settings(
commonSettings: _*
).enablePlugins(PlayScala)
fork in run := true
So basically I placed all dependencies into commonSettings and the imported that into the client and server projects.
However, I am getting this error:
[error] (scalaweb/compile:backgroundRun) No main class detected.
Why is this occuring?
Have I set up my build.sbt incorrectly?
That's because your root project (scalaweb) doesn't have a main class.
You can either:
run server's run command by doing: server/run
aggregate client and server under root project
(http://www.scala-sbt.org/0.13/docs/Multi-Project.html#Aggregation)
This might do what you wish.
Related
I am trying to upgrade mumoshu's Memcached Plugin for Play framework, to Play 2.8.6, in build.sbt.
The upgrade instructions are:
For Play 2.6.x and newer: !!! Changed play.modules.cache.* config keys to play.cache.* !!!
val appDependencies = Seq(
play.PlayImport.cacheApi,
"com.github.mumoshu" %% "play2-memcached-play26" % "0.9.2"
)
val main = Project(appName).enablePlugins(play.PlayScala).settings(
version := appVersion,
libraryDependencies ++= appDependencies,
resolvers += "Spy Repository" at "http://files.couchbase.com/maven2" // required to resolve `spymemcached`, the plugin's dependency.
)
Before the upgrade, I had:
libraryDependencies ++= Seq(
jdbc,
cache,
ws,
"com.github.mumoshu" %% "play2-memcached-play24" % "0.7.0",
//...
}
After the (unsuccessful) upgrade:
the cache dependency is not resolved, so I removed it.
The updated build.sbt now looks like this:
name := "CH07"
version := "1.0"
lazy val `ch07` = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.13.4"
resolvers += "Spy Repository" at "http://files.couchbase.com/maven2"
val appDependencies = Seq(
play.sbt.PlayImport.cache,
"com.github.mumoshu" %% "play2-memcached-play28" % "0.11.0"
//"com.github.mumoshu" %% "play2-memcached-play26" % "0.9.2"
)
val main = (project in file(".")).enablePlugins(play.sbt.PlayScala).settings(
version := version.value,
libraryDependencies ++= appDependencies,
resolvers += "Spy Repository" at "http://files.couchbase.com/maven2" // required to resolve `spymemcached`, the plugin's dependency.
)
libraryDependencies ++= Seq(
jdbc,
//cache,
ws,
"org.hsqldb" % "hsqldb" % "2.5.0",
"org.jooq" % "jooq" % "3.14.4",
"org.jooq" % "jooq-codegen-maven" % "3.14.4",
"org.jooq" % "jooq-meta" % "3.14.4",
"joda-time" % "joda-time" % "2.7",
"com.github.ironfish" %% "akka-persistence-mongo-casbah" % "0.7.6",
"com.ning" % "async-http-client" % "1.9.29"
)
routesGenerator := InjectedRoutesGenerator
Errors I am getting:
* build.sbt:
error: value cache is not a member of object play.sbt.PlayImport
* build.sbt:
"com.github.mumoshu" %% "play2-memcached-play28" % "0.11.0"
Intellij says: unresolved artifact. Not resolved or indexed.
* in project/plugins.sbt:
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.6")
Intellij says: unresolved artifact. Not resolved or indexed.
Can you see any errors I made in the build.sbt?
In other words, I am looking for a working build.sbt (and the other required definitions) example for a project that uses Play 2.8.6 and the Memcached Plugin for Play framework 0.9.2. (or highest possible version of the latter).
UPDATE:
This is my current configuration which does compile:
build.sbt
name := "CH07"
version := "1.0"
lazy val `ch07` = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.13.4"
resolvers += "Spy Repository" at "http://files.couchbase.com/maven2"
libraryDependencies ++= Seq(
jdbc,
cacheApi,
ws,
"com.github.mumoshu" %% "play2-memcached-play28" % "0.11.0",
"org.hsqldb" % "hsqldb" % "2.5.0",
"org.jooq" % "jooq" % "3.14.4",
"org.jooq" % "jooq-codegen-maven" % "3.14.4",
"org.jooq" % "jooq-meta" % "3.14.4",
"joda-time" % "joda-time" % "2.7",
"com.ning" % "async-http-client" % "1.9.29",
"com.github.scullxbones" %% "akka-persistence-mongo-common" % "3.0.5",
"com.typesafe.akka" %% "akka-persistence" % "2.6.10",
"com.typesafe.akka" %% "akka-persistence-query" % "2.6.10",
"com.typesafe.akka" %% "akka-persistence-typed" % "2.6.10",
"com.typesafe.play" %% "play-guice" % "2.8.7"
)
routesGenerator := InjectedRoutesGenerator
project/build.properties
sbt.version=1.3.10
project/plugins.sbt
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.7")
How about this?
name := """pla-memcache-example"""
organization := "com.example"
version := "1.0-SNAPSHOT"
scalaVersion := "2.13.3"
val appDependencies = Seq(
guice,
play.PlayImport.cacheApi,
"com.github.mumoshu" %% "play2-memcached-play28" % "0.11.0",
"org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test
)
lazy val root = (project in file(".")).enablePlugins(PlayScala).settings(
version := appVersion,
libraryDependencies ++= appDependencies,
resolvers += "Spy Repository" at "http://files.couchbase.com/maven2" // required to resolve `spymemcached`, the plugin's dependency.
)
plugins.sbt
sbt.version=1.3.13
plugins.sbt
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.7")
In this case, first find the giter8 template and use the "sbt new" command.
Next, go to the official page of the plugin and check the name of the library, and then use Maven search to find the version you want to use.
It's a good idea to read the entire readme of the plugin without skipping it.
You can also try to run sbt with commands instead of using IntelliJ.
If that doesn't solve the problem, you can try clearing the cache in the .ivy2 directory.
Reference Links:
https://github.com/mumoshu/play2-memcached
https://github.com/playframework/play-scala-seed.g8
https://search.maven.org/artifact/com.github.mumoshu/play2-memcached-play28_2.13/0.11.0/jar
Your issue is when trying to import play.sbt.PlayImport.cache. According to Cache APIs Migration by play:
New packages
Now `cache` has been split into a `cacheApi` component with just the API, and `ehcache` that contains the Ehcache implementation. If you are using the default Ehcache implementation, simply change `cache` to `ehcache` in your `build.sbt`:
libraryDependencies ++= Seq(
ehcache
)
If you are defining a custom cache API, or are writing a cache implementation module, you can just depend on the API:
libraryDependencies ++= Seq(
cacheApi
)
Removed APIs
The deprecated Java class play.cache.Cache was removed and you now must inject an play.cache.SyncCacheApi or play.cache.AsyncCacheApi.
Therefore a complete build.sbt will be:
name := "CH07"
version := "1.0"
lazy val `ch07` = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.13.4"
resolvers += "Spy Repository" at "https://files.couchbase.com/maven2"
val appDependencies = Seq(
play.sbt.PlayImport.ehcache,
play.sbt.PlayImport.cacheApi,
"com.github.mumoshu" %% "play2-memcached-play28" % "0.11.0"
//"com.github.mumoshu" %% "play2-memcached-play26" % "0.9.2"
)
val main = (project in file(".")).enablePlugins(play.sbt.PlayScala).settings(
version := version.value,
libraryDependencies ++= appDependencies,
resolvers += "Spy Repository" at "https://files.couchbase.com/maven2" // required to resolve `spymemcached`, the plugin's dependency.
)
libraryDependencies ++= Seq(
jdbc,
//cache,
ws,
"org.hsqldb" % "hsqldb" % "2.5.0",
"org.jooq" % "jooq" % "3.14.4",
"org.jooq" % "jooq-codegen-maven" % "3.14.4",
"org.jooq" % "jooq-meta" % "3.14.4",
"joda-time" % "joda-time" % "2.7",
"com.github.scullxbones" %% "akka-persistence-mongo-common" % "3.0.5",
"com.ning" % "async-http-client" % "1.9.29"
)
routesGenerator := InjectedRoutesGenerator
build.properties:
sbt.version=1.4.4
plugins.sbt:
logLevel := Level.Warn
resolvers += "Typesafe repository" at "https://repo.typesafe.com/typesafe/releases/"
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.7")
I am building a SBT multi-project project, which has common module and logic module, and logic.dependsOn(common).
In common, SparkSQL 2.2.1 ("org.apache.spark" %% "spark-sql" % "2.2.1") is introduced. In logic, SparkSQL also is used, however I get compilation errors, saying "object spark is not a member of package org.apache".
Now, if I add SparkSQL dependency to logic as "org.apache.spark" %% "spark-sql" % "2.2.1", it works. However if I add "org.apache.spark" %% "spark-sql" % "2.2.1" % Provided", I get the same error.
I don't get why this happened, why not the dependency can't be transitive from common to logic
here is the root sbt files:
lazy val commonSettings = Seq(
organization := "...",
version := "0.1.0",
scalaVersion := "2.11.12",
resolvers ++= Seq(
clojars,
maven_local,
novus,
twitter,
spark_packages,
artima
),
test in assembly := {},
assemblyMergeStrategy in assembly := {...}
)
lazy val root = (project in file(".")).aggregate(common, logic)
lazy val common = (project in file("common")).settings(commonSettings:_*)
lazy val logic = (project in file("logic")).dependsOn(common).settings(commonSettings:_*)
here is the logic module sbt file:
libraryDependencies ++= Seq(
spark_sql.exclude("io.netty", "netty"),
embedded_elasticsearch % "test",
scalatest % "test"
)
dependencyOverrides ++= Seq(
"com.fasterxml.jackson.core" % "jackson-core" % "2.6.5",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.6.5",
"com.fasterxml.jackson.module" % "jackson-module-scala_2.11" % "2.6.5",
"com.fasterxml.jackson.core" % "jackson-annotation" % "2.6.5",
"org.json4s" %% "json4s-jackson" % "3.2.11"
)
assemblyJarName in assembly := "***.jar"
I am trying to create a new project, this time with sbt 1.0.2 instead of 0.13.x which I used for quite some time now.
There I had a multi-project setup comparable to https://github.com/vmunier/akka-http-with-scalajs-example/blob/master/build.sbt
My problem now is that I always get [error] (projectname/compile:bgRun) No main class detected. when I try to run sbt run
Here is my current build.sbt file:
lazy val generalSettings = Seq(
name := "awesomeproject.tld",
version := "0.1",
scalaVersion := "2.12.3"
)
lazy val client = (project in file("modules/client"))
.settings(generalSettings: _*)
.settings(
name := "client",
libraryDependencies ++= Seq(
"com.lihaoyi" %%% "scalatags" % "0.6.5",
"org.scala-js" %%% "scalajs-dom" % "0.9.2"
)
, scalaJSUseMainModuleInitializer := true
)
.enablePlugins(ScalaJSPlugin, ScalaJSWeb)
.dependsOn(sharedJS)
lazy val server = (project in file("modules/server"))
.settings(generalSettings: _*)
.settings(
name := "server",
scalaJSProjects := Seq(client),
pipelineStages in Assets := Seq(scalaJSPipeline),
// triggers scalaJSPipeline when using compile or continuous compilation
//compile in Compile := ((compile in Compile) dependsOn scalaJSPipeline).value,
WebKeys.packagePrefix in Assets := "public/",
//managedClasspath in Runtime += (packageBin in Assets).value,
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.5.4",
"com.typesafe.akka" %% "akka-testkit" % "2.5.4" % Test,
"com.typesafe.akka" %% "akka-stream" % "2.5.4",
"com.typesafe.akka" %% "akka-stream-testkit" % "2.5.4" % Test,
"com.typesafe.akka" %% "akka-http" % "10.0.10",
"com.typesafe.akka" %% "akka-http-testkit" % "10.0.10" % Test,
"ch.qos.logback" % "logback-classic" % "1.2.3",
"com.typesafe.scala-logging" %% "scala-logging" % "3.7.2",
"com.lihaoyi" %% "scalatags" % "0.6.5",
"com.vmunier" %% "scalajs-scripts" % "1.1.0"
)
, mainClass := Some("tld.awesomeproject.Main")
)
.dependsOn(sharedJVM)
lazy val shared = (crossProject.crossType(CrossType.Pure) in file("modules/shared"))
.settings(generalSettings: _*)
.settings(
name := "shared"
)
lazy val sharedJS = shared.js
lazy val sharedJVM = shared.jvm
As you can see I tried to solve the problem with setting it explicitly with mainClass := Some("tld.awesomeproject.Main") in the subproject. I also tried to set a root project explicitly, make it dependOn the server but no luck.
I guess the real problem here is, that
onLoad in Global := (Command.command("project server", _: State)) compose (onLoad in Global) does not work in sbt 1.0.2 anymore.
I checked the Command class, but I am not wiser after. There simply is no more method that gives back a state.
Can anyone shed like on this? What I want is to run a server that sends some javascript to the client... that shouldn't be black magic, in fact everything worked like a charm in my 0.13. project.
This should work:
onLoad in Global ~= (_ andThen ("project server" :: _))
Reference: https://github.com/sbt/sbt/issues/1224#issuecomment-331840364
I want to use spring-data-neo4j with play framework 2.6 in Scala. But when I add the library dependency I have a compilation error:
object neo4j is not a member of package org
for
import org.neo4j.ogm.annotation.{GraphId, NodeEntity}
I think I don't have good resolvers:
name := """Project-name"""
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
resolvers += Resolver.sonatypeRepo("snapshots")
scalaVersion := "2.12.2"
libraryDependencies ++= Seq(
guice,
"org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0" % Test,
"com.h2database" % "h2" % "1.4.194",
"org.springframework.data" % "spring-data-neo4j" % "4.2.6.RELEASE"
)
The classes you are trying to import import org.neo4j.ogm.annotation.{GraphId, NodeEntity} is part of neo4j-ogm-core artifact. so you must include it as shown below to able to access those classes.
libraryDependencies += "org.neo4j" % "neo4j-ogm-core" % "3.0.0-RC1"
So I have a Scalatra app (using Scalatra 2.2.1). I'm building views using Scalate; I've decided to go with the Jade/Markdown one-two. Only one problem: if I try to use markdown in a jade template (started with the :markdown tag), I get this:
scala.Predef$.any2ArrowAssoc(Ljava/lang/Object;)Lscala/Predef$ArrowAssoc;
java.lang.NoSuchMethodError: scala.Predef$.any2ArrowAssoc(Ljava/lang/Object;)Lscala/Predef$ArrowAssoc;
at org.fusesource.scalamd.Markdown$.<init>(md.scala:119)
at org.fusesource.scalamd.Markdown$.<clinit>(md.scala:-1)
at org.fusesource.scalate.filter.ScalaMarkdownFilter$.filter(ScalaMarkdownFilter.scala:32)
at org.fusesource.scalate.RenderContext$class.filter(RenderContext.scala:276)
at org.fusesource.scalate.DefaultRenderContext.filter(DefaultRenderContext.scala:30)
at org.fusesource.scalate.RenderContext$class.value(RenderContext.scala:235)
at org.fusesource.scalate.DefaultRenderContext.value(DefaultRenderContext.scala:30)
at templates.views.$_scalate_$about_jade$.$_scalate_$render(about_jade.scala:37)
at templates.views.$_scalate_$about_jade.render(about_jade.scala:48)
at org.fusesource.scalate.DefaultRenderContext.capture(DefaultRenderContext.scala:92)
at org.fusesource.scalate.layout.DefaultLayoutStrategy.layout(DefaultLayoutStrategy.scala:45)
at org.fusesource.scalate.TemplateEngine$$anonfun$layout$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(TemplateEngine.scala:559)
at org.fusesource.scalate.TemplateEngine$$anonfun$layout$1$$anonfun$apply$mcV$sp$1.apply(TemplateEngine.scala:559)
at org.fusesource.scalate.TemplateEngine$$anonfun$layout$1$$anonfun$apply$mcV$sp$1.apply(TemplateEngine.scala:559)
So that's pretty cool. The error vanishes as soon as I remove the :markdown flag, and beyond that everything compiles (beyond markdown not getting rendered correctly).
Things I know and have found so far:
There's some thought that this error is the biproduct of incompatible Scala versions somewhere in the build. My build.scala defines Scala version as 2.10.0, which Scalatra is explicitly compatible with.
...that said, I have no idea which version of Scalate Scalatra pulls in, and my attempts to override it have not worked so far. I know the current stable of Scalate (1.6.1) is only compatible up to Scala 2.10.0 -- but that's what I'm using.
I am, however, sure that my classpath is clean. I have no conflicting Scala versions. Everything is 2.10.0 in the dependencies.
Has anybody worked with this one before? Any ideas?
EDIT
Per request, here are my build definitions:
//build.sbt
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M5b" % "test"
libraryDependencies += "org.twitter4j" % "twitter4j-core" % "3.0.3"
libraryDependencies += "org.fusesource.scalamd" % "scalamd" % "1.5"
//build.properties
sbt.version=0.12.3
//build.scala
import sbt._
import Keys._
import org.scalatra.sbt._
import org.scalatra.sbt.PluginKeys._
import com.mojolly.scalate.ScalatePlugin._
import ScalateKeys._
object TheRangeBuild extends Build {
val Organization = "com.gastove"
val Name = "The Range"
val Version = "0.1.0-SNAPSHOT"
val ScalaVersion = "2.10.0"
val ScalatraVersion = "2.2.1"
lazy val project = Project (
"the-range",
file("."),
settings = Defaults.defaultSettings ++ ScalatraPlugin.scalatraWithJRebel ++ scalateSettings ++ Seq(
organization := Organization,
name := Name,
version := Version,
scalaVersion := ScalaVersion,
resolvers += Classpaths.typesafeReleases,
libraryDependencies ++= Seq(
"org.scalatra" %% "scalatra" % ScalatraVersion,
"org.scalatra" %% "scalatra-scalate" % ScalatraVersion,
"org.scalatra" %% "scalatra-specs2" % ScalatraVersion % "test",
"ch.qos.logback" % "logback-classic" % "1.0.6" % "runtime",
"org.eclipse.jetty" % "jetty-webapp" % "8.1.8.v20121106" % "compile;container",
"org.eclipse.jetty.orbit" % "javax.servlet" % "3.0.0.v201112011016" % "compile;container;provided;test" artifacts (Artifact("javax.servlet", "jar", "jar"))
),
scalateTemplateConfig in Compile <<= (sourceDirectory in Compile){ base =>
Seq(
TemplateConfig(
base / "webapp" / "WEB-INF" / "templates",
Seq.empty, /* default imports should be added here */
Seq(
Binding("context", "_root_.org.scalatra.scalate.ScalatraRenderContext", importMembers = true, isImplicit = true)
), /* add extra bindings here */
Some("templates")
)
)
}
) ++ seq(com.typesafe.startscript.StartScriptPlugin.startScriptForClassesSettings: _*)
)
}
When using the markdown filter, you need to add the scalamd library as runtime dependency:
"org.fusesource.scalamd" %% "scalamd" % "1.6"
The most recent version can be found on Maven Central
Also you can delete the build.sbt file and put the dependencies into build.scala file which makes things a bit simpler.
import sbt._
import Keys._
import org.scalatra.sbt._
import org.scalatra.sbt.PluginKeys._
import com.mojolly.scalate.ScalatePlugin._
import ScalateKeys._
object TheRangeBuild extends Build {
val Organization = "com.gastove"
val Name = "The Range"
val Version = "0.1.0-SNAPSHOT"
val ScalaVersion = "2.10.0"
val ScalatraVersion = "2.2.1"
lazy val project = Project(
"the-range",
file("."),
settings = Defaults.defaultSettings ++ ScalatraPlugin.scalatraWithJRebel ++ scalateSettings ++ Seq(
organization := Organization,
name := Name,
version := Version,
scalaVersion := ScalaVersion,
resolvers += Classpaths.typesafeReleases,
libraryDependencies ++= Seq( // adding this Seq to the libraryDependencies
"org.scalatra" %% "scalatra" % ScalatraVersion,
"org.scalatra" %% "scalatra-scalate" % ScalatraVersion,
"org.scalatra" %% "scalatra-specs2" % ScalatraVersion % "test",
"ch.qos.logback" % "logback-classic" % "1.0.6" % "runtime",
"org.eclipse.jetty" % "jetty-webapp" % "8.1.8.v20121106" % "compile;container",
"org.scalatest" %% "scalatest" % "2.0.M5b" % "test",
"org.twitter4j" % "twitter4j-core" % "3.0.3",
"org.fusesource.scalamd" % "scalamd" % "1.6",
"org.eclipse.jetty.orbit" % "javax.servlet" % "3.0.0.v201112011016" % "compile;container;provided;test" artifacts (Artifact("javax.servlet", "jar", "jar"))
),
scalateTemplateConfig in Compile <<= (sourceDirectory in Compile){ base =>
Seq(
TemplateConfig(
base / "webapp" / "WEB-INF" / "templates",
Seq.empty, /* default imports should be added here */
Seq(
Binding("context", "_root_.org.scalatra.scalate.ScalatraRenderContext", importMembers = true, isImplicit = true)
), /* add extra bindings here */
Some("templates")
)
)
}
) ++ seq(com.typesafe.startscript.StartScriptPlugin.startScriptForClassesSettings: _*)
)
}
This comes from:
libraryDependencies += "org.fusesource.scalamd" % "scalamd" % "1.5"
Looking at the scalamd-1.5 pom.xml, it is built against Scala 2.8.1, which is not compatible with 2.10.
Dependency resolution keeps 2.10 and discard the 2.8.1 dependency, and you end up with this classpath issue.
The only solution you have is to try and build a new scalamd version against Scala 2.10, potentially fix a few things to get it there, and then publish it (at least locally).