How to create an executable JAR file with `scalac` (and run it with `scala`)

If you’re ever working on a really small Scala project — something that contains only a few source code files — and don’t want to use SBT to create a JAR file, you can do it yourself manually. Let’s look at a quick example. Note that the commands below work on Mac and Linux systems, and should work on Windows with minor changes.

Back to top

Example

Given a file named Hello.scala with these contents:

object Hello extends App {
    println("Hello, world")
}

you can compile that source code file directly to a JAR file like this:

$ scalac Hello.scala -d Hello.jar

That creates Hello.jar, whose contents you can look at like this:

$ jar tvf Hello.jar
    76 Mon Apr 15 18:45:56 MDT 2019 META-INF/MANIFEST.MF
  2554 Mon Apr 15 18:45:56 MDT 2019 Hello$.class
   753 Mon Apr 15 18:45:56 MDT 2019 Hello.class
   751 Mon Apr 15 18:45:56 MDT 2019 Hello$delayedInit$body.class

The META-INF/MANIFEST.MF file contains these contents:

Manifest-Version: 1.0
Scala-Compiler-Version: 2.12.8
Main-Class: Hello

Now you can run/execute the JAR file with the scala command like this:

$ scala Hello.jar

That produces the expected output:

Hello, world

That’s all there is to it. The key to this solution is knowing that the scalac “-d” option can be used to create an executable JAR fie.

Back to top

A more complex example

As a more complicated example I just did a similar thing by creating a one-object application that relies on two JAR files. The commands I used are the same, except for adding in the classpath complexity. Assuming I start with a Scala source code file named Foo.scala and want to create a JAR file named Foo.jar, the scalac command to create the JAR file looks like this:

$ scalac -classpath "sed_2.12-0.1.jar:kaleidoscope_2.12-0.1.0.jar" Foo.scala -d Foo.jar

I can then run the application with the scala command like this:

$ scala -classpath "sed_2.12-0.1.jar:kaleidoscope_2.12-0.1.0.jar:Foo.jar" Foo

I should mention that the Foo.scala file has source code that begins like this:

object Foo extends App ...

It’s not in a package, so I refer to Foo at the end of the scala command (as opposed to something like my.package.Foo).

Back to top

Summary

If you ever need to create a JAR file with scalac and then run that JAR file with scala, I hope these examples are helpful.

Back to top

Add new comment

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.