为 luminus clojure 项目创建可执行文件时出现问题

Problems creating an executeable for a luminus clojure project

我正在构建一个服务器程序以向包含照片详细信息的 mongo 数据库提供 API。从 REPL 中一切正常 运行,或者如果我使用 lein 运行 启动它。

问题发生在我尝试 运行 uberjar 时。构建 uberjar 工作正常:

(master) photo-api: lein uberjar
Compiling photo-api.env
Compiling photo-api.config
Compiling photo-api.core
WARNING: find-keyword already refers to: #'clojure.core/find-keyword in        namespace: image-lib.core, being replaced by: #'image-lib.core/find-keyword
Compiling photo-api.db.core
Compiling photo-api.handler
Compiling photo-api.layout
Compiling photo-api.middleware
Compiling photo-api.routes.home
Compiling photo-api.routes.services
Created /Users/iain/Code/Clojure/Luminus/photo-api/target/uberjar/photo-api-0.1.0-SNAPSHOT.jar
Created /Users/iain/Code/Clojure/Luminus/photo-api/target/uberjar/photo-api.jar
(master) photo-api:

但是 运行打开 jar 时出现错误:

(master) photo-api: java -jar target/uberjar/photo-api.jar
WARNING: find-keyword already refers to: #'clojure.core/find-keyword in   namespace: image-lib.core, being replaced by: #'image-lib.core/find-keyword
read config from resource: "config.edn"
Exception in thread "main" java.lang.RuntimeException: could not start    [#'photo-api.db.core/db*] due to
    at mount.core$up$fn__420.invoke(core.cljc:92)
    at mount.core$up.invokeStatic(core.cljc:92)
    at mount.core$up.invoke(core.cljc:90)
    at mount.core$bring.invokeStatic(core.cljc:210)
    at mount.core$bring.invoke(core.cljc:202)
    at mount.core$start.invokeStatic(core.cljc:252)
    at mount.core$start.doInvoke(core.cljc:244)
    at clojure.lang.RestFn.invoke(RestFn.java:397)
    at mount.core$start_with_args.invokeStatic(core.cljc:350)
    at mount.core$start_with_args.doInvoke(core.cljc:346)
    at clojure.lang.RestFn.invoke(RestFn.java:410)
    at photo_api.core$start_app.invokeStatic(core.clj:42)
    at photo_api.core$start_app.invoke(core.clj:41)
    at photo_api.core$_main.invokeStatic(core.clj:50)
    at photo_api.core$_main.doInvoke(core.clj:49)
    at clojure.lang.RestFn.invoke(RestFn.java:397)
    at clojure.lang.AFn.applyToHelper(AFn.java:152)
    at clojure.lang.RestFn.applyTo(RestFn.java:132)
    at photo_api.core.main(Unknown Source)
Caused by: java.lang.NullPointerException
    at com.mongodb.ConnectionString.<init>(ConnectionString.java:222)
    at com.mongodb.MongoClientURI.<init>(MongoClientURI.java:189)
    at com.mongodb.MongoClientURI.<init>(MongoClientURI.java:171)
    at monger.core$connect_via_uri.invokeStatic(core.clj:230)
    at monger.core$connect_via_uri.invoke(core.clj:230)
    at photo_api.db.core$fn__12620.invokeStatic(core.clj:29)
    at photo_api.db.core$fn__12620.invoke(core.clj:28)
    at mount.core$record_BANG_.invokeStatic(core.cljc:86)
    at mount.core$record_BANG_.invoke(core.cljc:85)
    at mount.core$up$fn__420.invoke(core.cljc:93)
    ... 18 more

或 SNAPSHOT jar。

(master) photo-api: java -jar target/uberjar/photo-api-0.1.0-SNAPSHOT.jar

Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/Var
    at photo_api.core.<clinit>(Unknown Source)
Caused by: java.lang.ClassNotFoundException: clojure.lang.Var
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more
(master) photo-api:

我在这里错过了什么?我猜这与开发版本和生产版本的差异有关,但我无法发现任何明显的错误消息对我帮助不大。

这是项目文件,据我所知大部分是直接来自原始 luminus 模板:

(defproject photo-api "0.1.0-SNAPSHOT"

  :description "API for geting data from photos db"
  :url "http://soulflyer.com"

  :dependencies [[cider/cider-nrepl "0.14.0"]
             [clj-time "0.13.0"]
             [com.google.guava/guava "20.0"]
             [com.novemberain/monger "3.1.0" :exclusions [com.google.guava/guava]]
             [compojure "1.6.0"]
             [cprop "0.1.10"]
             [funcool/struct "1.0.0"]
             [luminus-immutant "0.2.3"]
             [luminus-nrepl "0.1.4"]
             [luminus/ring-ttl-session "0.3.2"]
             [markdown-clj "0.9.99"]
             [metosin/compojure-api "1.1.10"]
             [metosin/muuntaja "0.3.1"]
             [metosin/ring-http-response "0.9.0"]
             [mount "0.1.11"]
             [org.clojure/clojure "1.8.0"]
             [org.clojure/tools.cli "0.3.5"]
             [org.clojure/tools.logging "0.4.0"]
             [org.clojure/data.json "0.2.6"]
             [org.webjars.bower/tether "1.4.0"]
             [org.webjars/bootstrap "4.0.0-alpha.5"]
             [org.webjars/font-awesome "4.7.0"]
             [org.webjars/jquery "3.1.1"]
             [ring-webjars "0.2.0"]
             [ring/ring-core "1.6.1"]
             [ring/ring-defaults "0.3.0"]
             [selmer "1.10.7"]
             [image-lib "0.2.1-SNAPSHOT"]]

  :min-lein-version "2.0.0"

  :jvm-opts ["-server" "-Dconf=.lein-env"]
  :source-paths ["src/clj"]
  :test-paths ["test/clj"]
  :resource-paths ["resources"]
  :target-path "target/%s/"
  :main ^:skip-aot photo-api.core

  :plugins [[lein-cprop "1.0.3"]
        [org.clojars.punkisdead/lein-cucumber "1.0.5"]
        [lein-immutant "2.1.0"]]
  :cucumber-feature-paths ["test/clj/features"]


  :profiles
  {:uberjar {:omit-source true
         :aot :all
         :uberjar-name "photo-api.jar"
         :source-paths ["env/prod/clj"]
         :resource-paths ["env/prod/resources"]}

   :dev           [:project/dev :profiles/dev]
   :test          [:project/dev :project/test :profiles/test]

   :project/dev  {:dependencies [[prone "1.1.4"]
                             [ring/ring-mock "0.3.0"]
                             [ring/ring-devel "1.6.1"]
                             [pjstadig/humane-test-output "0.8.2"]
                             [clj-webdriver/clj-webdriver "0.7.2"]
                             [org.apache.httpcomponents/httpcore "4.4"]
                             [org.clojure/core.cache "0.6.3"]
                             [org.seleniumhq.selenium/selenium-server "2.48.2"]]
              :plugins      [[com.jakemccrary/lein-test-refresh "0.19.0"]
                             [refactor-nrepl "2.3.0-SNAPSHOT"]]
              :source-paths ["env/dev/clj"]
              :resource-paths ["env/dev/resources"]
              :repl-options {:init-ns user}
              :injections [(require 'pjstadig.humane-test-output)
                           (pjstadig.humane-test-output/activate!)]}
   :project/test {:resource-paths ["env/test/resources"]}
   :profiles/dev {}
   :profiles/test {}})

我认为您只是缺少必需的配置 - 至少 Mongo 连接字符串。

当 运行在开发模式下运行时,luminus(和 cprops 配置库)使用来自您的 profiles.clj 的配置。 然而,这是 leiningen 的东西,当 运行ning 从 uberjar 时它不可用。

您可以在 "config.edn" 文件和 运行 uberjar 中指定所有 "production" 配置,如下所示:

java -Dconf=config.edn -jar target/uberjar/photo-api.jar

您还可以使用java系统属性来一项一项地设置配置值。 有关详细信息,请参阅 http://www.luminusweb.net/docs/environment.md