How to create the manifest for a Java app

Published on:

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 point mycompany.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

Comments

comments powered by Disqus