Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Build Status

Aang and Korra

When we hit our lowest point, we are open to the greatest change.

Avatar Aang, Legend of Korra


Add to project.clj dependencies:

[im.chit/korra "0.1.2"]


Korra is a library for introspection of maven packages. The library provides mappings between different representations of the same jvm concept.

  • maven coordinate and the jar file
  • a 'resource' and its related jar and jar entry under a given context
    • the resource can be:
      • a symbol representing a clojure namespace
      • a path to a resource
      • a java class
    • the context can be:
      • the jvm classloader classpath
      • a single jar
      • a list of jars
      • a maven coordinate
      • a list of maven coordinates
      • the entire maven local-repo.


There is a reversible mapping between the maven jar file and the coordinate. We use maven-file and maven-coordinate to transition from one to the other:

(use 'korra.common)

(maven-file '[org.clojure/clojure "1.6.0"])
;; => "/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar"

(maven-coordinate "/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar")
;; => [org.clojure/clojure "1.6.0"]

There is also a mapping between a clojure namespace, a java class and the their location in a jar.

(jar-entry "/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar"
;; => #<JarFileEntry clojure/core.clj>


The main work-horse is for korra is resolve-jar. It resolves a resource and a context. The default context is the current jvm classpath:

(use 'korra.resolve)
(resolve-jar 'clojure.core)
;; => ["/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar" "clojure/core.clj"]

It will resolve classes:

(resolve-jar java.lang.Object)
;;=> ["/Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home/jre/lib/rt.jar" "java/lang/Object.class"]

It will also resolve strings:

(resolve-jar "clojure/core.clj")
;;=> ["/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar" "clojure/core.clj"]

Symbols with the last section capitalized will default to java classes instead of clojure files:

(resolve-jar 'clojure.lang.IProxy)
;;=> ["/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar" "clojure/lang/IProxy.class"]

It will return nil if the resource cannot be found:

(resolve-jar 'does.not.exist)
;; => nil


Apart from searching via the current jvm classpath, other search contexts can be set, the most simple being a string representation of the jar path:

(resolve-jar 'clojure.core "/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar")
;; => ["/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar" "clojure/core.clj"]

If the entry cannot be found, nil will be returned:

(resolve-jar 'clojure.core "/Users/zhengc/.m2/repository/dynapath/dynapath/0.2.0/dynapath-0.2.0.jar")
;; => nil

In addition to the jar, one can use as the contexte a vector of jar-files:

(resolve-jar 'clojure.core ["/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar"])
;; => ["/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar" "clojure/core.clj"]

or a coordinate:

(resolve-jar 'clojure.core '[org.clojure/clojure "1.6.0"])
;; => ["/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar" "clojure/core.clj"]

or a vector of coordinates:

(resolve-jar 'clojure.core '[[org.clojure/clojure "1.6.0"]])
;; => ["/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar" "clojure/core.clj"]

or if you simply just want to explore, the context can be an entire maven local repository:

(resolve-jar 'clojure.core :repository)
;; => ["/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar" "clojure/core.clj"]

Coordinates and Dependencies

Once a mapping between the resource (path, class or namespace) and the actual jar and jar-entry on the file system, other very helpful functions can be built around resolve-jar:

resolve-coordinates works similarly to resolve-jar but will return the actual maven-style coordinates

(resolve-coordinates 'iroh.core)
;; => '[im.chit/iroh "0.1.11"]

(resolve-coordinates 'clojure.core :repository)
;; => '[org.clojure/clojure "1.6.0"]

resolve-with-deps will recursively search all child dependencies until it finds

       '[im.chit/korra "0.1.2"])
;;=> ["/Users/zhengc/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar" "clojure/core.clj"]


korra was extracted out of lein-repack, a leiningen plugin for analysing and repacking a larger project into a number of smaller ones.


Copyright © 2014 Chris Zheng


moved -> ''



No releases published


No packages published