简体   繁体   English

Leiningen Emacs和Clojure

[英]Leiningen Emacs and Clojure

I have a project setup at the moment that works like a charm when I use lein run . 当我使用lein run时,我现在有一个项目设置就像一个魅力。 The minimal case that causes the problem is the following. 导致问题的最小情况如下。 I have two files, shown below. 我有两个文件,如下所示。 The core.clj file is supposed to throw an error and then stop. core.clj文件应该抛出错误然后停止。 The error is simply an error that extends the standard Error of Java. 该错误只是一个扩展标准的Java Error However, when I open up this file in emacs and open up cider I can't get it to compile properly. 但是,当我在emacs中打开这个文件并打开苹果酒时,我无法正确编译它。

core.clj 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 RetryEx.clj

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

Now, as I said, when I run the lein run command it executes just fine. 现在,正如我所说,当我运行lein run命令时,它执行得很好。 However, in emacs I get the following stack trace: 但是,在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

Could anyone help me out please? 有人可以帮帮我吗? I think I need to tell Cider/Emacs to compile ahead of time or something. 我想我需要告诉Cider / Emacs提前编译或者其他东西。 Perhaps leiningen compiles to different directories than emacs? 也许leiningen编译到不同的目录而不是emacs?

You are correct that you need to compile the meta-clojure.stm.RetryEx namespace to produce the class files before you can include it. 您是正确的,您需要编译meta-clojure.stm.RetryEx命名空间以生成类文件,然后才能包含它。 This is sometimes useful if you are writing a class for consumption by a Java library and core.clj is only a test harness for developing, though it's not the easy or typical way to go about it. 如果你正在编写一个供Java库使用的类,那么这有时很有用。而core.clj只是一个用于开发的测试工具,尽管它不是简单或典型的方法。 It is a bit more common to use require instead of include to refer to a clojure namespace from with a Clojure project. 使用require而不是include从Clojure项目引用clojure命名空间更常见。

You can check what is actually been compiled by looking in the target/classes directory of the project. 您可以通过查看项目的target/classes目录来检查实际编译的内容。 before compiling I see: 在编译之前我看到:

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

Then after compiling it from the repl: 然后从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 is happy to do the AOT compiling for you, if you specify which namespaces require it: 如果您指定哪个名称空间需要,Leiningen很乐意为您进行AOT编译:

project.clj: 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 : 然后运行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 include java.lang.String it's included by default. PS:你也不需要包含默认包含的java.lang.String

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

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