sbt error when forking is enabled - scala

Sbt produce an error when there is this line:
fork in run := true
in this build.scala file
The surrounding build.scala content
lazy val scalafxDemos = Project(
id = "scalafx-demos",
base = file("scalafx-demos"),
settings = scalafxSettings ++ Seq(
libraryDependencies ++= Seq(
scalatest % "test",
junit % "test"),
unmanagedListing,
description := "The ScalaFX demonstrations",
fork in run := true,
fork in Test := true,
parallelExecution in Test := false,
// print junit-style XML for CI
testOptions in Test <+= (target in Test) map {
t => Tests.Argument(TestFrameworks.ScalaTest, "-u", "%s" format (t / "junitxmldir"))
},
The error produced:
[error] /Users/hanxue/Github/scalafx/project/build.scala:113: overloaded method value in with alternatives:
[error] (scope: sbt.Scope)sbt.SettingKey[Boolean] <and>
[error] (c: sbt.ConfigKey)sbt.SettingKey[Boolean] <and>
[error] (t: sbt.Scoped)sbt.SettingKey[Boolean] <and>
[error] (p: sbt.Reference)sbt.SettingKey[Boolean]
[error] cannot be applied to (run.type)
[error] fork in run := true,
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
I can avoid the error by changing the line to fork := true, though that does satisfy the intent of forking only in run and Test. How can I fix this without forcing everything else to be forked?

That probably means run is coming from somewhere else. You might try an explicit Keys.run to see if this is the case.

Related

How to fix "Could not find proxy for val base" error in sbt 1.3.0 loading project

I upgraded to sbt 1.3.0 and related plugins.sbt. When I try to start sbt for my project it fails to initialize with the error
java.lang.IllegalArgumentException: Could not find proxy for val base: sbt.SettingKey in List(value base, method sbtdef$1, method $sbtdef, object $bd1712fb73ddc970045f, package <empty>, package <root>) (currentOwner= method $sbtdef )
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.searchIn$1(LambdaLift.scala:316)
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.$anonfun$proxy$4(LambdaLift.scala:321)
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.searchIn$1(LambdaLift.scala:321)
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.$anonfun$proxy$4(LambdaLift.scala:321)
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.searchIn$1(LambdaLift.scala:321)
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.$anonfun$proxy$4(LambdaLift.scala:321)
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.searchIn$1(LambdaLift.scala:321)
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.$anonfun$proxy$4(LambdaLift.scala:321)
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.searchIn$1(LambdaLift.scala:321)
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.proxy(LambdaLift.scala:330)
[error] at scala.tools.nsc.transform.LambdaLift$LambdaLifter.proxyRef(LambdaLift.scala:370)
I did find this stackoverflow question Could not find proxy for ... in Macro , but I don't think it helps my error.
i think the code perpetrator is
//Ensure that version.sbt is included with each package.
mappings in Universal ++= {
val h=(packageBin in Compile, baseDirectory)
val base=h._2
val versionFile = (base.value / "version.sbt")
versionFile.get.map(file => file -> file.name)
}
and for some reason base is not storing (packageBin in Compile, baseDirectory) properly?
Edit:
I not a 100% but I think I fixed it by removing the intermediate variables and one lining it. So something like this:
mappings in Universal ++= {
((packageBin in Compile, baseDirectory)._2.value / "version.sbt").get.map(file => file -> file.name)
}
I don't know why it fixed it though...
I think the OP has confused the example with the ineffectual tuple use; perhaps there is some misunderstanding with some SBT API/DSL usage, that is, packageBin in Compile is never used or resolved (for it's side-effect).
I believe the error, however, is more to do with expressing the mappings in Universal task value in way the macro cannot process - it gets confused - for instance, expecting the macro/compiler to find the taskKey in a variable base, which is the _2 in a Tuple2.
The example could be rewritten as
mappings in Universal ++= {
(baseDirectory.value / "version.sbt").get.map(file => file -> file.name)
}
or
mappings in Universal ++= {
(baseDirectory in(Compile, packageBin)).value / "version.sbt").get.map(file => file -> file.name)
}
Depending on what the intention was (probably the latter).
Of course the new syntax would be
mappings in Universal ++= {
((Compile / packageBin / baseDirectory).value / "version.sbt").get.map(file => file -> file.name)
}

Setting up Cross Compilation for my SBT Auto plugin project

I am writing a SBT Auto Plugin. This is my build.sbt file
lazy val foo = (project in file(".")).settings(
name := "foo",
sbtPlugin := true,
organization := "com.foo",
crossScalaVersions = Seq("2.11.8", "2.12.4")
)
but I get the error
overloaded method value settings with alternatives:
(ss: sbt.Def.SettingsDefinition*)sbt.Project <and>
=> Seq[sbt.Def.Setting[_]]
cannot be applied to (sbt.Def.Setting[String], sbt.Def.Setting[Boolean], sbt.Def.Setting[String], crossScalaVersions: Seq[String])
lazy val foo = (project in file(".")).settings(
^
[error] sbt.compiler.EvalException: Type error in expression
[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
My objective is that when I do sbt publish I publish two jar files. one for scala 2.11 and other for scala 2.12
you have to give it like crossScalaVersions := Seq("2.11.8", "2.12.4") instead of crossScalaVersions = Seq("2.11.8", "2.12.4").
You can see more here Cross-Building a Project.

How can I use the Play Framework in a multi-project?

I am struggling to find any information on how to use the Play Framework in a multi-project where the root project is a plain SBT one. Basically this is my project's layout:
/
- common
- some-other-projects
- my-play-project
- - app
- - - controllers
- - conf
- - - routes
- build.sbt
I can start the application by running my-play-project/run in the SBT console, but when I try to visit any page, I get a 500 and this error is logged:
[error] /someorg/backend/cms/conf/routes: package router does not exist
[error] /someorg/backend/cms/conf/routes: cannot find symbol
[error] symbol: class ReversePostController
[error] location: package controllers
[error] /someorg/backend/cms/conf/routes: package controllers.javascript does not exist
[error] /someorg/backend/cms/conf/routes: cannot find symbol
[error] symbol: class ReversePostController
[error] location: package controllers
[error] /someorg/backend/cms/conf/routes: cannot find symbol
[error] symbol: variable RoutesPrefix
[error] location: class controllers.routes
[error] /someorg/backend/cms/conf/routes: package controllers.javascript does not exist
[error] /someorg/backend/cms/conf/routes: cannot find symbol
[error] symbol: variable RoutesPrefix
[error] location: class controllers.routes.javascript
[error] (cms/compile:compileIncremental) javac returned nonzero exit code
[info] Compiling 6 Scala sources and 1 Java source to /someorg/backend/cms/target/classes...
[error] /someorg/backend/cms/conf/routes: package router does not exist
[error] /someorg/backend/cms/conf/routes: cannot find symbol
[error] symbol: class ReversePostController
[error] location: package controllers
[error] /someorg/backend/cms/conf/routes: package controllers.javascript does not exist
[error] /someorg/backend/cms/conf/routes: cannot find symbol
[error] symbol: class ReversePostController
[error] location: package controllers
[error] /someorg/backend/cms/conf/routes: cannot find symbol
[error] symbol: variable RoutesPrefix
[error] location: class controllers.routes
[error] /someorg/backend/cms/conf/routes: package controllers.javascript does not exist
[error] /someorg/backend/cms/conf/routes: cannot find symbol
[error] symbol: variable RoutesPrefix
[error] location: class controllers.routes.javascript
[error] (cms/compile:compileIncremental) javac returned nonzero exit code
[error] application -
! #6pi9jna82 - Internal server error, for (GET) [/posts] ->
play.sbt.PlayExceptions$CompilationException: Compilation error[package router does not exist]
at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27)
at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27)
at scala.Option.map(Option.scala:145)
at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:49)
at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:44)
at scala.Option.map(Option.scala:145)
at play.sbt.run.PlayReload$.taskFailureHandler(PlayReload.scala:44)
at play.sbt.run.PlayReload$.compileFailure(PlayReload.scala:40)
at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17)
at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17)
Is there anything obvious I am missing that breaks this project? The controller is defined in the simplest possible way as explained in the documentation. The same goes for the only route I provide:
# Route
GET /posts controllers.PostController.list
// Controller
package controllers
import play.api.mvc.{Action, Controller}
class PostController extends Controller {
def list = TODO
}
I'm using Play Framework 2.5.1 and the project build is defined as follows:
lazy val resolvers = ...
lazy val projectSettings = Seq(
organization := "some-organization",
scalaBinaryVersion := "2.11",
scalaVersion := "2.11.7",
externalResolvers := resolvers,
moduleConfigurations := Seq(),
retrieveManaged := true,
concurrentRestrictions in Global += Tags.limit(Tags.Test, 1),
transitiveClassifiers in Scope.GlobalScope := Seq("sources"),
ivyLoggingLevel := UpdateLogging.Quiet,
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials"),
crossPaths := false,
publishMavenStyle := true,
publishArtifact in (Compile, packageDoc) := false,
publishArtifact in (Test, packageDoc) := false,
javacOptions := Seq("-source", "1.8", "-target", "1.8", "-encoding", "utf8"),
javaOptions := Seq("-server", "-XX:ReservedCodeCacheSize=192m", "-Xss2m"),
javaOptions in Test := Seq("-server", "-Xmx2g", "-XX:ReservedCodeCacheSize=192m", "-Xss2m"),
testFrameworks := Seq(TestFrameworks.ScalaTest, TestFrameworks.Specs2),
noTestCompletion(),
scalacOptions := Seq(
"-deprecation",
"-optimize",
"-unchecked",
"-encoding", "utf8",
"-target:jvm-1.8",
"-Xlog-reflective-calls",
"-feature",
"-language:_"
) ++ Seq(
"by-name-right-associative",
"delayedinit-select",
"doc-detached",
"inaccessible",
"missing-interpolator",
"nullary-override",
"option-implicit",
"package-object-classes",
"poly-implicit-overload",
"private-shadow",
"unsound-match"
).map(x => s"-Xlint:$x"),
compileOrder := CompileOrder.JavaThenScala,
fork in Test := true,
testOptions in Test := Seq(Tests.Filter(testName => testName.endsWith("Test") || testName.endsWith("Spec"))),
testOptions in Test += Tests.Argument("-oDF"),
testOptions in Test <+= (target in Test).map { t =>
val testDir = t / "test-reports"
val maybeJUnitXml = if (flag("sbt.test.nojunitxml")) Seq.empty else Seq("-u", testDir.getAbsolutePath)
Tests.Argument(TestFrameworks.ScalaTest, maybeJUnitXml: _*)
}
)
lazy val cms = (project in file("cms"))
.settings(projectSettings)
.dependsOn(common, commonTest % "test", model % compileTest)
.enablePlugins(PlayScala)
lazy val root = (project in file("."))
.settings(projectSettings)
.aggregate(common, some-other-projects, cms) // TODO: Remove web
Update:
Now that you've posted your build.sbt file, I think the problem is the compile order. javac fails because it cannot find the mentioned package.
Try to use the default Mixed compilation order.
I suspect that you didn't enable the sbt-play plugin in the my-play-project subproject and hence your routes file wasn't compiled to my-play-project/target/scala-2.11/routes/main/router
In my-play-project/build.sbt, add:
enablePlugins(PlayScala)
Try adding the Play plugin declaration to the root project at /project/plugins.sbt

Why does inspect compile:packageWar::packagedArtifact fail in the Sbt console when using xsbt-web-plugin?

I am using xsbt-web-plugin with Sbt 0.13.2. If I add the following to build.sbt I can type "myTask" in the console and it works:
val myTask = taskKey[Unit]("My task.")
myTask := {
val (art, file) = packagedArtifact.in(Compile, packageWar).value
println("Artifact definition: " + art)
println("Packaged file: " + file.getAbsolutePath)
}
But why does this return an error if I type it in the Sbt console?
inspect compile:packageWar::packagedArtifact
Error message:
[error] Expected key
[error] Not a valid key: packageWar (similar: package, packageSrc, package-src)
[error] inspect compile:packageWar::packagedArtifact
[error] ^
For comparison, this one does work:
inspect compile:packageBin::packagedArtifact
Key parts of build.sbt:
tomcat()
name := "my-war"
scalaVersion := "2.10.4"
webappSrc in webapp := baseDirectory.value / "web"
webInfClasses in webapp := true
val myTask = taskKey[Unit]("My task.")
myTask := {
val (art, file) = packagedArtifact.in(Compile, packageWar).value
println("Artifact definition: " + art)
println("Packaged file: " + file.getAbsolutePath)
}
project/plugins.sbt:
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "1.0.0-M4")
(I'm only asking so that I can understand Sbt better, it's not actually causing a problem.)
You can get this info from package rather than packageWar:
> inspect compile:package::packagedArtifact
[info] Task: scala.Tuple2[sbt.Artifact, java.io.File]
[info] Description:
[info] Generates a packaged artifact, returning the Artifact and the produced File.
The packageWar task is set up indirectly using packageTaskSettings.

Writing a custom matcher for NodeSeq

I'm trying to write a simple custom matcher for NodeSeq, with scalatest v.2.0.M5b.
package test
import org.scalatest.matchers.{MatchResult, Matcher, ShouldMatchers}
import scala.xml.NodeSeq
import org.scalatest.FunSpec
class MySpec extends FunSpec with ShouldMatchers with MyMatcher {
describe("where is wrong?") {
it("showOK") {
val xml = <span>abc</span>
xml should contn("b")
}
}
}
trait MyMatcher {
class XmlMatcher(str: String) extends Matcher[NodeSeq] {
def apply(xml: NodeSeq) = {
val x = xml.toString.contains(str)
MatchResult(
x,
"aaa",
"bbb"
)
}
}
def contn(str: String) = new XmlMatcher(str)
}
When I compile it, it reports error:
[error] /Users/freewind/src/test/scala/test/MyMacher.scala:14: overloaded method value should with alternatives:
[error] (beWord: MySpec.this.BeWord)MySpec.this.ResultOfBeWordForAnyRef[scala.collection.GenSeq[scala.xml.Node]] <and>
[error] (notWord: MySpec.this.NotWord)MySpec.this.ResultOfNotWordForAnyRef[scala.collection.GenSeq[scala.xml.Node]] <and>
[error] (haveWord: MySpec.this.HaveWord)MySpec.this.ResultOfHaveWordForSeq[scala.xml.Node] <and>
[error] (rightMatcher: org.scalatest.matchers.Matcher[scala.collection.GenSeq[scala.xml.Node]])Unit
[error] cannot be applied to (MySpec.this.XmlMatcher)
[error] xml should contn("b")
[error] ^
[error] one error found
[error] (test:compile) Compilation failed
Where is wrong?
Update:
The build.sbt file I use:
name := "scalatest-test"
scalaVersion := "2.10.1"
version := "1.0"
resolvers ++= Seq("snapshots" at "http://oss.sonatype.org/content/repositories/snapshots",
"releases" at "http://oss.sonatype.org/content/repositories/releases",
"googlecode" at "http://sass-java.googlecode.com/svn/repo"
)
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M5b" % "test"
And a demo project: https://github.com/freewind/scalatest-test
For the reason why scala compiler complains see this answer.
But it seems that ScalaTest API has changed quite a bit since then, so the two solutions proposed both need some modification (tested for ScalaTest 2.0.M5b):
Replace All instances of NodeSeq to GenSeq[Node] so that the type matches everywhere.
See SeqShouldWrapper class of ScalaTest.
Alternatively, wrap xml explicitely with the conversion function, i.e. manually setting the required type but I don't recommend this because it makes client code ugly.
new AnyRefShouldWrapper(xml).should(contn("b"))
BTW, it is good to have a small but complete project on github for others to tweak. It makes this question much more attractive.