Exclude dependencies from uberjar in leiningen 2

A question from Warren in the Clojure mailing list:

“As titled, I need to exclude certain dependencies from my final .jar file (because those dependencies will already be there in the final target Java environment). How can I do that? Thank you.

PS: I am using Leinengen 2″

I knew it’s feasible, but have never done it before. It turned out quite easy.

Firstly, create a demo project, say uberjar-excludes-demo.

jacek:~/sandbox
$ lein2 new uberjar-excludes-demo
Generating a project called uberjar-excludes-demo based on the 'default' template.
jacek:~/sandbox
$ cd uberjar-excludes-demo

Once created, import it to Eclipse IDE with Counterclockwise plugin installed – use Import, and then Configure > Convert to Leiningen Project.

Change the project.clj so that it contains the profiles section with dev profile. The profiles dev, user and default are enabled by default in leiningen 2.

(defproject uberjar-excludes-demo "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.4.0"]]
  :profiles {:dev {:dependencies [[ring/ring-jetty-adapter "1.1.0"]]}})

The dev profile adds ring/ring-jetty-adapter to the dependencies of the project. lein2 uberjar excludes dev, user and default profiles while processing the dependencies for inclusion (it does the opposite to the other tasks of lein2).

Let’s see whether the dependency gets included in the uberjar.

jacek:~/sandbox/uberjar-excludes-demo
$ lein2 uberjar
Including uberjar-excludes-demo-0.1.0-SNAPSHOT.jar
Including clojure-1.4.0.jar
Created /Users/jacek/sandbox/uberjar-excludes-demo/target/uberjar-excludes-demo-0.1.0-SNAPSHOT-standalone.jar

jacek:~/sandbox/uberjar-excludes-demo
$ lein2 with-profile dev uberjar
Performing task 'uberjar' with profile(s): 'dev'
Created /Users/jacek/sandbox/uberjar-excludes-demo/target/uberjar-excludes-demo-0.1.0-SNAPSHOT.jar
Including uberjar-excludes-demo-0.1.0-SNAPSHOT.jar
Including clojure-1.4.0.jar
Created /Users/jacek/sandbox/uberjar-excludes-demo/target/uberjar-excludes-demo-0.1.0-SNAPSHOT-standalone.jar

It was not, even when lein2 uberjar was executed with the profile dev explicitly.

Let’s create another profile, say demo.

(defproject uberjar-excludes-demo "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.4.0"]]
  :profiles {:dev {:dependencies [[ring/ring-jetty-adapter "1.1.0"]]}
             :demo {:dependencies [[ring/ring-jetty-adapter "1.1.0"]]}})

Now, when you run lein2 uberjar with the profile demo, the dependency (and its transitive dependencies) will indeed be included.

jacek:~/sandbox/uberjar-excludes-demo
$ lein2 with-profile demo uberjar
Performing task 'uberjar' with profile(s): 'demo'
Created /Users/jacek/sandbox/uberjar-excludes-demo/target/uberjar-excludes-demo-0.1.0-SNAPSHOT.jar
Including uberjar-excludes-demo-0.1.0-SNAPSHOT.jar
Including servlet-api-2.5.jar
Including javax.servlet-2.5.0.v201103041518.jar
Including ring-core-1.1.0.jar
Including ring-jetty-adapter-1.1.0.jar
Including commons-io-2.1.jar
Including clj-time-0.3.7.jar
Including clojure-1.4.0.jar
Including jetty-http-7.6.1.v20120215.jar
Including jetty-util-7.6.1.v20120215.jar
Including commons-codec-1.6.jar
Including joda-time-2.0.jar
Including jetty-server-7.6.1.v20120215.jar
Including jetty-io-7.6.1.v20120215.jar
Including ring-servlet-1.1.0.jar
Including commons-fileupload-1.2.1.jar
Including jetty-continuation-7.6.1.v20120215.jar
Created /Users/jacek/sandbox/uberjar-excludes-demo/target/uberjar-excludes-demo-0.1.0-SNAPSHOT-standalone.jar

Try to guess what happens when you run the above command with no profiles given.

There’s a follow-up question about AOT’ing the project before it’s uberjar’ed, but I haven’t got my head around it to propose a solution. Phil mentioned to develop a plugin for it, but I guess :uberjar-exclusions could do the trick.

Be Sociable, Share!
This entry was posted in Languages, Tools.

Leave a Reply

%d bloggers like this: