1

Using lein-ring plugin, I attempt to pass a configurator function to the ring jetty adapter. The minimal project.clj which reproduces the problem, and which is inspired by this SO answer, is:

(defproject sample "0.1.0-SNAPSHOT"
  :min-lein-version "2.0.0"
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [ring/ring-defaults "0.1.2"]]
  :plugins [[lein-ring "0.9.7"]]
  :ring {:handler sample.handler/app
         :adapter {:configurator ~#(println (.getClass %))}}) ; whatever...

The problem with this, is that it fails with a following error:

$ lein ring server-headless
Exception in thread "main" java.lang.RuntimeException: No reader function for tag object, ...
...

Declaring a function with fn form or defn separately doesn't impact the outcome. Now I realize this is probably not related to lein-ring itself, but I only reproduced the problem on a :configurator (that is, for example, calling a function to set a project description works fine).

I would like to understand, why this is happening (and understand the error message itself first of all), and, in the end, how to actually pass a configurator function when using lein-ring plugin.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Tim
  • 12,318
  • 7
  • 50
  • 72
  • why use ~#(....) instead of just #(...)? – Tim X Oct 17 '15 at 01:34
  • I understood from the other SO answer (http://stackoverflow.com/questions/10289617/clojure-ring-jetty-i-am-using-lein-ring-server-how-do-i-configure-the-jetty) that values under `defproject` are not evaluated, and they need to be unquoted for that. Simply put, if I leave `#(...)` - reader macro expands to `(fn ...)` list, but no evaluation happens, and I get a "PersistentList cannot be cast to IFn" error. So as far as I understand, when unquoted, the `(fn ...)` form should actually evaluate and the defined function is supposed to be the result associated with the `:configurator` – Tim Oct 18 '15 at 09:39
  • OK, now I understand. I would try your solution with a 'real' anonymous function rather than the short-hand version i.e. try ~(fn [x] (println (.getClass x))) and see if that works. My guess is that the environment where defproject is being parsed does not include the tag for the shorthand anonymous function definition – Tim X Oct 19 '15 at 02:16
  • Yes, tried that. As mentioned, using `fn` or also declaring the function outside of the `defproject` with `defn` doesn't change anything - same error is raised. – Tim Oct 19 '15 at 07:47
  • Sorry, missed that. One thing you could try is add org.clojure/tools.reader to your dependencies. I don't think it will fix the problem, but it might provide additional error/debug info. My guess is that for some reason, the reader is not able to interpret a token/tag when parsing the input. However, it isn't clear what item is causing this, so additional backtrace info might help identify what it is the reader doesn't understand – Tim X Oct 20 '15 at 21:20

0 Answers0