Adding local JARs to Clojure projects in Leiningen 2

I’ve been working through Amit Rathore’s excellent book Clojure in Action, and was excited to start tinkering with accessing HBase from Clojure. However, I discovered that this was not straightforward.

Amit notes that “you’ll need to have the HBase JAR file on your classpath”. If you’re using Leiningen, it handles downloading your dependencies and adding them to your classpath, which is quite handy. I added the following to the :dependency item in my project definition in project.clj:

[org.apache.hbase/hbase "0.92.0"]

did a lein deps, and thought I’d be on my merry way.

Unfortunately, I promptly ran into a wall: attempts to instantiate the HBaseConfiguration class yielded a “NoClassDefFoundError” for org.apache.hadoop.conf.Configuration. I took a quick look at the JAR that Maven had downloaded for HBase, and sure enough, it didn’t contain that class. I had no problem downloading and running the HBase server, so I took a look through the JARs in the lib/ directory in that, and it turns out that this class is provided by hadoop-core-1.0.0.jar. Apparently the HBase project in Maven Central is missing a dependency.

Leiningen really wants all the JARs that your projects rely on to be managed by Maven; it doesn’t seem that there’s an easy way to just say “include this JAR”. However, it turns out that it’s not terribly difficult to create a local Maven repository. I followed the steps that I found on Paul Gross’s blog, adding -DcreateChecksum=true as suggested in the comments, to create a repository containing hadoop-core-1.0.0.jar, and I was up and running after another lein deps.

Installing a Clojure development environment on Ubuntu

After a not-terribly-thrilling experience upgrading to Ubuntu 11.10 (Oneiric Ocelot) on my laptop, I’ve decided to leave my desktop running Lucid Lynx for a while longer. However, I’d like to do some Clojure development on a nice, big screen, so I needed to figure out how to get a dev environment set up. It looks like this may be easier in later versions of Ubuntu, but here’s the cleanest way I could find to set it up under Lucid.

First, here’s what you’ll need to do as root to get packages installed system-wide:

  1. Install Clojure: apt-get install clojure
  2. Install SLIME.

    If you’re new to Lisp, SLIME is a very powerful Emacs mode for developing Lisp programs. It’s in the APT repositories as well: apt-get install slime

Users will also likely want to be able to easily install clojure-mode, which adds some formatting features and, more importantly, functions for communicating with Clojure processes. To do this, we’ll need to add some package management features to Emacs.

  1. Install package.el.

    Emacs 24 comes with a package management system, package.el, but, sadly, Lucid is only up to Emacs 23. However, there is a version of package.el for Emacs 23 available at http://bit.ly/pkg-el23, which you should download and place into /usr/local/share/emacs/23.1/site-lisp.

  2. Set up the Marmalade repository.

    The default repository used by package.el, ELPA, does not have an up-to-date version of clojure-mode. We want to add the Marmalade repository. To do this for Emacs 23, we will add the following to /etc/emacs23/site-start.el (create it if it does not exist):

    (require 'package)
    (add-to-list 'package-archives
                 '("marmalade" . "http://marmalade-repo.org/packages/"))
    (package-initialize)
    

Finally, we will want to install Leiningen, which, as the README states, is a tool “for automating Clojure projects without setting your hair on fire.” This is very straightforward:

  • Download the zipball for leiningen, and copy bin/lein into /usr/local/bin

That’s all we need to do as root. For each user to set up his instance of Emacs to use clojure-mode, they’ll need to do the following within Emacs:

  1. Update the package list.

    M-x package-refresh-contents

  2. List the available packages

    M-x package-list-packages

  3. Mark clojure-mode for installation.

    Scroll down to clojure-mode and hit ‘i’.

  4. Install the package.

    Hit ‘x’ to execute the installer.

Finally, you’ll want to set up the lein-swank plugin for Leiningen that lets SLIME and clojure-mode talk to Clojure processes.

  1. Bootstrap Leiningen.

    Run lein at your prompt to bootstrap Leiningen, if you haven’t already.

  2. Add the lein-swank plugin to the :user profile.

    Create a ~/.lein/profiles.clj file with the following contents:

    {:user {:plugins [ [lein-swank "1.4.4"] ]}}
    

At this point, you should be good to go. To test your installation:

  1. Create a test “hello” project.

    At your prompt: lein new hello

  2. Change into the new project directory.

    At your prompt: cd hello

  3. Start emacs.
  4. Try to jack in.

    In Emacs: M-x clojure-jack-in

After a moment, you should have a REPL in a new Emacs buffer!

Update: after setting this up on my laptop, which is running 11.10 (Oneiric Ocelot) and looking at the package list for Precise Pangolin, I’m pretty sure that this guide is still valid. While there is a packaged version of Leiningen, it’s older and doesn’t seem to want to play nicely with the current version of clojure-mode.