2

我正在尝试将 clojure 库集成与基座一起使用,但我在编译时遇到了一个奇怪的错误

                                       java.lang.Thread.run                  Thread.java:  748
         java.util.concurrent.ThreadPoolExecutor$Worker.run      ThreadPoolExecutor.java:  624
          java.util.concurrent.ThreadPoolExecutor.runWorker      ThreadPoolExecutor.java: 1149
                        java.util.concurrent.FutureTask.run              FutureTask.java:  266
                                                        ...                                   
                        clojure.core/binding-conveyor-fn/fn                     core.clj: 2030
                                          boot.core/boot/fn                     core.clj: 1031
                                        boot.core/run-tasks                     core.clj: 1022
                       boot.task.built-in/eval2946/fn/fn/fn                 built_in.clj:  804
                                          boot.pod/eval-in*                      pod.clj:  471
                                                        ...                                   
org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke  ClojureRuntimeShimImpl.java:   97
org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke  ClojureRuntimeShimImpl.java:  104
                                                        ...                                   
                                          boot.pod/eval-in*                      pod.clj:  468
                                          clojure.core/eval                     core.clj: 3214
                                                        ...                                   
                                         pod$eval158.invoke                NO_SOURCE_FILE     
                                   pod$eval158.invokeStatic                NO_SOURCE_FILE     
                                       clojure.core/compile                     core.clj: 6136
                                    clojure.core/compile/fn                     core.clj: 6136
                                      clojure.core/load-one                     core.clj: 5908
                                                        ...                                   
                                          clojure.core/load                     core.clj: 6109
                                          clojure.core/load                     core.clj: 6125
                                       clojure.core/load/fn                     core.clj: 6126
                                                        ...                                   
                                        integrant.core/init                    core.cljc:  415
                                        integrant.core/init                    core.cljc:  418
                                       integrant.core/build                    core.cljc:  321
                                        clojure.core/reduce                     core.clj: 6828
                                clojure.core.protocols/fn/G                protocols.clj:   13
                                  clojure.core.protocols/fn                protocols.clj:   75
                          clojure.core.protocols/seq-reduce                protocols.clj:   31
                                clojure.core.protocols/fn/G                protocols.clj:   19
                                  clojure.core.protocols/fn                protocols.clj:  168
                                    clojure.core/partial/fn                     core.clj: 2632
                                   integrant.core/build-key                    core.cljc:  300
                            integrant.core/try-build-action                    core.cljc:  292
                                                        ...                                   
                                       redblackrose.core/fn                     core.clj:  145
                                    redblackrose.core/start                     core.clj:  136
                             io.pedestal.http/create-server                     http.clj:  374
                             io.pedestal.http/create-server                     http.clj:  377
                                    io.pedestal.http/server                     http.clj:  348
                                                        ...                                   
                              io.pedestal.http.jetty/server                    jetty.clj:  223
                       io.pedestal.http.jetty/create-server                    jetty.clj:  185
           java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number
             clojure.lang.ExceptionInfo: Error on key :adapter/jetty when building system
    data: {#object[clojure.lang.Keyword 0x2f85ee14 ":reason"] #object[clojure.lang.Keyword 0x78b8af86 ":integrant.core/build-threw-exception"], #object[clojure.lang.Keyword 0x348f1abf ":system"] {}, #object[clojure.lang.Keyword 0x748df981 ":function"] #object[clojure.lang.MultiFn 0x75c8d8e7 "clojure.lang.MultiFn@75c8d8e7"], #object[clojure.lang.Keyword 0x3681c4b9 ":key"] #object[clojure.lang.Keyword 0xa9c9cbe ":adapter/jetty"], #object[clojure.lang.Keyword 0x64607768 ":value"] {#object[clojure.lang.Keyword 0x1c29dad6 ":port"] 3000}}
clojure.lang.Compiler$CompilerException: Syntax error macroexpanding at (core.clj:148:3).
    data: {#object[clojure.lang.Keyword 0x7112fa5 ":clojure.error/phase"] #object[clojure.lang.Keyword 0x342dc040 ":execution"], #object[clojure.lang.Keyword 0x3a8ead9 ":clojure.error/line"] 148, #object[clojure.lang.Keyword 0x281ca256 ":clojure.error/column"] 3, #object[clojure.lang.Keyword 0x26feccf7 ":clojure.error/source"] "core.clj"}
             clojure.lang.ExceptionInfo: Syntax error macroexpanding at (core.clj:148:3).
    line: 80

redblackrose.core 文件是

(ns redblackrose.core
  (:gen-class)
  (:require [io.pedestal.http :as server]
            [clojure.core.async :as a]
            [clojure.java.io :as io]
            [integrant.core :as ig]
            [io.pedestal.http :as server]
            [reitit.coercion.spec]
            [reitit.dev.pretty :as pretty]
            [reitit.http :as http]
            [reitit.http.coercion :as coercion]
            [reitit.http.interceptors.dev :as dev]
            [reitit.http.interceptors.exception :as exception]
            [reitit.http.interceptors.multipart :as multipart]
            [reitit.http.interceptors.muuntaja :as muuntaja]
            [reitit.http.interceptors.parameters :as parameters]
            [reitit.http.spec :as spec]
            [reitit.pedestal :as pedestal]
            [reitit.ring :as ring]
            [reitit.swagger :as swagger]
            [reitit.swagger-ui :as swagger-ui]
            [spec-tools.spell :as spell]
            [muuntaja.core :as m]))

(defn interceptor [number]
  {:enter (fn [ctx] (a/go (update-in ctx [:request :number] (fnil + 0) number)))})

(def router
  (pedestal/routing-interceptor
   (http/router
    [["/swagger.json"
      {:get {:no-doc true
             :swagger {:info {:title "my-api"
                              :description "with pedestal & reitit-http"}}
             :handler (swagger/create-swagger-handler)}}]

     ["/interceptors"
      {:swagger {:tags ["interceptors"]}
       :interceptors [(interceptor 1)]}

      ["/number"
       {:interceptors [(interceptor 10)]
        :get {:interceptors [(interceptor 100)]
              :handler (fn [req]
                         {:status 200
                          :body (select-keys req [:number])})}}]]

     ["/files"
      {:swagger {:tags ["files"]}}

      ["/upload"
       {:post {:summary "upload a file"
               :parameters {:multipart {:file multipart/temp-file-part}}
               :responses {200 {:body {:name string?, :size int?}}}
               :handler (fn [{{{:keys [file]} :multipart} :parameters}]
                          {:status 200
                           :body {:name (:filename file)
                                  :size (:size file)}})}}]

      ["/download"
       {:get {:summary "downloads a file"
              :swagger {:produces ["image/png"]}
              :handler (fn [_]
                         {:status 200
                          :headers {"Content-Type" "image/png"}
                          :body (io/input-stream
                                 (io/resource "reitit.png"))})}}]]

     ["/math"
      {:swagger {:tags ["math"]}}

      ["/plus"
       {:get {:summary "plus with spec query parameters"
              :parameters {:query {:x int?, :y int?}}
              :responses {200 {:body {:total int?}}}
              :handler (fn [{{{:keys [x y]} :query} :parameters}]
                         {:status 200
                          :body {:total (+ x y)}})}
        :post {:summary "plus with spec body parameters"
               :parameters {:body {:x int?, :y int?}}
               :responses {200 {:body {:total int?}}}
               :handler (fn [{{{:keys [x y]} :body} :parameters}]
                          {:status 200
                           :body {:total (+ x y)}})}}]]]

    {:reitit.interceptor/transform dev/print-context-diffs ;; pretty context diffs
     :validate spec/validate ;; enable spec validation for route data
     :reitit.spec/wrap spell/closed ;; strict top-level validation
     :exception pretty/exception
     :data {:coercion reitit.coercion.spec/coercion
            :muuntaja m/instance
            :interceptors [;; swagger feature
                           swagger/swagger-feature
                           ;; query-params & form-params
                           (parameters/parameters-interceptor)
                           ;; content-negotiation
                           (muuntaja/format-negotiate-interceptor)
                           ;; encoding response body
                           (muuntaja/format-response-interceptor)
                           ;; exception handling
                           (exception/exception-interceptor)
                           ;; decoding request body
                           (muuntaja/format-request-interceptor)
                           ;; coercing response bodys
                           (coercion/coerce-response-interceptor)
                           ;; coercing request parameters
                           (coercion/coerce-request-interceptor)
                           ;; multipart
                           (multipart/multipart-interceptor)]}})

   ;; optional default ring handler (if no routes have matched)
   (ring/routes
    (swagger-ui/create-swagger-ui-handler
     {:path "/"
      :config {:validatorUrl nil
               :operationsSorter "alpha"}})
    (ring/create-resource-handler)
    (ring/create-default-handler))))

(defn start [port]
  (-> {:env :dev
       ::server/type :jetty
       ::server/port port
       ::server/join? false
       ;; no pedestal routes
       ::server/routes []
       ;; allow serving the swagger-ui styles & scripts from self
       ::server/secure-headers {:content-security-policy-settings
                                {:default-src "'self'"
                                 :style-src "'self' 'unsafe-inline'"
                                 :script-src "'self' 'unsafe-inline'"}}}
      (server/default-interceptors)
      ;; use the reitit router
      (pedestal/replace-last-interceptor router)
      (server/dev-interceptors)
      (server/create-server)
      (server/start))
  (println "server running in port 3000"))


(def config
  {:adapter/jetty {:port 3000}})

(defmethod ig/init-key :adapter/jetty [_ {:keys [handler] :as opts}]
  (start [opts]))

(def system
  (ig/init config))

(defn -main [& args]
  (system))

我知道这个例子看起来几乎没用(只有一个集成的“组件”),但我只是为一个更复杂的项目(也需要数据库访问)设置框架。

4

0 回答 0