For a recent project, I wanted to verify the correctness of a distributed queue implementation based on Amazon SQS. For this, I turned to the Jepsen library for verifying distributed systems. Jepsen is written in Clojure and the first task was to get Jepsen to compile with a Java library hosted on our internal Maven repository. I googled for a while, asked around, and assembled instructions from a few different places. Here then, is a single blog post summarizing the solution for future use.
The key to getting this to work is to add a few directives to your Leiningen project configuration. Particularly,
Add your private repository to the :repository directive
Leiningen needs to know the location of any private Maven repositories
that host your source code. This is done through the :repository
directive.
;; These repositories will be searched for :dependencies and
;; :plugins and will also be available to deploy to.
:repositories [["your-private-maven-repository" {:url "http://..."}]]
If you require authorization for your repository, you can add your
credentials to your leiningen profile. Within the :auth
section, you do
not need to specify http://
before the repository URL.
$ cat ~/.lein/profiles.clj
{:auth {:repository-auth {#"your-private-maven-repository-endpoint"
{:username "<your username>"
:password "<your password>"}}}}
Add Java library dependencies
Java library dependencies are added exactly the same as Clojure
dependencies. However you must explicitly list the groupId
and
artifactId
for Maven hosted artifacts:
:dependencies [[org.clojure/clojure "1.8.0"]
[org.apache.thrift/libthrift "0.9.3"]
[jepsen "0.1.4"]])
Add Java code called by Clojure
Java code called by Clojure must be compiled and made available to the
Clojure compiler. Leiningen does this for us through the
:java-source-paths
directive. Specify any Java code here:
;;; Filesystem Paths
;; If you'd rather use a different directory structure, you can set these.
;; Paths that contain "inputs" are string vectors, "outputs" are strings.
:java-source-paths ["src/main/java"] ; Java source is stored separately.
A Minimal Sample Configuration
Putting this all together, the following project configuration is used to add Java library code from a private Maven repository and local Java source code to a Leiningen project:
(defproject my-project "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:main jepsen.my-project
:repositories [["my-private-maven-repository" {:url "http://my-private-maven-endpoint"}]]
:java-source-paths ["src/main/java"]
:dependencies [[org.clojure/clojure "1.8.0"]
[<my-private-group-id>/<my-private-artifact-id> "2.4.0"]
[jepsen "0.1.4"]])