Stephen Cagle
Stephen Cagle

Reputation: 14524

java.lang.IllegalArgumentException: No implementation of method: :route-matches of protocol: #'clout.core/Route

I have two files of interest: build.boot

(set-env!
 :source-paths #{"src/clj" "src/cljs" "test/clj"}
 :resource-paths #{"html" "target/main.js"}
 :dependencies '[[adzerk/boot-cljs      "0.0-3308-0"]
                 [adzerk/boot-cljs-repl "0.1.10-SNAPSHOT"]
                 [adzerk/boot-reload    "0.3.1"]
                 [adzerk/boot-test "1.0.4"]
                 [cljsjs/hammer "2.0.4-4"]
                 [compojure "1.3.1"]
                 [com.datomic/datomic-pro "0.9.5186"]
                 [hiccup "1.0.5"]
                 [org.clojure/clojure "1.7.0-RC1"]
                 [org.clojure/clojurescript "0.0-3308"]
                 [org.clojure/core.async "0.1.346.0-17112a-alpha"]
                 [org.clojure/test.check "0.7.0"]
                 [org.omcljs/om "0.8.8"]
                 [pandeiro/boot-http "0.6.3-SNAPSHOT"]
                 [ring/ring-devel "1.4.0-RC1"]
                 [http-kit "2.1.18"]])

(require
 '[adzerk.boot-cljs      :refer [cljs]]
 '[adzerk.boot-cljs-repl :refer [cljs-repl start-repl]]
 '[adzerk.boot-reload    :refer [reload]]
 '[adzerk.boot-test      :refer [test]]
 '[pandeiro.boot-http    :refer [serve]])

(task-options!
 cljs {:source-map true
       :optimizations :none
       :pretty-print true})

(deftask build
  "Build an uberjar of this project that can be run with java -jar"
  []
  (comp
   (cljs)
   (aot :namespace '#{vidiot.server})
   (pom :project 'vidiot
        :version "0.1.0")
   (uber)
   (jar :main 'vidiot.server)))

and src/clj/vidiot/server.clj

(ns vidiot.server
  (:gen-class)
  (:require
   [compojure.core :refer :all]
   [compojure.route :as route]
   [hiccup.core :refer :all]
   [org.httpkit.server :refer :all]
   [ring.middleware.reload :as reload]
   [ring.util.response :as response]))

(defonce server (atom nil))

(defroutes all-routes

  (GET "/" [] (response/redirect "index.html"))

  (GET "/ws" [request]
       (with-channel request channel
         (on-close
          channel
          (fn [status]
            (println "channel closed: " status)))

         (on-receive
          channel
          (fn [data] ;; echo it back
            (send! channel data)))))

  (route/files "/" {:root "target"})

  (route/not-found (response/response (html [:div#erro "Page Not Found"]))))

(defn -main [& args]
  (run-server all-routes {:port 8080}))

Then I,

 > boot build
 > java -jar target/vidiot-0.1.0.jar

Followed by going to localhost:9090 in my browser, the terminal prints.

java.lang.IllegalArgumentException: No implementation of method: :route-matches of protocol: #'clout.core/Route found for class: clout.core.CompiledRoute
    at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:554)
    at clout.core$eval5590$fn__5591$G__5581__5598.invoke(core.clj:39)
    at compojure.core$if_route$fn__5887.invoke(core.clj:40)
    at compojure.core$if_method$fn__5879.invoke(core.clj:27)
    at compojure.core$routing$fn__5918.invoke(core.clj:127)
    at clojure.core$some.invoke(core.clj:2568)
    at compojure.core$routing.doInvoke(core.clj:127)
    at clojure.lang.RestFn.applyTo(RestFn.java:139)
    at clojure.core$apply.invoke(core.clj:630)
    at compojure.core$routes$fn__5922.invoke(core.clj:132)
    at org.httpkit.server.HttpHandler.run(RingHandler.java:91)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

I can fix this issue by downgrading :dependencies in build.boot to [compojure "1.1.6"].

So, my question is, why can't I use [compojure "1.3.4"] (the most recent version at this writing) when building my uberjar?

Upvotes: 5

Views: 1805

Answers (2)

Lucas
Lucas

Reputation: 11

I was able to fix this by adding an exclude for the clout folder. It looks like uberjar is unpacking some compiled clout files on top of those compiled from project source. Example from my project:

     (comp (cljs :compiler-options {:output-to "js/main.js"})
           (aot :namespace '#{zoondka-maps.server zoondka-maps.handler})
           (pom :project (symbol (:name project))
                :version (:version project))
           (uber :exclude (conj pod/standard-jar-exclusions #".*\.html" #"clout/.*"))
           (jar :file (str (:name project) ".jar")
                :main 'zoondka-maps.server)))

Upvotes: 1

user771505
user771505

Reputation:

Placing aot task after uber fixes the issue.

(task-options! pom {:project 'my-project
                    :version "0.1.0"}
               jar {:main 'my-project.core}
               aot {:namespace '#{my-project.core}})

(deftask build []
  (comp (pom)
        (uber)
        (aot)
        (jar)))

Upvotes: 3

Related Questions