greglook / whidbey

nREPL middleware to pretty-print colored values
The Unlicense
158 stars 10 forks source link

Bad interaction with Virgil #25

Closed miikka closed 7 years ago

miikka commented 7 years ago

I tried to use both Whidbey and Virgil in the same project. This is what happens:

% lein repl
Compiling 1 source files to /Users/miikka/mess/2017-01/wbtest/target/classes

recompiling all files in /Users/miikka/mess/2017-01/wbtest/java-src
nREPL server started on port 62774 on host 127.0.0.1 - nrepl://127.0.0.1:62774
ERROR: Unhandled REPL handler exception processing message {:id 05d8761b-08a8-4853-8dbd-803a608934a6, :op clone}
java.lang.ClassCastException: clojure.tools.nrepl.transport.FnTransport cannot be cast to clojure.tools.nrepl.transport.Transport
    at clojure.tools.nrepl.middleware.render_values$wrap_renderer$reify__2794.send(render_values.clj:24)
    at clojure.tools.nrepl.middleware.session$register_session.invokeStatic(session.clj:144)
    at clojure.tools.nrepl.middleware.session$register_session.invoke(session.clj:137)
    at clojure.tools.nrepl.middleware.session$session$fn__3195.invoke(session.clj:188)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__424.invoke(middleware.clj:22)
    at clojure.tools.nrepl.middleware.render_values$render_values$fn__2800.invoke(render_values.clj:42)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__424.invoke(middleware.clj:22)
    at clojure.tools.nrepl.middleware.load_file$wrap_load_file$fn__4679.invoke(load_file.clj:79)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__424.invoke(middleware.clj:22)
    at clojure.tools.nrepl.server$handle_STAR_.invokeStatic(server.clj:19)
    at clojure.tools.nrepl.server$handle_STAR_.invoke(server.clj:16)
    at clojure.tools.nrepl.server$handle$fn__3285.invoke(server.clj:28)
    at clojure.core$binding_conveyor_fn$fn__4676.invoke(core.clj:1938)
    at clojure.lang.AFn.call(AFn.java:18)
    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 don't know if the problem is in Whidbey, in Virgil, or somewhere else. I'm opening the issue here, because the stacktrace points towards the direction of Whidbey.

Here's a repo for reproducing the problem: https://github.com/miikka/whidbey-virgil-problem. If you remove either Virgil or Whidbey from the plugin list, the REPL opens just fine. I'm using Whidbey 1.3.1, Virgil 0.1.5, Clojure 1.8.0, Leiningen 2.7.1 on Java 1.8.0_66.

greglook commented 7 years ago

Hmm, I'm not familiar with Virgil. I'll take a look, but at a first pass it seems like both plugins want to wrap the nrepl middleware and some sort of conflict is happening.

greglook commented 7 years ago

Actually, Virgil doesn't inherently touch anything in nrepl, so maybe the recompiling is somehow changing the nrepl function so it's not implementing the right interface anymore.

miikka commented 7 years ago

Okay, I think I know what's happening. Virgil reloads all the namespaces whenever it (re)compiles Java and it does it in an arbitrary order. First it reloads clojure.tools.nrepl.middleware.render-values which uses the old definition of Transport and then it reloads clojure.tools.nrepl.transport, which creates a new definition for Transport.

I assume a solution would be to make Virgil reload the namespaces in the dependency order – I'll open an issue there to discuss this further.

greglook commented 7 years ago

Ah, yeah the arbitrary ordering would be an issue for the reason you described. You can take a look at clojure.tools.namespace for the correct way to do dependency-ordered reloading.