How do I add a jar to SBT's classpath? - scala

I have a Java Play project and I added Snake Yaml to my class path.
libraryDependencies ++= Seq("org.yaml" % "snakeyaml" % "1.16")
This works great, my app can import org.yaml.
However, SBT cannot import org.yaml. It does not have access to libraryDependencies for some reason.
If I add import org.yaml.snakeyaml.Yaml to project/commons.scala, I get an error when I compile with activator compile.
[error] <path to project>/project/commons.scala:2: object yaml is not a member of package org
[error] import org.yaml.snakeyaml.Yaml
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
How do I get make jars accessible within SBT?

Adding a dependency X to the source code of the project is not the same as adding a dependency X to your build code (a dependency to be used inside build.sbt, project/*.scala, etc.)
If that is what you are trying to do then you need to add the library dependency inside your project folder.
For example, just add libraryDependencies ++= Seq("org.yaml" % "snakeyaml" % "1.16") inside project/build.sbt (in contrast to adding in the normal ./build.sbt file).
Minimal project that showcase this
Structure:
.
├── build.sbt
└── project
└── build.sbt
build.sbt
import org.yaml.snakeyaml.Yaml
name := "hello"
project/build.sbt
libraryDependencies ++= Seq("org.yaml" % "snakeyaml" % "1.16")

Related

Scala Play and Multi Project SBT Builds

I created a scala play project like this
activator new foo play-event-sourcing-starter
the project was generated successfully and I can go inside and easily compile and run the app.
However what I want is that I should have a multi project sbt build. I googled and found this https://www.playframework.com/documentation/2.5.x/SBTSubProjects
But this is not the same as what I want because here they have play as the root project. whereas what I want is that I have an empty root project with a build.sbt file and then multiple "peer" projects. One of them is play.
So I changed the steps to
mkdir -p LearnPlay/project
cd LearnPlay
activator new foo play-event-sourcing-starter
Now I went inside foo and moved the build.sbt to the LearnPlay directory. I also moved the build.properties and plugins.sbt files into LearnPlay/project folder.
I edited the build.sbt file so that the root project becomes
lazy val root = (project in file("foo")).enablePlugins(PlayScala)
However now sbt cannot compile the project anymore and it cannot find any of the play framework dependencies.
sbt.ResolveException: unresolved dependency: com.typesafe.play#play-server_2.10;2.5.9: not found
unresolved dependency: com.typesafe.play#play-netty-server_2.10;2.5.9: not found
unresolved dependency: com.typesafe.play#play-logback_2.10;2.5.9: not found
unresolved dependency: com.typesafe.play#play-test_2.10;2.5.9: not found
unresolved dependency: com.typesafe.play#play-omnidoc_2.10;2.5.9: not found
at sbt.IvyActions$.sbt$IvyActions$$resolve(IvyActions.scala:313)
These are the contents of my plugins.sbt file. The resolver is defined correctly so I am not sure why sbt will not be able to find the dependencies after the file was moved from sub-project to root project. it was able to resolve everything when the file was in the project directory of the foo project.
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
// The Play plugin
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.9")
// web plugins
addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.0")
The thing that gave me some ideas what's the problem there is:
unresolved dependency: com.typesafe.play#play-server_2.10;2.5.9: not found
Aren't you surprised, that sbt tries to download the version of play server for Scala 2.10, which doesn't exist for Play 2.5.x, since it's already out of lifecycle.
In my projects this is happening, if I'm not specifying scala version in build.sbt or set it to the 2.10, e.g.
lazy val root = (project in file("foo")).settings(
scalaVersion := "2.10.6",
so, I think you just need to add scalaVersion parameter and set it to something from 2.11.x or 2.12.x

read application.conf from build.sbt

I found a lot of similar questions, but some of them are unanswered and others don't work for me.
My task is to read application.conf from build.sbt, to keep all configuration in a single place. But my build.sbt with code
import com.typesafe.config._
val conf = com.typesafe.config.ConfigFactory.parseFile(new File("conf/application.conf")).resolve()
version := conf.getString("app.version")
don't compile with error
error: object typesafe is not a member of package com
How to fix this problem?
To make this work it is important to know that sbt projects have a recursive structure, so when you run sbt you actually start a project that has as root folder the project folder within your root project.
Given that, to fix your problem you need to add typesafe-config as a library dependency also for you sbt project; in order to do that add a build.sbt in the project folder of your root project and specify the dependency in there as you would normally do (i.e. libraryDependencies += ...).
Use this in your code
import com.typesafe.config.{Config, ConfigFactory}
private val config = ConfigFactory.load()
and in your build.sbt file
libraryDependencies += "com.typesafe" % "config" % "1.3.0"

Play Framework 2.1.1 cannot find play object in multi-project setup Build.scala

I'm trying to use an SBT sub project with the Play Framework and I followed the instructions here.
I created the three directories, one containing the main play stuff, one dir being the sbt sub-project, and the last being the project directory with the Build.scala file.
At first I had problems with unresolved dependencies which was fixed with a build.properties file but now it doesn't want to include the play api when compiling the Build.scala file.
[info] Loading project definition from
/home/caskman/ScalaProjects/CorpusBrowserMultiTest/project
[info] Updating
{file:/home/caskman/ScalaProjects/CorpusBrowserMultiTest/project/}default-20bdad..
[info] Resolving org.scala-sbt#precompiled-2_10_0-m7;0.12.1 ...
[info] Done updating.
[info] Compiling 1 Scala source to
/home/caskman/ScalaProjects/CorpusBrowserMultiTest/project/target/scala-2.9.2/sbt0.12/classes...
[error] /home/caskman/ScalaProjects/CorpusBrowserMultiTest/project/Build.scala:3: not found: object play
[error] import play.Project._
[error] ^
[error] one error found
Here's Build.scala
import sbt._
import Keys._
import play.Project._
object ApplicationBuild extends Build {
val appName = "PlayProject"
val appVersion = "1.0-SNAPSHOT"
val appDependencies = Seq(
// Add your project dependencies here,
jdbc,
anorm
)
val subProject = Project("subProject",file("subProject-dir"))
val main = play.Project(appName, appVersion, appDependencies, path = file("playProject"))
.dependsOn(subProject)
}
Are you sure the Play plugin is correctly loaded ? Without it, the Play library cannot be used in the Build file (or anywhere else).
As explained here, the project/plugins.sbt file must contain the plugin definition.
You can look at these samples to have working examples of this file:
// The Typesafe repository
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
// Use the Play sbt plugin for Play projects
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % Option(System.getProperty("play.version")).getOrElse("2.0"))

sbt direct git source dependency - not fetching transitive library dependencies?

I'm trying out sbt's direct dependsOn feature with a git repository ("project A") hosted at Github. I am using a stable tag reference, and in my test project ("project B"), sbt does clone project A from source and starts compiling. However compilation fails with project A's own dependencies seemingly missing (i.e. it doesn't seem to pick up anything defined in project A's build.sbt).
Is this a different from maven/ivy managed dependencies? Do I need to include all the transitive dependencies in my child project B? Sounds a bit weird to me. That would kind of kill off the whole effort, as I'm having like a dozen libraries on which project A depends.
To illustrate:
Project A (online on Github as source):
// build.sbt:
version := "1.2.3"
libraryDependencies += "org.foo" %% "bar" % "1.0"
Project B (local):
// project/Build.scala
import sbt._
import Keys._
object Build extends sbt.Build {
lazy val projA = RootProject(uri("git://github.com/me/projA.git#v1.2.3"))
lazy val projB = Project(id = "project-B", base = file(".").dependsOn(projA)
}
This goes:
[info] Compiling 678 Scala sources to /Users/me/.sbt/staging/
5666eafa865fdf605be3/target/scala-2.10/classes...
[error] /Users/me/.sbt/staging/5666eafa865fdf605be3/src/main/scala/com/me/
BarKeeper.scala:3: not found: object bar
[error] import org.foo.bar
[error] ^
So do I have to re-declare the library dependency on "org.foo" %% "bar" % "1.0"? I hope not!
This was purely my own fault, not sbt's. I had overseen an unmanaged library (folder lib) in project A. After exchanging it for a Maven managed version (folder lib_managed), project A now correctly compiles from source in the staging for project B.

SBT can't resolve dependency in build definition

I'm making an SBT task that needs to make a multipart POST request to a certain server. I want to use Dispatch to make the request. I have the following in build.sbt at the top level of my project:
libraryDependencies ++= Seq(
"net.databinder.dispatch" %% "dispatch-core" % "0.9.5"
)
The task definition is in project/Build.scala. I have
import sbt._
import Keys._
import dispatch._
object SubmitBuild extends Build {
...
}
I get the following error message:
[error] /Users/ken/xxxxtools/project/Build.scala:3: not found: object dispatch
[error] import dispatch._
[error] ^
If I remove import dispatch._ then sbt will compile. I know I have Dispatch installed. Why can't SBT find it?
If you want to make references in Build.scala to some dependency it has to be declared in build's project not in the "project project". Meaning that it should be project/build.sbt.
It turns out that project/Build.scala is also a SBT project in the same way your project is.
SBT authors give a very good explanation in sbt is recursive.