我使用带有lein 2.0的lein new compojure mongotest
和一个Procfile web: lein ring server-headless $PORT
创建了一个compojure应用程序。这工作正常,但现在我添加
(def mongolab-url (System/getenv "MONGOLAB_URI"))
(println "mongolab-url")
(println mongolab-url)
(mg/connect-via-uri! mongolab-url)
当我尝试git push heroku master
Heroku最终给了我
Compiling mongotest.handler
mongolab-url
nil
Exception in thread "main" java.lang.NullPointerException, compiling:(handler.clj:13:1)
... 25 more
Compilation failed: Subprocess failed
Error encountered performing task 'compile' with profile(s): 'production'
Suppressed exit
! Failed to build.
! Push rejected, failed to compile Clojure (Leiningen 2) app
我在handler.clj
的顶层添加了这些行。我看到连接的一些旧文档是在main
中创建的,但这必须是旧版本的compojure,因为在生成的应用程序中不再有main
(我已经找到)。在当前版本中应该在哪里建立连接? (或者我的Procfile不对吗?)
(是的,MONGOLAB_URI
中定义了heroku config
答案 0 :(得分:1)
对我有用且似乎最惯用的答案是将上述连接放入同一文件中的函数init
(myproject/handler.clj
)
(defn init[] (mg/connect-via-uri! (System/getenv "MONGOLAB_URI")))
并从
更新project.clj
文件环描述符行
:ring {:handler myproject.handler/app}
到
:ring {:handler myproject.handler/app :init myproject.handler/init}
答案 1 :(得分:0)
您不希望在命名空间加载时发生副作用(例如打开数据库连接),这是有效的编译时间。当你在clojure启动时编译你的代码时,通常你可以逃避这些事情,但在这种情况下,heroku会将你的应用程序预编译到一个jar中,以便它可以更快地提供它。现在,在编译时,您尝试阅读PORT
环境变量;但是直到heroku试图实际运行你的应用程序才会设置它。
解决方案是仅在运行时创建它,例如在-main
或其他函数中创建它,或者将其定义为只delay
的{{1}}运行时。