Future-proofing a Scala/SBT project - scala

I am trying to use scala-graph and scala-swing in the same program. I can use the latest graph-core library (1.9.2) alone with the latest version of scala (2.11.6). I can use scala-swing, but when I do that, sbt gives me Scala 2.10.4 rather than 2.11.6.
When I tried to use both libraries, I got errors -- either compilation or runtime errors, depending on how I set up build.sbt. So I tried using an older version of graph-core (1.8.0), which if I understand the library's release history [1] correctly, was designed for Scala 2.10.
Doing that works, although it causes sbt to use scala 2.10.4 instead of 2.11.6. I'm worried because it seems like a fragile arrangement.
Will it keep working? Currently my build.sbt file (below) does not restrict the scalaVersion or the scala-compiler version; it just says which graph and swing libraries to use. I'm afraid that changes to the graph library, or the swing library, or the scala language itself, will break the code.
[The rest of this post describes my OS, installations, and code; you might not need to read it.]
I am using Ubuntu 14.04. I installed scala and sbt using apt-get. swing appears already to be installed on my machine. I did not install the graph library but sbt seems to take care of it.
My only two files are in the same folder: build.sbt and main.scala. The build.sbt looks like this:
lazy val root = (project in file(".")).
settings(
name := "main",
version := "1.0",
libraryDependencies += "org.scala-lang" % "scala-swing" % "2.10.5",
libraryDependencies += "com.assembla.scala-incubator" %% "graph-core" % "1.8.0"
)
main.scala looks like this:
import scalax.collection.Graph // or scalax.collection.mutable.Graph
import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._
import scala.swing._, scala.swing.event._
object App extends SimpleSwingApplication {
def top = new MainFrame {
val g1 = Graph(3~1, 5) // no effect; just tests the constructor
val button = new Button { text = "Click me" }
contents = new BoxPanel(Orientation.Vertical) {
contents += button
border = Swing.EmptyBorder(30, 30, 10, 30)
}
}
}
Thanks.
[1] http://www.scala-graph.org/download/

First, you need to use "org.scala-lang.modules" %% "scala-swing" % "1.0.1" for 2.11.
I'm afraid that changes to the graph library, or the swing library, or the scala language itself, will break the code.
Since you have specific fixed versions of both libraries, release of new versions can't affect it; but I certainly would recommend including scalaVersion anyway. Note in particular that the effect of %% depends on what your scalaVersion is.

Related

Intellij has wrong scala syntax errors

I have this piece of code:
object Application {
def main(args: Array[String]) {
import scala.concurrent.ExecutionContext.Implicits.global
val ws = new NingWSClient(new AsyncHttpClientConfig.Builder().build())
ws.url("https://www.google.com").get() onSuccess {
case resp: WSResponse => {
println("Hello");
}
case _ => {
println("Error");
}
}
}
}
Every dependency is well defined inside the build.sbt like so:
name := "example"
version := "1.0"
scalaVersion := "2.11.4"
libraryDependencies ++= Seq(
"com.typesafe.play" %% "play-ws" % "2.4.0-M2",
"com.typesafe.play" %% "play-json" % "2.4.0-M2"
)
But Intellij looks like this when viewing my project:
Could somebody tell me what I'm doing wrong because I'm clueless and this is really annoying because my imports are constantly being removed by Intellij.
This looks like an IntelliJ (or Scala plugin) bug. Sometimes scala namespace does not seem to be handled well - I have seen it with my projects as well since I gave upgraded to version 14. Sometimes it helps to use File / Invalidate Caches/Restart.
Sometimes even adding / removing Scala SDK and invalidating caches does not help. In such case installing scalap.jar from issue SCL-8025 Standard scala library unrecognized on sbt project creation on 2.11.4 might help (the scala plugin location was %userprofile%\.IntelliJIdea14\config\plugins\Scala\lib on my computer).
Another issue SCL-7900
Scala import/auto-complete problem seems to suggest the problem shows when Idea uses JRE from Java 8 - uninstalling 1.8 JDK or setting a IDEA_JDK_64 variable to point to jdk7-64bit files is also supposed to fix the issue.

How to add ScalaScriptEngine library in IntelliJ Idea

I have created a libs folder and placed scalascriptengine-1.3.9-2.11.0.jar in there. After that, I right-clicked on the .jar and selected Add Library.
Then, I created Test.scala:
import java.io.File
import com.googlecode.scalascriptengine.ScalaScriptEngine
object Test {
def main(args: Array[String]): Unit = {
val sourceDir = new File("examples/folder")
val sse = ScalaScriptEngine.onChangeRefresh(sourceDir)
}
}
It correctly recognized ScalaScriptEngine, or at least it did not give any warnings or errors. But it did not compile.
According to the library page I edited my build.sbt:
name := "ScalaScriptEngineTest"
version := "1.0"
libraryDependencies += "com.googlecode.scalascriptengine" %% "scalascriptengine" % "1.3.10"
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.11.1"
But upon refreshing, I get this: http://pastebin.com/GdirttUJ
What am I missing? I am learning scala and it is the first time I am trying to add a library to IntelliJ Idea...
Short answer:
Change the two dependency entries in your build.sbt as follows:
libraryDependencies +=
"com.googlecode.scalascriptengine" % "scalascriptengine" % "1.3.9-2.10.3"
libraryDependencies += "org.scala-lang" % "scala-compiler" % "2.10.4"
Notice I didn't just change the versions -- I replaced your %% with a single %.
This results in you using a slightly older version of ScalaScriptEngine, and I don't know if that will cause any problems for you.
If you're using sbt build dependencies you don't need to be manually placing jars anywhere.
Explanation:
From your log I see that sbt is looking for the ScalaScriptEngine for Scala 2.10. In fact, it's pretty clear that you're running Scala 2.10.4, even though your sbt file expresses a dependency on the 2.11 compiler, which in fact is consistent with the instructions for using ScalaScriptEngine.
On line 23 of the log you can see exactly where it's looking. If you point your browser part way down that path you'll see that there is a version for Scala 2.11 and another directory, scalascriptengine, without a version qualifier. If you dive down the latter, you'll see it's where they keep all the old versions. There isn't a ScalaScriptEngine 1.3.10 (the one you asked for) compiled for Scala 2.10, so your options seem to be to upgrade to Scala 2.11 (which I don't think currently works if you want to use IntelliJ Idea's tight integration with sbt), or you can use ScalaScriptEngine 1.3.9.
You have basically the same problem with your Scala compiler dependency -- it needs the be the Scala version you're using.
I've confirmed the above solution with Scala 2.10.4. I'm playing it a little fast and loose because there isn't a pre compiled version for 2.10.4, and I gambled that the 2.10.3 build will probably work.
Alternatives:
There may be a cleaner way to solve this, but the way the repository is organized makes me doubt it.
You could build the version of your choice with the compiler of your choice, or persuade the ScalaScriptEngine community to do it for you and put it in The Central Repository, but my guess is that 1.3.10 won't build with anything lower than Scala 2.11.
Finally, if you do want to download jars by hand, you may want to read the "Unmanaged dependencies" section of the sbt documentation. Actually, if you're going to use sbt, just read the whole thing a few times.

What version manager should I use to manage multiple Scala versions?

I come from a background in Ruby, and I use RVM to manage multiple Ruby and gemsets. I have googled around, and I found these two SVM and PVM, not sure what should I use?
Anyone can recommend what should I use to manage multiple scala?
PVM Play Version Manager https://github.com/kaiinkinen/pvm
SVM Scala Version Manager https://github.com/yuroyoro/svm
You don't need a version manager. You need a build tool.
Scala projects work differently than Ruby projects. If you use SBT as a build tool, you specify the Scala version in your build file:
//build.sbt
scalaVersion := "2.11.0" // or some other version
SBT then proceeds to download the specified Scala version for you if it hasn't been downloaded before, and builds and runs your project with this version. If you want, you can even specify which version of SBT you want, and it'll arrange everything for you as well.
This is because Scala, contrary to Ruby, is a compiled language - it must be compiled/built before running. Ruby projects don't have a build process, and can be (attempted to) run on any Ruby version. Scala projects might not build on incompatible versions, let alone run, so you need to specify which Scala version your project is supposed to be built against.
There's also no such thing as gemsets for Scala. For Ruby, gems were originally system-wide libraries and executables, shared by all Ruby scripts on the system. Therefore, gems override each other and you need to maintain gemsets with the specific versions you require for each project. In Scala, a dependency is just a library specifically for your project. They don't override each other, and you just specify which version you need in your build file. SBT then automatically downloads it for you when you build.
This just works:
// myproject1/build.sbt
scalaVersion := "2.10.2"
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.2.0"
// myproject2/build.sbt
scalaVersion := "2.11.0"
libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.3.3"

How to get sbteclipse working with Scala 2.9

I am playing with the spray template project and Scala 2.9.0.1.
I want to work with Eclipse and so I've added the following lines to the build.sbt file
of the spray template project.
resolvers += {
val typesafeRepoUrl = new java.net.URL("http://repo.typesafe.com/typesafe/releases")
val pattern = Patterns(false, " [organisation]/[module]/[sbtversion]/[revision]/[type]s/[module](-[classifier])-[revision]. [ext]")
Resolver.url("Typesafe Repository", typesafeRepoUrl)(pattern)
}
libraryDependencies <<= (libraryDependencies, sbtVersion) { (deps, version) =>
deps :+ ("com.typesafe.sbteclipse" %% "sbteclipse" % "1.3-RC2" extra("sbtversion" -> version))
}
I always get this error:
com.typesafe.sbteclipse#sbteclipse_2.9.0-1;1.3-RC2: not found
Of course the directory at the typesafe server does not exist. There is only:
http://repo.typesafe.com/typesafe/releases/com.typesafe.sbteclipse/sbteclipse_2.8.1/
but sbt is trying to get:
http://repo.typesafe.com/typesafe/releases/com.typesafe.sbteclipse/sbteclipse_2.9.0-1/0.10.1/1.3-RC2/jars/sbteclipse_2.9.0-1-1.3-RC2.jar
I figured out that 2.8.1 is the scala version sbt uses internaly. But my
sbt version (0.10) uses the scala version set in the build.sbt (scalaVersion := "2.9.0-1") to build the url to download sbteclipse.
Does anyone know how to set this up correctly? How do I tell the build.sbt file that I want to use Scala 2.9 but to look for the sbteclipse plugin at the correct URL?
Are there any plans to include something like sbteclipse to the sbt standard distribution? That would be more than welcome and probably help a lot of beginners with Scala, sbt and Eclipse.
Claus
try some thing like "com.typesafe.sbteclipse" % "sbteclipse_2.8.1" % "1.3-RC2....."
using "%%" will automicly add scala version to the library name. using "%" will not.
There is also a shorter way to get sbteclipse into use. Create a file ~/.sbt/plugins/plugins.sbt with this content:
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")

sbt: can i put the source of scala compiler plugin into a project that needs to be compiled using that plugin?

i'm writing my own scala compiler plugin and using sbt to build the project. is it possible to put the source of that plugin in the same project that needs to be compiled using that plugin?
all the documentation on sbt seems to be concerned with using a plugin that's external to the project. it just seems much easier to test the plugin if they're in the same project. otherwise i have to continuously build the plugin, copy that jar over to the main project, and then compile that.
the documentation i read is at http://code.google.com/p/simple-build-tool/wiki/CompilerPlugins.
Here is an example using SBT 0.13:
object PluginBuild extends Build {
def buildSettings = Seq(
name := "test-compiler-plugin",
scalaVersion := "2.10.3"
)
override def settings = super.settings ++ buildSettings
lazy val codeToBeChecked = project.in(file("code-to-be-checked")).
settings(
scalacOptions += "-Xplugin:" + packageBin.in(Compile).in(thePlugin).value
)
lazy val thePlugin = project.in(file("the-plugin")).settings(
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value
)
}
I am not shure about what you are doing, but maybe is the project/plugins/src_managed/ diriectory what you are looking for. If the user of the plugin needs some code from the plugin, it can be found there.