Wednesday, October 12, 2011

dj supports lazy classpath and dependency resolution

Imagine you've been developing code and have all these data structures in memory. You want to visualize them but didn't add incanter as part of a dependency. Now its not a problem since we can set both classpath and obtain dependencies lazily.

We can create a repl anytime and anywhere using:


$ dj repl
Clojure 1.3.0
;user=>


Let's add a simple hello.clj file:


$ echo '(println "hello world")' > hello.clj


Let's add the classpath to the current directory and see if we can require it:


;user=> (dj.classloader/add-to-classpath! "/home/user/")
#
;user=> (require '[hello])
hello world
nil


Let's load some dependencies, how about incanter?:


;user=> (dj.classloader/add-dependencies! '[[incanter/incanter "1.3.0-SNAPSHOT"]])
resolving #dj.deps.maven.maven-dependency{:name incanter, :version 1.3.0-SNAPSHOT, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name incanter-core, :version 1.3.0-SNAPSHOT, :group incanter}
excluding #dj.deps.maven.maven-dependency{:name clojure, :version 1.3.0, :group org.clojure}
resolving #dj.deps.maven.maven-dependency{:name math.combinatorics, :version 0.0.1, :group org.clojure}
resolving #dj.deps.maven.maven-dependency{:name parallelcolt, :version 0.9.4, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name netlib-java, :version 0.9.4, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name arpack-combo, :version 0.9.4, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name csparsej, :version 0.9.4, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name jplasma, :version 0.9.4, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name jtransforms, :version 0.9.4, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name optimization, :version 0.9.4, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name incanter-io, :version 1.3.0-SNAPSHOT, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name opencsv, :version 2.0.1, :group net.sf.opencsv}
resolving #dj.deps.maven.maven-dependency{:name clojure-json, :version 1.1-SNAPSHOT, :group org.danlarkin}
excluding #dj.deps.maven.maven-dependency{:name clojure, :version 1.2.0-master-SNAPSHOT, :group org.clojure}
resolving #dj.deps.maven.maven-dependency{:name incanter-charts, :version 1.3.0-SNAPSHOT, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name jfreechart, :version 1.0.13-no-gnujaxp, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name jcommon, :version 1.0.16, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name incanter-processing, :version 1.3.0-SNAPSHOT, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name processing-core, :version 1.1, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name incanter-mongodb, :version 1.3.0-SNAPSHOT, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name congomongo, :version 0.1.7-SNAPSHOT, :group congomongo}
excluding #dj.deps.maven.maven-dependency{:name clojure, :version 1.2.1, :group org.clojure}
resolving #dj.deps.maven.maven-dependency{:name core.incubator, :version 0.1.0, :group org.clojure}
resolving #dj.deps.maven.maven-dependency{:name data.json, :version 0.1.1, :group org.clojure}
resolving #dj.deps.maven.maven-dependency{:name mongo-java-driver, :version 2.6.5, :group org.mongodb}
resolving #dj.deps.maven.maven-dependency{:name incanter-pdf, :version 1.3.0-SNAPSHOT, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name itext, :version 1.4, :group com.lowagie}
resolving #dj.deps.maven.maven-dependency{:name incanter-latex, :version 1.3.0-SNAPSHOT, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name jlatexmath, :version 0.9.1-SNAPSHOT, :group net.sf.alxa}
resolving #dj.deps.maven.maven-dependency{:name incanter-excel, :version 1.3.0-SNAPSHOT, :group incanter}
resolving #dj.deps.maven.maven-dependency{:name poi, :version 3.6, :group org.apache.poi}
resolving #dj.deps.maven.maven-dependency{:name poi-ooxml, :version 3.6, :group org.apache.poi}
resolving #dj.deps.maven.maven-dependency{:name poi-ooxml-schemas, :version 3.6, :group org.apache.poi}
resolving #dj.deps.maven.maven-dependency{:name xmlbeans, :version 2.3.0, :group org.apache.xmlbeans}
resolving #dj.deps.maven.maven-dependency{:name stax-api, :version 1.0.1, :group stax}
resolving #dj.deps.maven.maven-dependency{:name geronimo-stax-api_1.0_spec, :version 1.0, :group org.apache.geronimo.specs}
resolving #dj.deps.maven.maven-dependency{:name dom4j, :version 1.6.1, :group dom4j}
resolving #dj.deps.maven.maven-dependency{:name xml-apis, :version 1.0.b2, :group xml-apis}
resolving #dj.deps.maven.maven-dependency{:name swingrepl, :version 1.3.0, :group swingrepl}
excluding #dj.deps.maven.maven-dependency{:name clojure, :version 1.3.0-alpha2, :group org.clojure}
resolving #dj.deps.maven.maven-dependency{:name jline, :version 0.9.94, :group jline}
nil
;user=> (require '[incanter.core])
nil


Don't forget that the input is a vector of dependencies, not just a single dependency.

In conclusion, this enables us to develop anywhere (directory) and anytime (during development after the repl started). This is very powerful.