I am having problems building and running an SBT project.
The "protocol" project is used by several modules, including the "daemon".
The "daemon" project should be packaged as an executable jar.
What is the "right" way of doing this?
Here's my Build.scala:
object MyBuild extends Build {
lazy val buildSettings = Seq(
organization := "com.example",
version := "1.0-SNAPSHOT",
scalaVersion := "2.9.1"
)
lazy val root = Project(
id = "MyProject",
base = file("."),
aggregate = Seq(protocol, daemon)
)
lazy val protocol = Project(
id = "Protocol",
base = file("Protocol")
)
lazy val daemon = Project(
id = "Daemon",
base = file("Daemon"),
dependencies = Seq(protocol)
)
// (plus more projects)
The right way to do this is to use one of the sbt plugins for producing jars. I've tested both one-jar and assembly and both have support for excluding libraries from your jar. You can add the settings to individual projects so that only some of them will produce jars.
I'm personally using assembly, but as this post points out, you will run into problems if you have overlapping filenames.
Edit:
For your example above you'd add the following imports at the top:
import sbtassembly.Plugin._
import AssemblyKeys._
You'd modify the project to look like this:
lazy val daemon = Project(
id = "Daemon",
base = file("Daemon"),
dependencies = Seq(protocol),
settings = assemblySettings
)
Also you need to add the following to your project/plugins.sbt
(for sbt .11):
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.7.3")
resolvers += Resolver.url("sbt-plugin-releases",
new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns)
If you decide to go with Assembly you'll probably need to remove duplicate files. Here's an example of the assembly code for excluding duplicate log4j.properties files in a project named "projectName". This should be added as part of the "settings" sequence for the project. Note that the 2nd collect statement is the base implementation and is required.
excludedFiles in assembly := { (bases: Seq[File]) =>
bases.filterNot(_.getAbsolutePath.contains("projectName")) flatMap { base =>
//Exclude all log4j.properties from other peoples jars
((base * "*").get collect {
case f if f.getName.toLowerCase == "log4j.properties" => f
}) ++
//Exclude the license and manifest from the exploded jars
((base / "META-INF" * "*").get collect {
case f if f.getName.toLowerCase == "license" => f
case f if f.getName.toLowerCase == "manifest.mf" => f
})
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With