This article shows how to install and use Scala programming language on Raspberry Pi.

Traditionally, the programming language of choice for Raspberry Pi was Python, while JVM-based languages were set aside. That was reasonable, because JVM platform is rather resource-intensive, especially in interpreted mode, and the first version of Raspberry Pi was hardly apt for such a task.

However, things have changed: on the one hand, Raspberry Pi 2 now offers a 900MHz quad-core CPU and 1GB of RAM, on the other hand, Oracle released JDK 8 for ARM (with HardFP, JIT and server VM), which provides >10X performance boost (comparing to Zero VM from OpenJDK), so Scala runs nicely even on Raspberry Pi 1 (and, RPi 2 can run IntelliJ IDEA, if you wish).

Contents:

Some of the commands will require root privileges, so either login as root user or use sudo to start an interactive shell via sudo -i .



Installing Java

Because Scala compiles to Java bytecode, we need to install Java virtual machine (JVM) first.

Some Linux distributives come with JVM pre-installed, however that JVM is usually provided by OpenJDK package. While I really appreciate that open-source implementation of the Java Platform, it currently offers no just-in-time compiler on ARM systems (like Raspberry Pi), so it’s too slow for our purpose.

Linux distributives often provide dedicated utilities (e. g. in Debian, in Arch Linux, etc.) to switch Java implementations, yet we’ll not rely on them and will use plain and simple approach (which is also distributive agnostic).

We can determine installed Java version by running:

java -version

If the output is “command not found” than there’s no Java installed (preferable). If the output contains “Zero VM” or “interpreted mode”, it’s better to use package manager to remove all existing Java packages (*jdk, *jre) from the system before proceeding.

First, we need to obtain JDK 8 for ARM from Oracle’s site. Open the page in a browser, accept the license and download the distributive.

Then upload the file to your Raspberry Pi via SSH (use appropriate version / host / user parts):

scp jdk-8u33-linux-arm-vfp-hflt.tar.gz user@address:/home/user

On Windows, it’s possible to use pscp from Putty for that purpose. Alternatively, you may simply copy the file to the boot partition on the SD card (which uses Windows-friendly, FAT file system) and then access the file via /boot/... path.

Create a directory to hold the JVM:

mkdir /usr/lib/jvm

Unpack the distributive:

tar -xf jdk-8u33-linux-arm-vfp-hflt.tar.gz -C /usr/lib/jvm

Rename the resulting directory:

mv /usr/lib/jvm/jdk1.8.0_33 /usr/lib/jvm/java-8-oracle

Delete the original archive file:

rm jdk-8u33-linux-arm-vfp-hflt.tar.gz

Create symbolic links to binaries:

ln -s /usr/lib/jvm/java-8-oracle/bin/java /bin/java ln -s /usr/lib/jvm/java-8-oracle/bin/javac /bin/javac

Run java -version again, the output should be like:

java version "1.8.0_33" Java(TM) SE Runtime Environment (build 1.8.0_33-b05) Java HotSpot(TM) Client VM (build 25.33-b05, mixed mode)

This confirms that the required version of Java is correctly installed.

Installing Scala

It’s possible to download Scala distributive directly to Raspberry Pi (consider using the latest version):

wget https://downloads.typesafe.com/scala/2.11.6/scala-2.11.6.tgz

After downloading, unpack and then delete the resulting file:

mkdir /usr/lib/scala tar -xf scala-2.11.6.tgz -C /usr/lib/scala rm scala-2.11.6.tgz

Create symbolic links:

ln -s /usr/lib/scala/scala-2.11.6/bin/scala /bin/scala ln -s /usr/lib/scala/scala-2.11.6/bin/scalac /bin/scalac

Run scala -version to verify the installation. The output should be:

Scala code runner version 2.11.6 -- Copyright 2002-2013, LAMP/EPFL

If output is OK, than everything is ready to compile and run Scala code.

Using Scala

There are multiple ways of how we can run Scala code. Let’s enumerate most common ones.

Interpreter

Scala offers an interactive interpreter (often called a REPL for Read-Evaluate-Print Loop), which can be started by simply typing scala at the command line:

Welcome to Scala version 2.11.6. Type in expressions to have them evaluated. Type :help for more information.

Here’s how we can interactively define an infinite stream of Fibonacci numbers and then compute first 10 of them:

scala> val fs: Stream[Int] = 0 #:: fs.scanLeft(1)(_ + _) fs: Stream[Int] = Stream(0, ?) scala> fs.take(10).mkString(", ") res0: String = 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

Type :q to exit the interpreter.

If you want to see more cool one-liners that can easily fit into the REPL, you may check Scala for Project Euler article.

Scala scripts

Scala allows to omit all the boilerplate code (like enclosing classes or “main” methods) in scripts and to run those files directly, without explicit compilation.

Create a new Scala file:

nano ls.scala

Enter the following code and then save the file:

new java.io.File(".").listFiles.foreach(println)

Run the resulting script via:

scala ls.scala

Shell scripts

It’s possible to use Scala from shell scripts. All we need to do is to specify scala as a desired interpreter in a script header. Arguments are accessible via args value.

Create cat.sh file with the following content:

#!/bin/sh exec scala "$0" "$@" !# print(io.Source.fromFile(args(0)).mkString)

Mark the file as executable:

chmod +x cat.sh

Then run this file just like any other shell script:

./cat.sh /etc/fstab

Compiler

While, scripts can be handy, Scala can be explicitly compiled to Java bytecode to avoid subsequent re-compilations and improve startup performance.

Scala works like Java in this respect, just use scalac instead of javac for compilation, and scala instead of java to run the resulting bytecode. Many of the command line options are also rather similar.

Let’s compile the snippet from the REPL example to bytecode.

Create Main.scala file with the flowing lines:

object Main extends App { lazy val fs: Stream[Int] = 0 #:: fs.scanLeft(1)(_ + _) println(fs.take(10).mkString(", ")) }

Invoke Scala compiler:

scalac Main.scala

Run the resulting Main.class file:

scala Main

Notice, that this time the result appears much faster, because code is pre-compiled beforehand. We use scala to run the class just for simplicity (to add standard Scala library to class path). In principle, the produced class file can be run via java command as well.

Just like javac , Scala compiler will compile all the specified files each time you run it, which may be not desirable for large code bases. That is where incremental compilation via SBT comes in handy.

Installing SBT

SBT is a build tool that (besides defining a project model) handles incremental compilation of Scala and Java files, and can be used as a compile server for continuous compilation.

Download sbt-launch.jar file:

wget https://repo.typesafe.com/typesafe/ivy-releases\ /org.scala-sbt/sbt-launch/0.13.8/sbt-launch.jar

Place it withing the system:

mkdir /usr/lib/sbt mv sbt-launch.jar /usr/lib/sbt

Create a shell script to run the SBT launcher:

nano /bin/sbt

Add the following lines and save the file:

#!/bin/sh java -server -Xmx512M -jar /usr/lib/sbt/sbt-launch.jar "$@"

We’re using -server switch here, which can slower JVM startup, yet can significantly improve performance once JVM is “warmed up”. Note that server VM requires arm7 architecture, so this switch can be applied only on Raspberry Pi 2.

Mark the script as executable:

chmod +x /bin/sbt

Verify installation by querying SBT version:

sbt --version

The output should looks like:

sbt launcher version 0.13.8

SBT relies on file modification timestamps for incremental compilation, yet Raspberry Pi boards have no real time clock (so they reset OS time on boot). Most Linux distributives rely on NTP to synchronize clock over the Internet. Make sure that the synchronization works properly by issuing date command.

Using SBT

Run SBT interactive shell (it will take some time to download required dependencies):

sbt

Then you can invoke compile command from the SBT command line. Type exit to exit the tool.

You can also start compilation directly from command line:

sbt compile

SBT employs comprehensive analysis to recompile only those files which really should to be recompiled. That can significantly speed up subsequent compilations of large projects.

To speed up compilation even further, it’s possible to avoid multiple JVM and SBT startups by keeping a running SBT process for automatic, continuous compilation.

Here’s how we can run SBT compilation loop in the background:

sbt "~ compile" &

In this way SBT will monitor file changes and automatically recompile files almost instantaneously.

Use standard management command like fg , bg , jobs , etc. to interact with the launched process. Alternatively, you may run the compilation loop within GNU screen, or simply from another shell session.

While Scala runs fine on Raspberry Pi out-the-box, I recommend you to check related Raspberry Pi tweaks which can help to improve performance even further.

See also: Install IntelliJ IDEA on Raspberry Pi, Scala for Project Euler

* Raspberry Pi is a trademark of the Raspberry Pi Foundation

Tags: arm, compile, install, java, jvm, raspberry pi, repl, sbt, scala, scalac, script