繁体   English   中英

Leiningen Emacs和Clojure

[英]Leiningen Emacs and Clojure

当我使用lein run时,我现在有一个项目设置就像一个魅力。 导致问题的最小情况如下。 我有两个文件,如下所示。 core.clj文件应该抛出错误然后停止。 该错误只是一个扩展标准的Java Error 但是,当我在emacs中打开这个文件并打开苹果酒时,我无法正确编译它。

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))

现在,正如我所说,当我运行lein run命令时,它执行得很好。 但是,在emacs中,我得到以下堆栈跟踪:

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

有人可以帮帮我吗? 我想我需要告诉Cider / Emacs提前编译或者其他东西。 也许leiningen编译到不同的目录而不是emacs?

您是正确的,您需要编译meta-clojure.stm.RetryEx命名空间以生成类文件,然后才能包含它。 如果你正在编写一个供Java库使用的类,那么这有时很有用。而core.clj只是一个用于开发的测试工具,尽管它不是简单或典型的方法。 使用require而不是include从Clojure项目引用clojure命名空间更常见。

您可以通过查看项目的target/classes目录来检查实际编译的内容。 在编译之前我看到:

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

然后从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> 

并检查相同的目录:

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很乐意为您进行AOT编译:

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])

然后运行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:你也不需要包含默认包含的java.lang.String

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM