【发布时间】:2014-06-06 18:19:04
【问题描述】:
这是一个非常简单的 Leiningen 项目示例,使用 lein new app hanging 制作,只有两个文件 project.clj:
(defproject hanging "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.6.0"]]
:main hanging.core
:aot [hanging.core]
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
和src/hanging/core.clj:
(ns hanging.core (:gen-class))
(println "1")
(def problematic (future))
(println "2")
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println 3))
运行项目时,这是输出(提示冻结,我必须用C-c杀死它):
% lein clean && lein run
Compiling hanging.core
1
2
注释掉problematic Var 定义后,输出如下(JVM 关闭):
% lein clean && lein run
Compiling hanging.core
1
2
1
2
3
我猜 AOT 是这里的罪魁祸首,但有人能解释一下到底发生了什么吗?
我对第二个(已注释)版本没有任何问题:在 AOT 期间,编译器会执行所有顶级表单,这就是为什么 1 和 2 在输出中出现两次的原因。
但是为什么在里面添加一个空未来的 var 会改变呢?这是否意味着编译器陷入了 AOT 阶段?任何细节和指针表示赞赏...
根据建议的答案,我已将 (shutdown-agents) 添加到 (-main),但它不会更改编译步骤(编译大约需要 60 秒)。但是,有了(shutdown-agents),程序就不再挂起。
【问题讨论】: