Play dependencies on a scala project - scala

I am trying to get a play project to have another local scala project as a dependency. I have the local scala project deploying to my local M2 repository with this line in my configuration file.
publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository")))
And I am trying to load the dependency in my play project with this line
val appDependencies = Seq(
"com.experimentalcork" %% "timeywimeyentities" % "0.0.2"
)
val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(
resolvers += "Local Maven Repository" at "file://" + Path.userHome.absolutePath + "/.m2/repository",testOptions in Test := Nil
)
In the logs as I do a 'play compile' it states that it can not find the dependency. It is looking in the place where I specified the dependency would be.
[warn] ==== Local Maven Repository: tried
[warn] file://C:/Users/caelrin/.m2/repository/com/experimentalcork/timeywimeyentities_2.9.1/0.0.2/timeywimeyentities_2.9.1-0.0.2.pom
And when I go to check that directory, I can confirm that the pom and jar files are there. I am completely baffled as to how it could look in the directory that contains the pom and not find it. Has anyone had any experiences with this?

You need a .dependsOn call too, I think.
val timeywimeyentities: Project = Project([Put all of your settings here for the project just like you would a play project])
val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings(
resolvers += "Local Maven Repository" at "file://" + Path.userHome.absolutePath + "/.m2/repository",testOptions in Test := Nil
).dependsOn(timeywimeyentities % "compile->compile")
Adding "compile->compile" makes the main code of your play project rely on the main code of your dependency. If you wanted to make the test code of your play project also depend on it, you could use "compile->test". If you want only the test code of both to see each other, you could use "test->test". You can also chain them together, for example: "compile->compile;test->test". If all you want is "compile->compile", you need not explicitly state it.
See https://github.com/harrah/xsbt/wiki/Getting-Started-Multi-Project for more information.

Related

Setting up Scala project

Is there a standard in place for setting up a Scala project where the build.sbt is contained in a subdirectory?
I've cloned https://github.com/lightbend/cloudflow and opened it in IntelliJ, here is the structure:
Can see core contains build.sbt.
If I open the project core in a new project window then IntelliJ will recognise the Scala project.
How to compile the Scala project core while keeping the other folders available within the IntelliJ window?
EDIT:
If you do want to play around with the project, it should suffice to either import an SBT project and select core as the root. Intellij should also detect the build.sbt if you open core as the root.
Here is the SBT Reference Manual
Traditionally, build.sbt will be at the root of the project.
If you are looking to use their libraries, you should import them in your sbt file, you shouldn't clone the repo unless you intend to modify or fork their repo.
For importing libraries into your project take a look at the Maven Repository for Cloudflow, select the project(s), click on the version you want, and select the SBT tab. Just copy and paste those dependencies into your build.sbt. Once you build the project with SBT, you should have all those packages available to you.
So in [ProjectRoot]/build.sbt something along the lines of
val scalaVersion = "2.13.4"
lazy val root = (project in file("."))
.settings(
name := "Your_Project_Name",
scalaVersion := scalaVersion,
libraryDependencies += "com.lightbend.cloudflow" %% "cloudflow-streamlets" % "2.0.26-RC12",
// Either sequentially
libraryDependencies += "com.lightbend.cloudflow" %% "cloudflow-akka" % "2.0.26-RC12",
// Or as a sequence (note that you can have a trailing comma for these)
libraryDependencies ++= Seq(
"com.lightbend.cloudflow" %% "cloudflow-blueprint" % "2.0.26-RC12",
"com.lightbend.cloudflow" %% "cloudflow-flink" % "2.0.26-RC12", // No next elemenet
)
// Or combo using both like above, just don't forget the commas in between
)

How to a reference the shared source without depending on a project

Say I have a project defined as follows:
val commonSettings = Seq(
name := "project1",
version := "1.0",
scalaVersion := "2.12.8",
unmanagedSourceDirectories in Compile +=
baseDirectory.value / ".." / "shared" / "src" / "main" / "scala"
)
val client = project.in(file("client"))
.settings(commonSettings: _*)
val server = project.in(file("server"))
.settings(commonSettings: _*)
And I have a second project that uses a REST api to communicate with this server. Thus the second project uses code defined in the shared source of the first. The second project cannot depend on the entire project1 as there are incompatibilities between the sbt versions for the two projects.
What do I need to add to my build.sbt and/or change in the first project in order for the second project to reference the shared source?
If project1 and project 2 are finally going to run independently it would be better if you write REST APIs to communicate in between them.
You can write an API in project2 and hit it from project1 to run the shared code of project2.
Otherwise, why not just replicate shared code from project2 to project1 ?
You can try jitpack, add below lines in your build.sbt to enable jitpack resolver and add appropriate dependencies
resolvers += "jitpack" at "https://jitpack.io"
// you can also use specific sha or tag instead of master-SNAPSHOT
libraryDependencies += "org.xyz" %% "project" % "master-SNAPSHOT"

Why does enablePlugins(DockerPlugin) from sbt-docker in Play project give "error: reference to DockerPlugin is ambiguous"?

I am trying to dockerize a play web app and I am using sbt-docker. I get the gollowing error when I execute sbt docker:
error: reference to DockerPlugin is ambiguous;
it is imported twice in the same scope by
import _root_.sbtdocker.DockerPlugin
and import _root_.com.typesafe.sbt.packager.docker.DockerPlugin
enablePlugins(DockerPlugin)
^
[error] Type error in expression
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? q
I get the above error and my build.sbt looks like this:
enablePlugins(DockerPlugin)
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.11.6"
libraryDependencies ++= Seq(
jdbc,
cache,
ws,
specs2 % Test
)
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
// Make docker depend on the package task, which generates a jar file of the application code
docker <<= docker.dependsOn(sbt.Keys.`package`.in(Compile, packageBin))
// Define a Dockerfile
dockerfile in docker := {
val jarFile = artifactPath.in(Compile, packageBin).value
val classpath = (managedClasspath in Compile).value
val mainclass = mainClass.in(Compile, packageBin).value.getOrElse(sys.error("Expected exactly one main class"))
val jarTarget = s"/app/${jarFile.getName}"
// Make a colon separated classpath with the JAR file
val classpathString = classpath.files.map("/app/" + _.getName).mkString(":") + ":" + jarTarget
new Dockerfile {
// Base image
from("java")
// Add all files on the classpath
add(classpath.files, "/app/")
// Add the JAR file
add(jarFile, jarTarget)
// On launch run Java with the classpath and the main class
entryPoint("java", "-cp", classpathString, mainclass)
}
}
My suspicion is that the sbt-native-packager is conflicting with sbt-docker. But I am not importing sbt-native-packager anywhere.
If there's a conflict then use the full name.
enablePlugins(sbtdocker.DockerPlugin)
As the message says "and import _root_.com.typesafe.sbt.packager.docker.DockerPlugin" sbt-native-packager comes with the conflicting DockerPlugin class. But that's what you know already.
The trick is that the Play plugin depends on sbt-native-packager to...ease people's lifes and hence the conflict (sorry, too much help might break people's lifes :)).
A solution is to use fully-qualified plugin class names as #pfn recommended or disablePlugins(SbtNativePackager).
See http://www.scala-sbt.org/sbt-native-packager/topics/play.html.

How to add a github java dependency in sbt config?

I've added this code to my Build.scala.
lazy val root = Project("root", file(".")) dependsOn(jbcrypt)
lazy val jbcrypt = RootProject(uri("https://github.com/jeremyh/jBCrypt.git"))
But sbt fails with the error:
[error] (root/*:update) sbt.ResolveException: unresolved dependency: default#jbcrypt_2.11;0.1-SNAPSHOT: not found
How to tell sbt that it is Java not Scala?
How to reference to a specific branch or tag?
Thank you.
Building a project from source is only possible if the referenced project is a sbt project. sbt doesn't know of all the different build systems out there, so how is it supposed to know how to build a non sbt project?
It is possible to add support for other build systems through a sbt plugin but this may be a lot of work.
Your referenced project is a simple Maven project, which means that you can easily create a sbt project from it. Just fork the repo and create a build.sbt with the following content:
scalaVersion := "2.11.5"
projectDependencies += "junit" % "junit" % "3.8.1" % "test"
publishTo := {
val nexus = "https://oss.sonatype.org/"
if (isSnapshot.value) Some("snapshots" at nexus + "content/repositories/snapshots")
else Some("releases" at nexus + "service/local/staging/deploy/maven2")
}
This is the minimal code that was necessary to get it up and running. sbt seems to require that a publish repo is specified, it also seems to require an explicit Scala version. The dependency is already specified by your linked Maven project.
Of course, you know need to change the URI of RootProject to point to the location of your fork.
To your second question: You can reference a commit/tag/branch by appending it to the URI, separated with a # sign:
uri("git://github.com/your/repo#<commit-hash/tag/branch>")

Adding a managed dependency to Play 2 app

I want to add Jersey-client to my Play 2 app using SBT.
So, I added the dependency into my ApplicationBuild.scala file as follows:
object ApplicationBuild extends Build {
val appName = "wealcome-webapp"
val appVersion = "1.0-SNAPSHOT"
val appDependencies = Seq(
// Add your project dependencies here,
jdbc,
anorm,
"com.sun.jersey" % "jersey-client" % "1.16"
)
val main = play.Project(appName, appVersion, appDependencies).settings(
scalaVersion := "2.10.0"
)
}
So, in command-line I make : play reload update.
Thus, I expect to find Jersey's jars file into play-2.1-RC1/repository/local.
However, I find jars into play-2.1-RC1/repository/cache.
What should I do to make automatically the dependency goes into the local folder in order to expect my app to compile?
Is it normal to find jars file into the cache folder? What is exactly the role of cache?
If you are using an IDE make sure to run play eclipsify or play idea after making changes to your dependencies. Afterwards refreshing the project may be necessary. Then the class paths for the project files will be updated appropriately. Only SBT will be aware of your changes before you do this.