[英]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中打开这个文件并打开苹果酒时,我无法正确编译它。
(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)
(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.