Search code examples
javamavenclojureleiningenclojure-maven-plugin

How to load java classes from maven project in a Clojure REPL?


Does anyone know an easy way to load java classes from maven project in a Clojure REPL?

I took a look at the lein docs and they don't seem to support maven.

The clojure-maven-plugin provides a clojure:repl target, but it seems to just load the project's dependencies, not the classes in my src/main/java.

Ideally I wouldn't be willing to setup a lein project only for this task, since I just want to play around with some java classes I have on my project.

Anyone?


Solution

  • lein supports requiring dependencies from maven repos. In fact this is one of the, if not the, central lein feature.

    You can use pallet/alembic to acquire and load maven dependencies are runtime from a repl.

    I have pallet/alembic available due to the following contents in my ~/.lein/profiles.clj

     {:user
      {:dependencies [[clojure-complete "0.2.3"]
                      [lein-pdo "0.1.1"]
                      [criterium "0.4.2"]
                      [org.clojure/tools.trace "0.7.6"]
                      [alembic "0.2.0"]]}}
    

    this means that I can use alembic from any repl

    user> (require '[alembic.still :as still])
    nil
    user> (org.apache.giraph.GiraphRunner.) ; create a new GiraphRunner
    CompilerException java.lang.ClassNotFoundException: org.apache.giraph.GiraphRunner, compiling:(/tmp/form-init5282725623346658314.clj:1:50) 
    

    oops, I don't actually have that Class available

    user> (still/distill '[[org.apache.giraph/giraph-core "1.0.0"]] :repositories [["apache" "http://obelix.ics.uci.edu/nexus/content/groups/hyracks-public-releases"]])
    WARN: com.google.guava/guava version 12.0 requested, but 14.0.1 already on classpath.
    Loaded dependencies:
    [[commons-cli "1.2"]
     [commons-io "2.1"]
     [jline "0.9.94"]
     [junit "3.8.1"]
     [log4j "1.2.15"]
     [com.google.code.findbugs/jsr305 "1.3.9"]
     [com.yammer.metrics/metrics-core
      "2.2.0"
      :exclusions
      [[org.slf4j/slf4j-api]]]
     [io.netty/netty "3.5.3.Final"]
     [it.unimi.dsi/fastutil "6.5.3"]
     [javax.activation/activation "1.1"]
     [javax.mail/mail "1.4"]
     [net.iharder/base64 "2.3.8"]
     [org.apache.giraph/giraph-core "1.0.0"]
     [org.apache.zookeeper/zookeeper
      "3.3.3"
      :exclusions
      [[com.sun.jmx/jmxri] [com.sun.jdmk/jmxtools] [javax.jms/jms]]]
     [org.codehaus.jackson/jackson-core-asl "1.8.0"]
     [org.codehaus.jackson/jackson-mapper-asl "1.8.0"]
     [org.json/json "20090211"]
     [org.slf4j/slf4j-api "1.7.2"]
     [org.slf4j/slf4j-log4j12 "1.7.2"]]
    Dependencies not loaded due to conflict with previous jars :
    [[com.google.guava/guava "12.0"]]
    nil
    

    OK, now we have giraph

    user> (org.apache.giraph.GiraphRunner.) ; create a new GiraphRunner
    CompilerException java.lang.NoClassDefFoundError: org/apache/hadoop/util/Tool, compiling:(/tmp/form-init5282725623346658314.clj:1:50) 
    user> (still/distill '[[org.apache.hadoop/hadoop-core "0.20.2"]])
    WARN: commons-logging version 1.0.3 requested, but 1.1.1 already on classpath.
    WARN: commons-codec version 1.3 requested, but 1.6 already on classpath.
    Loaded dependencies:
    [[ant "1.6.5"]
     [commons-cli "1.2"]
     [commons-el "1.0"]
     [commons-httpclient "3.0.1"]
     [commons-net "1.4.1"]
     [hsqldb "1.8.0.10"]
     [junit "4.5"]
     [oro "2.0.8"]
     [xmlenc "0.52"]
     [net.java.dev.jets3t/jets3t "0.7.1"]
     [net.sf.kosmosfs/kfs "0.3"]
     [org.apache.hadoop/hadoop-core "0.20.2"]
     [org.eclipse.jdt/core "3.1.1"]
     [org.mortbay.jetty/jetty "6.1.14"]
     [org.mortbay.jetty/jetty-util "6.1.14"]
     [org.mortbay.jetty/jsp-2.1 "6.1.14"]
     [org.mortbay.jetty/jsp-api-2.1 "6.1.14"]
     [org.mortbay.jetty/servlet-api-2.5 "6.1.14"]
     [tomcat/jasper-compiler "5.5.12"]
     [tomcat/jasper-runtime "5.5.12"]]
    Dependencies not loaded due to conflict with previous jars :
    [[commons-codec "1.3"] [commons-logging "1.0.3"]]
    nil
    user> (org.apache.giraph.GiraphRunner.) ; create a new GiraphRunner
    #<GiraphRunner org.apache.giraph.GiraphRunner@2dbfe923>
    user> (bean *1)
    {:conf nil, :class org.apache.giraph.GiraphRunner}
    

    so, after acquiring the requisite dependencies, we can create and experiment with most any Class available via a maven repository.

    In your particular case, you could install your java project locally via maven, then use alembic to load it into a repl for experimentation.