sbt get real compiler options in custom sbt plugin - scala

I know there is scalacOptions in sbt. But options add via addCompilerPlugin does not exists in scalacOptions.
I type show scalacOptions in sbt console and there is nothing like -Xplugin.
So how can I get real scalac options when I am writing an sbt plugin
My sbt info
> libraryDependencies
[info] List(org.scala-lang:scala-library:2.10.4, org.scala-lang:scala-reflect:2.10.4, io.netty:netty:3.9.0.Final, net.sandrogrzicic:scalabuff-runtime:1.3.7, org.scalamacros:quasiquotes:2.0.0, org.specs2:specs2:2.3.11:test, org.scalamacros:paradise:2.0.0:plugin->default(compile))
> show scalacOptions
[info] List(-feature, -deprecation, -language:implicitConversions, -language:dynamics)
[success] Total time: 0 s, completed Jul 3, 2014 4:04:09 PM
> version
[info] 0.0.1-SNAPSHOT
> sbt
sbtBinaryVersion sbtClearOnFailure sbtDependency sbtPlugin sbtPopOnFailure sbtResolver sbtStashOnFailure
> sbtVersion
[info] 0.13.5
>
my build.sbt
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % "2.10.4",
"io.netty" % "netty" % "3.9.0.Final",
"net.sandrogrzicic" %% "scalabuff-runtime" % "1.3.7",
"org.scalamacros" %% "quasiquotes" % "2.0.0",
"org.specs2" %% "specs2" % "2.3.11" % "test")
scalacOptions ++= Seq(
"-feature",
"-deprecation",
"-language:implicitConversions",
"-language:dynamics"
)
parallelExecution in Test := false
addCompilerPlugin("org.scalamacros" % "paradise" % "2.0.0" cross CrossVersion.full)

Finally I found compile:scalacOptions actually contains the plugin settings

Are you sure that you have actually managed to add the compiler plugin?
With sbt 0.13.5 and an empty project with this in build.sbt:
addCompilerPlugin("org.scala-lang.plugins" % "continuations" % "2.10.1")
I get the plugin in both libraryDependencies and scalacOptions:
> libraryDependencies
[info] List(org.scala-lang:scala-library:2.10.4, org.scala-lang.plugins:continuations:2.10.1:plugin->default(compile))
> show scalacOptions
[info] List(-Xplugin:/Users/johan/.ivy2/cache/org.scala-lang.plugins/continuations/jars/continuations-2.10.1.jar)

Related

common-validator sbt dependency for scala 2.12.1

My sbt file looks as follows
organization := "scala"
name := "MyProject"
version := "1.0"
scalaVersion := "2.12.1"
libraryDependencies += "com.github.nscala-time" %% "nscala-time" % "2.20.0"
libraryDependencies += "commons-net" % "commons-net" % "3.6"
libraryDependencies += "commons-validator" % "commons-validator" % "1.6.0"
When I run sbt compile I get this
sbt.librarymanagement.ResolveException: unresolved dependency: commons-validator#commons-validator;1.6.0: not found
However when I change scala version to 2.11.7, sbt compiles fine. What am I missing? How can I make it work for 2.12.1?
According to mvnrepo (https://mvnrepository.com/artifact/commons-validator/commons-validator)
use libraryDependencies += "commons-validator" % "commons-validator" % "1.6"

sbt assembly plugin includes "provided" libraries and it's lineage

Here is my build.sbt
resolvers ++= Seq("Apache Development Snapshot Repository" at "https://repository.apache.org/content/repositories/snapshots/",
Resolver.mavenLocal)
name := "flink-wiki-edits"
version := "1.0"
scalaVersion := "2.11.7"
val flinkVersion = "1.1.3"
val flinkDependencies = Seq(
"org.apache.flink" %% "flink-scala" % flinkVersion % "provided",
"org.apache.flink" %% "flink-streaming-scala" % flinkVersion % "provided",
"org.apache.flink" %% "flink-connector-wikiedits"% flinkVersion )
lazy val root = (project in file(".")).
settings(
libraryDependencies ++= flinkDependencies
)
mainClass in assembly := Some("com.ta.WikipediaAnalytics")
// make run command include the provided dependencies
run in Compile <<= Defaults.runTask(fullClasspath in Compile, mainClass in (Compile, run), runner in (Compile, run))
// exclude Scala library from assembly
assemblyOption in assembly := (assemblyOption in assembly).value.copy(includeScala = false)
and the console output snippet of $ sbt assembly
vagrant#vagrant-ubuntu-trusty-64:/workspace/flink-wiki-edits$ sbt assembly
[info] Loading project definition from /workspace/flink-wiki-edits/project
[info] Set current project to flink-wiki-edits (in build file:/workspace/flink-wiki-edits/)
[info] Including: flink-connector-wikiedits_2.11-1.1.3.jar
[info] Including: flink-streaming-java_2.11-1.1.3.jar
[info] Including: flink-core-1.1.3.jar
[info] Including: flink-annotations-1.1.3.jar
[info] Including: jsr305-1.3.9.jar
[info] Including: commons-lang3-3.3.2.jar
[info] Including: slf4j-api-1.7.7.jar
[info] Including: slf4j-log4j12-1.7.7.jar
[info] Including: log4j-1.2.17.jar
[info] Including: force-shading-1.1.3.jar
[info] Including: flink-metrics-core-1.1.3.jar
[info] Including: kryo-2.24.0.jar
[info] Including: minlog-1.2.jar
where I see lot of libraries that are part of the
"org.apache.flink" %% "flink-scala" % flinkVersion % "provided",
"org.apache.flink" %% "flink-streaming-scala" % flinkVersion % "provided"
lineage, I assumed that provided will exclude the libraries while assembling the fat-jar, let me know if I have overlooked something.
This is caused by flink-connector-wikiedits library has dependency flink-streaming-java_2.11, see: flink-streaming-java_2.11 pom:
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_2.11</artifactId>
<version>1.1.3</version>
<scope>compile</scope>
</dependency>
and also flink-streaming-java_2.11 has flink-core ... dependency, see:
http://search.maven.org/#artifactdetails%7Corg.apache.flink%7Cflink-streaming-java_2.11%7C1.1.3%7Cjar

How do dependencies work in Scala?

For my existing projects I am migrating from scalaVersion 2.10.5 to 2.11.7 and sbtVersion 1.13.9 also.
Current migrating project is Sales, it have Sales-common, Sales-read, Sales-write modules. It have one dependent project Core. But I don't have Core project code I have only already published artefact jars(I have myapp-core-read_2.10-2.2.33.jar, 2.10 is Scala version).
My project looks like this
Sales
common
build.sbt
read
build.sbt
write
build.sbt
build.sbt
Till now, with scala 2.10.5 everything working fine using in real time also.
After change the version I run sbt clean and sbt update. I am getting Unresolved dependency issue like this:
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: mycompany#myapp-core-read_2.11;2.2.33: not found
[warn] :: mycomapny#myapp-core-write_2.11;2.2.33: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
My Sales buld.sbt is this:
name := "myapp-sales"
organization in ThisBuild := "com.mycompany"
scalaVersion in ThisBuild := "2.11.7"
//crossScalaVersions in Thisq
//Build := List("2.10.5", scalaVersion.value)
//crossPaths := false
scalacOptions in Compile in ThisBuild ++= Seq("-unchecked", "-deprecation", "-encoding", "utf8", "-language:postfixOps", "-language:implicitConVersions")
lazy val common = Project("myapp-sales-common", file("common"))
lazy val read = Project("myapp-sales-read", file("read")).configs(IntegrationTest).settings(Defaults.itSettings: _*).dependsOn(common, write)
lazy val write = Project("myapp-sales-write", file("write")).configs(IntegrationTest).settings(Defaults.itSettings: _*).dependsOn(common)
conflictWarning in ThisBuild := ConflictWarning.disable
parallelExecution in Test in ThisBuild := false
parallelExecution in IntegrationTest in ThisBuild := false
javacOptions in Compile in ThisBuild ++= Seq("-source", "1.6", "-target", "1.6")
//Remove SNAPSHOT check from the release process (for now until Squants gets a release)
releaseProcess := releaseProcess.value.filterNot(_ == ReleaseTransformations.checkSnapshotDependencies)
My read module build.sbt:
libraryDependencies ++= Seq(
"com.mycompany" %% "myapp-core-read" % myappsales.CoreVersion % "compile", // disable using the Scala version in output paths and artifacts,
"com.mycompany" %% "myapp-core-write" % myappsales.CoreVersion % "compile",
"com.mycompany" %% "myapp-registration-common" % myappsales.RegistrationVersion % "compile",
"com.mycompany" %% "myapp-load-common" % myappsales.LoadVersion % "compile",
"com.mycompany" %% "myapp-core-write-test" % myappsales.CoreVersion % "it, test",
"com.mycompany" %% "myapp-core-test" % myappsales.CoreVersion % "it, test"
)
libraryDependencies ++= Seq(
"com.typesafe" % "config" % myappsales.TypeSafeConfigVersion % "compile",
"org.json4s" %% "json4s-native" % Versions.Json4s % "compile",
"io.spray" % "spray-routing" % Versions.Spray % "compile",
"com.typesafe.akka" %% "akka-actor" % Versions.Akka % "compile",
"com.typesafe.akka" %% "akka-remote" % Versions.Akka % "compile"
exclude ("io.netty", "netty")
)
//Assemby settings
test in assembly := {}
assemblyShadeRules in assembly := Seq(
ShadeRule.rename("play.api.libs.iteratee.**" -> "shade.play.api.libs.iteratee.#1")
.inLibrary("play" % "play-iteratees_2.10" % "2.1-RC2")
.inLibrary("org.reactivemongo" % "reactivemongo_2.10" % "0.8.1-SNAPSHOT"),
ShadeRule.rename("scala.concurrent.stm.**" -> "shade.scala.concurrent.stm.#1")
.inLibrary("org.scala-stm" % "scala-stm_2.10.0" % "0.6")
.inLibrary("play" % "play-iteratees_2.10" % "2.1-RC2")
)
assemblyMergeStrategy in assembly := {
case "application.conf" => MergeStrategy.concat
case path => MergeStrategy.defaultMergeStrategy(path)
}
//Make assembly a publishable artifact
artifact in (
Compile, assembly) := {
val art = (artifact in (Compile, assembly)).value
art.copy(`classifier` = Some("assembly"))
}
addArtifact(artifact in (Compile, assembly), assembly)
How can I make it work with existing myapp-core-read_2.10-2.2.33.jar jar?
Important note: Scala 2.10 and 2.11 are not binary compatible so you will have to recompile the modules on which you depend
Answer to question:
This seems to be related to how SBT resolves dependencies. When you declare a dependency like so:
"com.mycompany" %% "myapp-core-read" % myappsales.CoreVersion
The %% part in the declaration means that SBT will automatically append the scala version to the library name, so your dependency becomes
group: com.mycompany
artifactId: myapp-core-read_2.11
version: `your version`
It seems that your myapp-core-read was not compiled with scala 2.11 thus SBT can't find the correct version.
You can avoid this by using % and applying the correct suffix manually, so your dependency would become:
"com.mycompany" % "myapp-core-read_2.10" % myappsales.CoreVersion
Having said that, I think scala 2.10 and 2.11 are not binary compatible so you might have to recompile the myapp-core-read module with 2.11.

Why does an sbt project with ScalaVersion set to a 2.11 load 2.10 as well

Following is the core of the project/build.sbt for a scalatra/spark project :
val ScalaVersion = "2.11.6"
val ScalatraVersion = "2.4.0-RC2-2"
// ivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true)}
lazy val project = Project (
"keywordsservlet",
file("."),
settings = ScalatraPlugin.scalatraSettings ++ scalateSettings ++ Seq(
organization := Organization,
name := Name,
version := Version,
scalaVersion := ScalaVersion,
resolvers += Classpaths.typesafeReleases,
resolvers += "Scalaz Bintray Repo" at "http://dl.bintray.com/scalaz/releases",
libraryDependencies ++= Seq(
// "org.scala-lang" % "scala-reflect" % ScalaVersion,
"org.apache.spark" % "spark-core_2.11" % "1.4.1",
"org.scalatra" %% "scalatra" % ScalatraVersion,
"org.scalatra" %% "scalatra-scalate" % ScalatraVersion,
"org.scalatra" %% "scalatra-specs2" % ScalatraVersion % "test",
"ch.qos.logback" % "logback-classic" % "1.1.2" % "runtime",
"org.eclipse.jetty" % "jetty-webapp" % "9.2.10.v20150310" % "container",
"javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
),
Here is the sbt output: notice it is loading a 2.10 target !
$ sbt
[info] Loading project definition from /shared/keywords/project
[info] Updating {file:/shared/keywords/project/}keywords-build...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /shared/keywords/project/target/scala-2.10/sbt-0.13/classes...
[info] Set current project to KeywordsServlet (in build file:/shared/keywords/)
So what is happening here?
There is a difference between the version of Scala that you are using for your project and the version of Scala that sbt itself uses.
sbt 0.13 can compile 2.9, 2.10 and 2.11 (and 2.12). However, when it compiles your build.sbt or Build.scala files, sbt 0.13 uses Scala 2.10.
Similarly, all of the plugins that sbt uses are compiled with 2.10.
On the other hand, sbt 0.12 used Scala 2.9.

How to declare play json dependency?

My build.sbt file (sbt version is 0.13.8):
lazy val commonSettings = Seq(
version := "1.0.0",
scalaVersion := "2.11.6"
)
resolvers += "Typesafe Repo" at "http://repo.typesafe.com/typesafe/releases/"
lazy val root = (project in file(".")).
settings(commonSettings: _*).
settings(
name := "myapp",
libraryDependencies ++= Seq(
"com.typesafe.play" % "play-json" % "2.3.4",
"org.scalatest" % "scalatest_2.11" % "2.2.4" % "test",
"junit" % "junit" % "4.12" % "test"
)
)
scalacOptions ++= Seq("-unchecked", "-feature", "-deprecation")
I get this error when trying to compile my project:
[trace] Stack trace suppressed: run last *:update for the full output.
[error] (*:update) sbt.ResolveException: unresolved dependency: com.typesafe.play#play-json_2.11;2.3.4: not found
[error] Total time: 0 s, completed Apr 17, 2015 5:59:28 PM
How can I get this play-json library for my scala 2.11.6?
You need to tell sbt which scala version should use.
You can either be explicit:
"com.typesafe.play" % "play-json_2.11" % "2.3.4",
Or use %% (sbt doc) as follows to tell sbt to use scalaVersion :
"com.typesafe.play" %% "play-json" % "2.3.4",
You can see all of com.typesafe.play's play-json versions here. They don't have a 2.3.4 version; try using 2.4.0-M3 instead.
"com.typesafe.play" %% "play-json" % "2.4.0-M3"
Mind the double %% so scalaVersion is used properly to resolve the dependency.