簡體   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