How to create the manifest for a Java app
The problem
We have a Java or Scala app that has some dependencies and one entry point.
We would like to:
- have all needed jars in a directory call i.e.
lib
. - be able to start our app by simply executing "java -jar myapp.jar".
Suppose that:
- we have the a multiproject
build.sbt
and - the project
myapp
holds the entry pointmycompany.myapp.MainClass
then this would the our build.sbt
would be something like this:
lazy val myapp = project.settings(Seq(
mainClass in (Compile, packageBin) := Some("mycompany.myapp.MainClass"),
// Remove version from the artifact
artifactName in (Compile, packageBin) := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
"myapp.jar"
},
packageOptions in (Compile, packageBin) +=
Package.ManifestAttributes(java.util.jar.Attributes.Name.CLASS_PATH ->
((dependencyClasspath in Compile).value
.map{_.data.getName}
.filter(!_.startsWith("scala-"))
.mkString(" "))
),
projectDependencies ++= Seq(
"com.somecompany" % "dependency1" % "1.0"
)
): _*)
We are filtering scala-library.jar
as this app is Java-based. SBT always adds scala-library.jar
.
In this way, all the needed classpath is already coded in the MANIFEST.MF
and it's easier to launch our app.
This has been tested with SBT 0.13.7
.
If your use recent versions of Java, another alternative is to use:
java -cp '*' mycompany.myapp.MainClass