Building Clojure Libraries for use in Storm

Storm

Here's a little gem that I figured out while trying to deliver a nice clojure library for some storm work that I've been doing. The problem is that when you build an uberjar for a topology (or library) with leiningen, you don't want to include the storm jars as that will mess up the storm cluster when you go to deploy the topology. So how to get it to all work locally, but when building the uberjar, it goes smoothly.

Sadly, this is not clearly documented anywhere that I could find. But there were bits and pieces here and there and I was able to figure out what I needed with a little trial-and-error.

Thankfully, it's all in the leiningen project.clj file:

  (defproject having-fun "1.0.0"
    :aot [project.core]
    :profiles {:provided {:dependencies [[storm "0.9.0-wip16"]]}}
    :repositories [["releases" {:url "http://nexus/content/repositories/releases/"
                                :sign-releases false}]]
    :main project.core)

Where the keys seem to be that with leiningen 2, you need to accept that the :aot tag needs to be at the top level, and not buried in a :profiles entry. This seems to be a change going forward, so I wanted to adopt it now, and it works better this way.

Additionally, the :profiles line is all about excluding the storm jars in the uberjar, which is just what I needed, and then the :repositories tag is all about where to deploy this to with a simple:

  $ lein deploy

With this, I've been able to build clojure libraries with defbolt and defspout constructs - which is exactly what I wanted to do, and then put this up on our local nexus server so that it's very easy for others in the group to put this library in their project.clj file and make use of it.

Sweet.