Safe-to-Wake Light, Part 4: Clojure on the Pi
January 08, 2020
- In Part 1, we introduced Squishy Kitty and set the stage for this project
- In Part 2, we had some surprise soldering to do
- In Part 3, we did some proctology and confirmed our soldering was good with some ham-fisted Python execution
Now, we want to class it up a bit. Get some Clojure running. Maybe even get Clojure working some lights!
Installing Java
Java doesnât ship by default on Raspbian Lite, so we need to install it. After a couple false starts, I landed on using the Zulu Embedded version of Java, by Azul Systems. Installation was pretty straightforward:
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0x219BD9C9
$ echo 'deb http://repos.azulsystems.com/debian stable main' | sudo tee /etc/apt/sources.list.d/zulu.list > /dev/null
$ sudo apt update
$ sudo apt install zulu-embedded-8
Because of all my false starts, I needed to add Java to my PATH. I added the following lines to my ~/.bashrc
:
export JAVA_HOME=/usr/lib/jvm/zulu-embedded-8-armhf/bin
export PATH=$JAVA_HOME:$PATH
Afterwards, a quick source ~/.bashrc
made Java available from the command line.
$ java -version
openjdk version "1.8.0_152"
OpenJDK Runtime Environment (Zulu Embedded 8.25.0.76-linux-aarch32hf) (build 1.8.0_152-b76)
OpenJDK Client VM (Zulu Embedded 8.25.0.76-linux-aarch32hf) (build 25.152-b76, mixed mode, Evaluation)
Running Clojure on the Pi
Cool, so Java is installed, but can it run Clojure?
To find out, I took the jar file from my solution to Day 04 of the 2019 Advent of Code challenge, because we spent a lot of time optimizing it ( first with reflection, then with reducers, and then we profiled it to make it even faster). We have a good handle on how fast it runs on a 6-core Intel 8700k, it will be interesting to see how it performs on a 1ghz single-threaded $9 computer.
Letâs give it a shot!
pi@raspberrypi:~ $ java -jar advent2019-day04.jar
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
đ€Ł
All right, so maybe programs that do a bunch of number crunching are not the best choice for an embedded computer.
Letâs make something smaller!
Setting up Clojure on the Pi
If weâre going to be working in Clojure on the Pi, we should have a REPL on the Pi, and so we might as well install Leiningen to do all the things for us.
mkdir ~/bin && cd ~/bin
wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
chmod +x ./lein
Then, we need to modify our $PATH
again so it can find lein
.
I edited my .bashrc
file such that my PATH now looked like this:
export PATH=~/bin:$JAVA_HOME:$PATH
Source your .bashrc
file again, and you should be ready for some embedded Clojure development.
Making a Small Program
Letâs scaffold a new project, squishy-kitty
, with the following command:
lein new app squishy-kitty
Once weâve done that, we can take a look to see whatâs inside the default core.clj
file:
(ns squishy-kitty.core
(:gen-class))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!"))
A simple âHello, World!â program. Doesnât get much smaller than this! Letâs compile it:
$ lein uberjar
Fun tip: If youâre stuck waiting a million years to compile Java on a Pi Zero, consider instead compiling the JAR file on your PC and copying it over to the Pi. Java is âcompile once, run anywhere!â
Now that we have a JAR file, letâs try that whole ârunning Clojure on the Piâ thing again.
This time, letâs add the time
prefix to see just how long it takes:
$ time java -jar ./target/uberjar/squishy-kitty-0.1.0-SNAPSHOT-standalone.jar
Hello, World!
real 0m18.293s
user 0m17.655s
sys 0m0.599s
We did it! A Clojure program running on the Pi!
But bleh! 18 Seconds to print Hello World!
Hey, itâs still Clojure on the Pi. The productivity benefits will outweigh the runtime cost in the end.
Next time, weâre going to get Clojure-Python interop working. Stay tuned!