3

Is it possible to add new stuff to the classpath (e.g. editing project.clj and running lein deps) and then importing it to an existing Clojure session?

This is, without having to disconnect and then connect again.

deprecated
  • 5,142
  • 3
  • 41
  • 62

2 Answers2

5

You can use pomegranate to download new libraries and add them to your classpath at runtime. It won't read directly from your project.clj, but does use a compatible syntax (using the Aether library which Leiningen 2 uses for its own dependency resolution).

Usage looks like so (quoting the README's example):

=> (add-dependencies
      :coordinates '[[incanter "1.2.3"]]
      :repositories (merge cemerick.pomegranate.aether/maven-central
                           {"clojars" "http://clojars.org/repo"}))

That said, you do have to have pomegranate itself in your initial classpath before it can be used.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • It's great to know that it is possible. A bit unpractical for daily dev usage as it's not integrated with lein but I can see how this could be useful for updating deployed, running apps. – deprecated May 15 '12 at 14:01
  • Integration shouldn't be that hard to build -- all you'd need would be a wrapper that reads project.clj and calls add-dependencies appropriately. For my own projects I don't use lein (as they integrate into larger projects, one of which has its own dependencies on Maven, the other on Gradle)... but I can see how optional integration, without losing standalone usage, would be a convenience. – Charles Duffy May 15 '12 at 15:14
  • You're right - especially given that pomegranate's author is intentionally using lein's format. Will look into it! – deprecated May 15 '12 at 15:55
1

I'm assuming by clojure session you mean a REPL as started by lein repl.

The short answer to your question is No - you can't do it.

The JVM supports Classloaders to provide this dynamic loading functionality and clojure makes use of these to suporrt dynamic class definitions with deftype gen-class etc.

Adding new 3rd party classes (presumably a new library jar) to the classpath would be fearsomely complicated when you consider that you'd have to unwind and re-construct the classloaders already in use.

See this question for more details on clojure's classloading

Community
  • 1
  • 1
sw1nn
  • 7,278
  • 1
  • 26
  • 36
  • It's not that bad -- URLClassloader instances (which are very common -- for that matter, Clojure's DynamicClassLoader is derived from same) support an addURL call, and if one isn't already at the tip of the tree, it can be added under the current thread's context classloader at runtime. I do this to allow pomegranate to be used to add new dependencies at runtime even within the OSGi-"sandboxed" environment provided to v2 JIRA plugins. – Charles Duffy May 15 '12 at 13:37