If you want to run/execute a main
method from a jar file you created with Scala and the sbt package
command, this tutorial shows how to do it. To make things a little more complicated, my Scala project depends on three external jar files, and the main
method requires a command-line argument.
Note 1: As I note in the Summary, you’ll probably want to use a tool like sbt-assembly for larger projects.
Note 2: This article was originally written in 2015, and used Scala 2.11. That being said, everything still seems nearly the same in late 2020.
Solution
I’m currently writing a little Scala code to download stock market quotes for my Radio Pi project, and I’m going to deploy the code to a “production” Raspberry Pi server that currently has Java installed on it, but not Scala. (It looks like you can run Scala on an RPI, but for the moment I was curious how to get this working.)
The first step in the solution is to package my Scala project with the SBT package
command. I run the following command from the root directory of my Scala project to do that:
$ sbt package
There’s a bunch of output from that command, but the final file it generates has this name:
target/scala-2.11/stockquotes_2.11-1.0.jar
For the purposes of this article I’ll rename that file to:
stockquotes.jar
This jar file depends on these other jar files, which are in my project’s lib folder:
htmlcleaner.jar lift-json.jar paranamer.jar
The solution to my problem requires that I use the scala-library.jar file as another dependency, so I find it at /Users/al/bin/scala/lib/scala-library.jar, and copy it to my local folder.
Now, if you assume that (a) I have copied all of those jar files to the current directory; (b) the application requires a configuration file be passed to the app on the command line; (c) the package for the application is com.alvinalexander; and (d) the first line of the application looks like this:
object GetStockQuotes extends App {
then the java
command to run my application looks like this:
java -cp \ "htmlcleaner.jar:lift-json.jar:paranamer.jar:scala-library.jar:stockquotes.jar" \ com.alvinalexander.GetStockQuotes$delayedInit$body \ stocks.conf
I put that command in a shell script, and I use the \
characters to spread the full command across multiple lines to make it more readable.
A few “tricks” of this solution are:
- Knowing how to use the
java -cp
approach. - Knowing that you need include the scala-library.jar file.
- Knowing that the
main
method for a Scala object defined with “extends App
” will look like com.alvinalexander.GetStockQuotes$delayedInit$body.
(Note that you should not include “.class” after the $body part of that name. For some reason I kept adding “.class” after it today, and of course it kept failing until I saw what I had done.)
Summary
Note that while this solution works for small projects like this, you’ll probably want to use the SBT-Assembly plugin for larger projects. I wrote about how to do that in Recipe 18.14 of the Scala Cookbook.
In summary, if you wanted to see how to execute the main
method in a Scala jar file with the java
command, where the Scala jar file depends on external dependencies, I hope this example is helpful.
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |