我试图在创建时理解“Lieningen”行为uberjar
。以下是重现该行为的最小示例:
(ns my-stuff.core
(:gen-class))
(def some-var (throw (Exception. "boom!")))
(defn -main [& args]
(println some-var))
当执行此操作时lein run
它显然因异常而失败。但是,我不明白为什么要执行lein uberjar
也因变量定义异常而失败?为什么执行lein uberjar
尝试评估变量值?这是具体针对uberjar
任务还是我错过了有关 Clojure 或 Leiningen 的更实质性内容?
为了编译 uberjar 的命名空间(如果您打开了 AOT),clojure 编译器必须加载您的命名空间。这将始终调用所有顶级副作用。
处理这个问题的最佳方法是永远不要在顶级代码中产生副作用(无论是在内部还是外部)def
形式),并具有初始化函数来实现所需的任何启动副作用。
解决方法可以是创建一个小型命名空间,使用内省在运行时加载其余代码,而不是在编译时加载 - 使用如下函数:
(defn -main
[]
(require 'my.primary.ns)
((resolve 'my.primary.ns/start)))
如果该命名空间已编译,则 jvm 可以找到 -main 并运行它,尽管没有编译任何其他代码。运行时require
将导致 Clojure 编译器仅在运行时加载其余代码,并且resolve
需要这样-main
将干净地编译 - 它返回引用的 var,然后在调用时调用您的函数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)