Leiningen Emacs and Clojure

I have a project setup at the moment that works like a charm when I use lein run

. The smallest case that causes the problem is as follows. I have two files shown below. The file core.clj

should throw an error and then stop. A bug is simply a bug that extends the Error

Java standard . However, when I open this file in emacs and open the cider, I cannot compile it correctly.

core.clj

(ns meta-clojure.core
  (:import (org.jsoup Jsoup)
           (java.lang String)
           (meta_clojure.stm RetryEx)))

(defn -main
  [& args]
  (println "Throwing exception now..")
  (throw (RetryEx. "this is broken"))
  (println "End of main")
  nil)

      

RetryEx.clj

(ns meta-clojure.stm.RetryEx
  (:gen-class :extends java.lang.Error))

      

Now, as I said, when I run the command lein run

, it runs just fine. However, in emacs I get the following stack trace:

clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: meta_clojure.stm.RetryEx, compiling:(/home/christophe/bitbucket/meta-clojure/src/meta_clojure/core.clj:1:1)
                                Compiler.java:7142 clojure.lang.Compiler.load
                                  NO_SOURCE_FILE:1 user/eval931
                                Compiler.java:6703 clojure.lang.Compiler.eval
                                Compiler.java:6666 clojure.lang.Compiler.eval
                                     core.clj:2927 clojure.core/eval
                                      main.clj:239 clojure.main/repl[fn]
                                      main.clj:239 clojure.main/repl[fn]
                                      main.clj:257 clojure.main/repl[fn]
                                      main.clj:257 clojure.main/repl
                                  RestFn.java:1523 clojure.lang.RestFn.invoke
                         interruptible_eval.clj:67 clojure.tools.nrepl.middleware.interruptible-eval/evaluate[fn]
                                      AFn.java:152 clojure.lang.AFn.applyToHelper
                                      AFn.java:144 clojure.lang.AFn.applyTo
                                      core.clj:624 clojure.core/apply
                                     core.clj:1862 clojure.core/with-bindings*
                                   RestFn.java:425 clojure.lang.RestFn.invoke
                         interruptible_eval.clj:51 clojure.tools.nrepl.middleware.interruptible-eval/evaluate
                        interruptible_eval.clj:183 clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval[fn]
                        interruptible_eval.clj:152 clojure.tools.nrepl.middleware.interruptible-eval/run-next[fn]
                                       AFn.java:22 clojure.lang.AFn.run
                      ThreadPoolExecutor.java:1145 java.util.concurrent.ThreadPoolExecutor.runWorker
                       ThreadPoolExecutor.java:615 java.util.concurrent.ThreadPoolExecutor$Worker.run
                                   Thread.java:745 java.lang.Thread.run
Caused by: java.lang.ClassNotFoundException: meta_clojure.stm.RetryEx
                           URLClassLoader.java:366 java.net.URLClassLoader$1.run
                           URLClassLoader.java:355 java.net.URLClassLoader$1.run
                                  (Unknown Source) java.security.AccessController.doPrivileged
                           URLClassLoader.java:354 java.net.URLClassLoader.findClass
                        DynamicClassLoader.java:61 clojure.lang.DynamicClassLoader.findClass
                              ClassLoader.java:425 java.lang.ClassLoader.loadClass
                              ClassLoader.java:358 java.lang.ClassLoader.loadClass
                                  (Unknown Source) java.lang.Class.forName0
                                    Class.java:191 java.lang.Class.forName
                                        core.clj:1 meta-clojure.core/eval935[fn]
                                        core.clj:1 meta-clojure.core/eval935
                                Compiler.java:6703 clojure.lang.Compiler.eval
                                Compiler.java:6692 clojure.lang.Compiler.eval
                                Compiler.java:7130 clojure.lang.Compiler.load

      

Can anyone help me please? I think I need to tell Sid / Emacs to compile ahead of time or something. Perhaps leiningen compiles to different directories than emacs?

+3


source to share


1 answer


You are correct that you need to compile the meta clojure.stm.RetryEx namespace to create the class files before you can include it. This is sometimes useful if you are writing a class to be consumed by a Java library and core.clj is just a test harness for development, although this is not an easy or typical way to solve it. To use require instead of include, to reference the clojure namespace with the clojure project.

You can check what was actually compiled by looking at the target/classes

project directory . before compiling I see:

arthur@a:~/meta-clojure$ ls target/classes/
META-INF

      

Then after compiling from repl:

user> (compile 'meta-clojure.stm.RetryEx)
meta-clojure.stm.RetryEx
user> 
meta-clojure.core> (-main )
Throwing exception now..
RetryEx this is broken  meta-clojure.core/-main (core.clj:6)
meta-clojure.core> 

      

And checking the same directory:

arthur@a:~/meta-clojure$ ls -R  target/classes/
target/classes/:
meta_clojure  META-INF

target/classes/meta_clojure:
stm

target/classes/meta_clojure/stm:
RetryEx.class  RetryEx$fn__3333.class  RetryEx$fn__3351.class  RetryEx__init.class  RetryEx$loading__4958__auto__.class

target/classes/META-INF:
maven

target/classes/META-INF/maven:
meta-clojure

target/classes/META-INF/maven/meta-clojure:
meta-clojure

target/classes/META-INF/maven/meta-clojure/meta-clojure:
pom.properties

      



Leiningen will happily compile the AOT for you if you specify the spaces in which they require:

project.clj:

(defproject meta-clojure "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]]
  :aot [meta-clojure.stm.RetryEx])

      

and then run lein compile

:

arthur@a:~/meta-clojure$ lein compile
Compiling meta-clojure.stm.RetryEx
arthur@a:~/meta-clojure$ ls target/classes/
meta_clojure/ META-INF/     
arthur@a:~/meta-clojure$ ls target/classes/meta_clojure/stm/

      

PS: you also don't need to enable java.lang.String

by default.

+1


source







All Articles