Question

Running Leiningen 2.3.4 on Java 1.7.0_21 Java HotSpot(TM) 64-Bit Server VM

I am having trouble connecting to an nREPL server.

I setup a new project using lein new luminus, and then added a dependency to drawbridge ([com.cemerick/drawbridge "0.0.6"]).

I added a handler route for the repl as follows (based on https://devcenter.heroku.com/articles/debugging-clojure):

(def drawbridge-handler
  (-> (cemerick.drawbridge/ring-handler)
      (wrap-keyword-params)
      (wrap-nested-params)
      (wrap-params)
      (wrap-session)))

(defn wrap-drawbridge [handler]
  (fn [req]
    (if (= "/repl" (:uri req))
      (drawbridge-handler req)
      (handler req))))

And added wrap-drawbridge to my middlewares.

I then start the server using

lein ring server-headless

The connection seems to be working well because performing a GET request on http:localhost:3000/repl yields a response: ["[\n","\n]"]

But I can't connect to the REPL:

> lein repl :connect 0.0.0.0:3000/repl
Connecting to nREPL at 0.0.0.0:3000/repl

And, after some time:

SocketException The transport's socket appears to have lost its connection to the nREPL server
    clojure.tools.nrepl.transport/bencode/fn--4287/fn--4288 (transport.clj:95)
    clojure.tools.nrepl.transport/bencode/fn--4287 (transport.clj:95)
    clojure.tools.nrepl.transport/fn-transport/fn--4261 (transport.clj:42)
    clojure.core/binding-conveyor-fn/fn--4107 (core.clj:1836)
    java.util.concurrent.FutureTask$Sync.innerRun (FutureTask.java:334)
    java.util.concurrent.FutureTask.run (FutureTask.java:166)
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:615)
    java.lang.Thread.run (Thread.java:722)
Bye for now!

Am I missing something?

Edit:

Added the following logging code to my handler:

(defn wrap-drawbridge [handler]
  (fn [req]
    (if (= "/repl" (:uri req))
      (do (println "IN REPL ")
        (drawbridge-handler req))
      (handler req))))

When connecting with lein repl :connect http://localhost:3000/repl as suggested, I see the line IN REPL being printed in an infinite loop, on the servers console.

Was it helpful?

Solution

Not really a direct answer, but I've found that I was not approaching this problem the right way.

Luminus creates a project-name.repl namespace that should be used for interactive development.

I found that I could do what I wanted by adding to my project.clj

:repl-options {
                  :init-ns project-name.repl
                  :init (start-server)}

And then simply starting the server with lein repl.

Much simpler than setting up an nREPL middleware!

OTHER TIPS

Have you made sure that there actually is a request entering your server (e.g. by printlining)?

However, my first guess would be that lein repl :connect behaves differently depending on whether you pass it an IP/Port pair or a fully-qualified URL. Since drawbridge seems to make nREPL accessible via HTTP I'd suggest you try:

lein repl :connect http://localhost:3000/repl

You need to add wrap-drawbridge at the first place in you middleware list.

If you do something like that

(def app (-> #'all-routes
               wrap-drawbridge
               ...
               ...
               ...
               ))

It works like a charm.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top