2014-04-11 50 views
1

我試圖在使用aot的項目中將midje「事實」與我的源代碼一起包含在內。試圖訪問repl或運行項目導致出現以下錯誤,我已經包含了一個重現此問題的最小示例項目。謝謝你的幫助!Clojure/Midje使用源內測試的AOT編譯無法運行

project.clj

(defproject test-midje "0.1.1" 
    :description "Why doesn't midje work?" 
    :min-lein-version "2.0.0" 
    :source-paths ["src/clj"] 
    :repl-options { 
       :timeout 120000 
       } 
    :main org.midjetest.core 
    :profiles {:dev {:dependencies [[midje "1.5.0"]]}} 
    :aot [org.midjetest.core]) 

SRC/CLJ /組織/ midjetest/core.clj

(ns org.midjetest.core 
    (:require [midje.sweet :refer [fact facts]])) 


(defn addtwo [a] (+ 2 a)) 

(fact "addtwo adds two to numbers" 
     (addtwo 3) => 5) 


(defn -main 
    "testing with main" 
    ([] (println (addtwo 5)))) 

lein runlein repl提供以下錯誤:

$ lein repl 
Compiling org.midjetest.core 
Exception in thread "main" java.lang.ExceptionInInitializerError 
at java.lang.Class.forName0(Native Method) 
at java.lang.Class.forName(Class.java:270) 
at clojure.lang.RT.loadClassForName(RT.java:2056) 
at clojure.lang.RT.load(RT.java:419) 
at clojure.lang.RT.load(RT.java:400) 
at clojure.core$load$fn__4890.invoke(core.clj:5415) 
at clojure.core$load.doInvoke(core.clj:5414) 
at clojure.lang.RestFn.invoke(RestFn.java:408) 
at clojure.core$load_one.invoke(core.clj:5227) 
at clojure.core$load_lib.doInvoke(core.clj:5264) 
at clojure.lang.RestFn.applyTo(RestFn.java:142) 
at clojure.core$apply.invoke(core.clj:603) 
at clojure.core$load_libs.doInvoke(core.clj:5298) 
at clojure.lang.RestFn.applyTo(RestFn.java:137) 
at clojure.core$apply.invoke(core.clj:603) 
at clojure.core$require.doInvoke(core.clj:5381) 
at clojure.lang.RestFn.invoke(RestFn.java:408) 
at org.midjetest.core$loading__4784__auto__.invoke(core.clj:1) 
at org.midjetest.core__init.load(Unknown Source) 
at org.midjetest.core__init.<clinit>(Unknown Source) 
at java.lang.Class.forName0(Native Method) 
at java.lang.Class.forName(Class.java:270) 
at clojure.lang.RT.loadClassForName(RT.java:2056) 
at clojure.lang.RT.load(RT.java:419) 
at clojure.lang.RT.load(RT.java:400) 
at clojure.core$load$fn__4890.invoke(core.clj:5415) 
at clojure.core$load.doInvoke(core.clj:5414) 
at clojure.lang.RestFn.invoke(RestFn.java:408) 
at clojure.core$load_one.invoke(core.clj:5227) 
at clojure.core$load_lib.doInvoke(core.clj:5264) 
at clojure.lang.RestFn.applyTo(RestFn.java:142) 
at clojure.core$apply.invoke(core.clj:603) 
at clojure.core$load_libs.doInvoke(core.clj:5298) 
at clojure.lang.RestFn.applyTo(RestFn.java:137) 
at clojure.core$apply.invoke(core.clj:603) 
at clojure.core$require.doInvoke(core.clj:5381) 
at clojure.lang.RestFn.invoke(RestFn.java:408) 
at user$eval5.invoke(form-init9180276290836069038.clj:1) 
at clojure.lang.Compiler.eval(Compiler.java:6511) 
at clojure.lang.Compiler.eval(Compiler.java:6500) 
at clojure.lang.Compiler.eval(Compiler.java:6500) 
at clojure.lang.Compiler.load(Compiler.java:6952) 
at clojure.lang.Compiler.loadFile(Compiler.java:6912) 
at clojure.main$load_script.invoke(main.clj:283) 
at clojure.main$init_opt.invoke(main.clj:288) 
at clojure.main$initialize.invoke(main.clj:316) 
at clojure.main$null_opt.invoke(main.clj:349) 
at clojure.main$main.doInvoke(main.clj:427) 
at clojure.lang.RestFn.invoke(RestFn.java:421) 
at clojure.lang.Var.invoke(Var.java:419) 
at clojure.lang.AFn.applyToHelper(AFn.java:163) 
at clojure.lang.Var.applyTo(Var.java:532) 
at clojure.main.main(main.java:37) 
Caused by: java.lang.NullPointerException 
at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333) 
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:988) 
at clojure.lang.Namespace.find(Namespace.java:188) 
at clojure.core$find_ns.invoke(core.clj:3659) 
at clojure.core$the_ns.invoke(core.clj:3691) 
at clojure.core$ns_name.invoke(core.clj:3698) 
at midje.Bootstrap$bootstrap.invoke(Bootstrap.clj:8) 
at midje.sweet__init.load(Unknown Source) 
at midje.sweet__init.<clinit>(Unknown Source) 
... 53 more 
Exception in thread "Thread-4" clojure.lang.ExceptionInfo: Subprocess failed {:exit-code 1} 
at clojure.core$ex_info.invoke(core.clj:4327) 
at leiningen.core.eval$fn__3532.invoke(eval.clj:226) 
at clojure.lang.MultiFn.invoke(MultiFn.java:231) 
at leiningen.core.eval$eval_in_project.invoke(eval.clj:326) 
at clojure.lang.AFn.applyToHelper(AFn.java:167) 
at clojure.lang.AFn.applyTo(AFn.java:151) 
at clojure.core$apply.invoke(core.clj:619) 
at leiningen.repl$server$fn__7443.invoke(repl.clj:201) 
at clojure.lang.AFn.applyToHelper(AFn.java:159) 
at clojure.lang.AFn.applyTo(AFn.java:151) 
at clojure.core$apply.invoke(core.clj:617) 
at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1788) 
at clojure.lang.RestFn.invoke(RestFn.java:425) 
at clojure.lang.AFn.applyToHelper(AFn.java:163) 
at clojure.lang.RestFn.applyTo(RestFn.java:132) 
at clojure.core$apply.invoke(core.clj:621) 
at clojure.core$bound_fn_STAR_$fn__4102.doInvoke(core.clj:1810) 
at clojure.lang.RestFn.invoke(RestFn.java:397) 
at clojure.lang.AFn.run(AFn.java:24) 
at java.lang.Thread.run(Thread.java:744) 

回答

2

問題的根源這裏是Bootstrap.clj在AOT-ed時不起作用;它取決於在它之前被加載的一些名稱空間;然而,對於Clojure的AOTed類的靜態初始化都或多或少等價的:

(binding [clojure.core/*ns* nil clojure.core/*fn-loader* loader clojure.core/*read-eval* true] (my.class/load))

由於之前midje.sweet定義它自己的NS(https://github.com/marick/Midje/blob/master/src/midje/sweet.clj#L2)引導/引導被調用時,*ns*保持空,(ns-name *ns*)崩潰。

我不認爲你可以做這個工作,除非midje的引導代碼發生變化。我建議把你的測試放到單獨的文件中,而不是將它們分開。