【问题标题】:Schema causing uberimage build failure导致 uberimage 构建失败的架构
【发布时间】:2015-09-05 06:40:44
【问题描述】:

我正在 Clojure 中开发一个简单的 hello world web 应用程序。但是,在我将Schema 库添加到我的项目后,我在尝试使用lein uberjar 构建一个uberjar 时开始收到以下错误。奇怪的是,应用程序在使用lein dev 启动时仍然通过了单元测试并且运行时没有错误。

java.lang.RuntimeException:无法解析符号: 在这种情况下缺少必需的密钥,正在编译:(server/api.clj:21:17) 在 clojure.lang.Compiler.analyze(Compiler.java:6464) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$VectorExpr.parse(Compiler.java:3126) 在 clojure.lang.Compiler.analyze(Compiler.java:6447) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$MapExpr.parse(Compiler.java:2981) 在 clojure.lang.Compiler.analyze(Compiler.java:6453) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$MapExpr.parse(Compiler.java:2981) 在 clojure.lang.Compiler.analyze(Compiler.java:6453) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.access$100(Compiler.java:38) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6050) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6100) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6100) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6100) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6100) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$FnMethod.parse(Compiler.java:5217) 在 clojure.lang.Compiler$FnExpr.parse(Compiler.java:3846) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6642) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$FnMethod.parse(Compiler.java:5217) 在 clojure.lang.Compiler$FnExpr.parse(Compiler.java:3846) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6642) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.access$100(Compiler.java:38) 在 clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:538) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler.compile1(Compiler.java:7221) 在 clojure.lang.Compiler.compile(Compiler.java:7292) 在 clojure.lang.RT.compile(RT.java:398) 在 clojure.lang.RT.load(RT.java:438) 在 clojure.lang.RT.load(RT.java:411) 在 clojure.core$load$fn__5066.invoke(core.clj:5641) 在 clojure.core$load.doInvoke(core.clj:5640) 在 clojure.lang.RestFn.invoke(RestFn.java:408) 在 clojure.core$load_one.invoke(core.clj:5446) 在 clojure.core$compile$fn__5071.invoke(core.clj:5652) 在 clojure.core$compile.invoke(core.clj:5651) 在 用户$eval9$fn__16.invoke(form-init1857067608391167398.clj:1) 在 用户$eval9.invoke(form-init1857067608391167398.clj:1) 在 clojure.lang.Compiler.eval(Compiler.java:6703) 在 clojure.lang.Compiler.eval(Compiler.java:6693) 在 clojure.lang.Compiler.load(Compiler.java:7130) 在 clojure.lang.Compiler.loadFile(Compiler.java:7086) 在 clojure.main$load_script.invoke(main.clj:274) 在 clojure.main$init_opt.invoke(main.clj:279) 在 clojure.main$initialize.invoke(main.clj:307) 在 clojure.main$null_opt.invoke(main.clj:342) 在 clojure.main$main.doInvoke(main.clj:420) 在 clojure.lang.RestFn.invoke(RestFn.java:421) 在 clojure.lang.Var.invoke(Var.java:383) 在 clojure.lang.AFn.applyToHelper(AFn.java:156) 在 clojure.lang.Var.applyTo(Var.java:700) 在 clojure.main.main(main.java:37) 引起:java.lang.RuntimeException: 无法解析符号:在此上下文中缺少所需键 clojure.lang.Util.runtimeException(Util.java:221) 在 clojure.lang.Compiler.resolveIn(Compiler.java:6940) 在 clojure.lang.Compiler.resolve(Compiler.java:6884) 在 clojure.lang.Compiler.analyzeSymbol(Compiler.java:6845) 在 clojure.lang.Compiler.analyze(Compiler.java:6427) ... 153 更多 线程“主”java.lang.RuntimeException 中的异常:无法 解析符号:在此上下文中缺少必需的键, 编译:(server/api.clj:21:17) 在 clojure.lang.Compiler.analyze(Compiler.java:6464) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$VectorExpr.parse(Compiler.java:3126) 在 clojure.lang.Compiler.analyze(Compiler.java:6447) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$MapExpr.parse(Compiler.java:2981) 在 clojure.lang.Compiler.analyze(Compiler.java:6453) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$MapExpr.parse(Compiler.java:2981) 在 clojure.lang.Compiler.analyze(Compiler.java:6453) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.access$100(Compiler.java:38) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6050) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6100) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6100) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6100) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6100) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$FnMethod.parse(Compiler.java:5217) 在 clojure.lang.Compiler$FnExpr.parse(Compiler.java:3846) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6642) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6646) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782) 在 clojure.lang.Compiler$FnMethod.parse(Compiler.java:5217) 在 clojure.lang.Compiler$FnExpr.parse(Compiler.java:3846) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6642) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6632) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.access$100(Compiler.java:38) 在 clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:538) 在 clojure.lang.Compiler.analyzeSeq(Compiler.java:6644) 在 clojure.lang.Compiler.analyze(Compiler.java:6445) 在 clojure.lang.Compiler.analyze(Compiler.java:6406) 在 clojure.lang.Compiler.compile1(Compiler.java:7221) 在 clojure.lang.Compiler.compile(Compiler.java:7292) 在 clojure.lang.RT.compile(RT.java:398) 在 clojure.lang.RT.load(RT.java:438) 在 clojure.lang.RT.load(RT.java:411) 在 clojure.core$load$fn__5066.invoke(core.clj:5641) 在 clojure.core$load.doInvoke(core.clj:5640) 在 clojure.lang.RestFn.invoke(RestFn.java:408) 在 clojure.core$load_one.invoke(core.clj:5446) 在 clojure.core$compile$fn__5071.invoke(core.clj:5652) 在 clojure.core$compile.invoke(core.clj:5651) 在 用户$eval9$fn__16.invoke(form-init1857067608391167398.clj:1) 在 用户$eval9.invoke(form-init1857067608391167398.clj:1) 在 clojure.lang.Compiler.eval(Compiler.java:6703) 在 clojure.lang.Compiler.eval(Compiler.java:6693) 在 clojure.lang.Compiler.load(Compiler.java:7130) 在 clojure.lang.Compiler.loadFile(Compiler.java:7086) 在 clojure.main$load_script.invoke(main.clj:274) 在 clojure.main$init_opt.invoke(main.clj:279) 在 clojure.main$initialize.invoke(main.clj:307) 在 clojure.main$null_opt.invoke(main.clj:342) 在 clojure.main$main.doInvoke(main.clj:420) 在 clojure.lang.RestFn.invoke(RestFn.java:421) 在 clojure.lang.Var.invoke(Var.java:383) 在 clojure.lang.AFn.applyToHelper(AFn.java:156) 在 clojure.lang.Var.applyTo(Var.java:700) 在 clojure.main.main(main.java:37) 引起:java.lang.RuntimeException: 无法解析符号:在此上下文中缺少所需键 clojure.lang.Util.runtimeException(Util.java:221) 在 clojure.lang.Compiler.resolveIn(Compiler.java:6940) 在 clojure.lang.Compiler.resolve(Compiler.java:6884) 在 clojure.lang.Compiler.analyzeSymbol(Compiler.java:6845) 在 clojure.lang.Compiler.analyze(Compiler.java:6427) ... 153 更多 编译失败:子进程失败

下面是我使用架构的源文件。为简洁起见,我省略了其余的源文件,但如果有人想查看其余部分,请询问。

(ns server.api
  (:require [aleph.http :as http]
            [compojure.api.sweet :refer :all]
            [compojure.route :as route]
            [com.stuartsierra.component :as component]
            [ring.middleware.reload :refer [wrap-reload]]
            [ring.util.http-response :refer :all]
            [schema.core :as s]
            [server.logging :refer [wrap-exception-logging wrap-request-logging] :as log]))

(s/defschema Greeting
  {:hello s/Str
   s/Keyword s/Any})

(defn app [db]
  (api
   {:format {:formats [:json-kw]}}
   (middlewares [wrap-request-logging
                 wrap-exception-logging]
                (swagger-ui "/docs" :swagger-docs "/endpoints")
                (swagger-docs "/endpoints"
                 {:info {:title "Hello World Api"}})

                (GET* "/greet" []
                      :summary "Greets someone by name."
                      :description "Greets a person by name, telling them about
                                    the database configuration we're using as well."
                      :return Greeting
                      :query-params [name :- s/Str]
                      (ok {:hello name :with-db db}))

                (route/not-found (not-found {:error "Page not found."})))))

(defrecord Api
  [port env db logger]
  component/Lifecycle

  (start [{:keys [connection] :as component}]
    (if connection
      component
      (do (log/info "Starting Api at port" port "with env" env)
          (let [application (app db)
                handler (if (= env :dev) (wrap-reload application) application)
                conn (http/start-server handler {:port port :join? false})]
            (assoc component :connection conn)))))

  (stop [{:keys [connection] :as component}]
    (if-not connection
      component
      (do (log/info "Stopping Api")
          (.close connection)
          (assoc component :connection nil)))))

(defn new-api [port env]
  (->Api port env nil nil))

我已经尝试禁用 AOT 编译,因为这似乎是正常编译和构建 uberjar 之间的主要区别,但没有骰子。我还在 Schema 源代码中查找了 'missing-required-key' 键,并确保它被正确引用,它似乎是,因为如果我更改它,Schema 的测试开始失败。

与正常编译相比,创建uberjar时的编译过程还有什么不同?还有什么我可以尝试的吗?

【问题讨论】:

    标签: clojure compilation leiningen uberjar


    【解决方案1】:

    我以前从未见过该错误(我们使用架构和 uberjar 部署所有服务)。看起来第 21 行是 swagger-docs 中间件;您可以尝试删除它,看看是否可以解决问题?

    【讨论】:

    • 感谢您的提示!删除第 21/22 行确实解决了这个问题。现在我需要弄清楚为什么大摇大摆让它失败了......是什么让你怀疑这是问题所在?
    【解决方案2】:

    我确实对您使用:refer :all 做出了反应,最好使用:refer [list of symbols used in code]。这可能不是这里的错误,但它使那些对库不太了解的人更容易深入研究代码。

    我查看了compojure.api.sweet-命名空间,发现 Zach Tellmans Potemkin 用于将来自不同命名空间的所有函数“导入”到您的命名空间 service.api。也许这会在创建 jar 时出现问题。

    您能否尝试通过将这一行添加到 require 中来从其原始命名空间中 require swagger-uiswagger-docs

    [compojure.api.swagger swagger-ui swagger-docs]

    如果这不起作用但至少给出另一个错误消息(也许)尝试require所有其他明确使用的符号。

    【讨论】:

    • 我对@9​​87654330@ 的了解越多,我就越不了解它是如何评估其路由表的,调试这应该是一场噩梦。我实际上建议使用另一个更明确的库来促进 Swagger。
    • 感谢您的详细回复。我尝试了您的建议,明确提及所有内容,但我仍然收到相同的错误消息。那么这里的问题可能是我正在使用的不同库之间的命名空间冲突吗?
    • 我认为这两个嵌套宏存在一些冲突。也许macroexpand 看看结果表达式是否编译...
    【解决方案3】:

    我不确定这是否会有所帮助,但请尝试运行 lein deps :tree 并查看传递依赖项是什么。可能是多个库依赖于同一依赖项的不同、不兼容的版本。我以前遇到过这种情况,但我不知道为什么它只会在打包在 uberjar 中时发生。

    【讨论】:

      【解决方案4】:

      根本原因是swagger-docs-route 给出了无效输入(没有给出:version,参见https://github.com/metosin/ring-swagger/blob/master/src/ring/swagger/swagger2_schema.clj#L13)。添加后,它按预期工作。

      不过,给定的异常确实很糟糕,现在在最新的 SNAPSHOT 中得到了修复 - 对缺失的字段使用默认值,因此不会对其进行编译时架构检查。

      另外,建议不要对整个应用进行 AOT。见https://github.com/metosin/compojure-api/issues/129

      【讨论】:

        猜你喜欢
        • 2019-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-30
        • 2015-02-07
        • 2017-03-23
        • 2018-09-18
        相关资源
        最近更新 更多