Different behavior between Clojure REPL and regualr lein repl in Cursive - unsatisfied protocols

Hi!

I’ve run into unexpected issue when working with protocols. This seems to be related directly to IntelliJ Cursive (but I don’t think it’s really doing anything special). See example code:

(ns data-engine.plugins.core
  "Core for plugin subsytem."
  (:require [data-engine.plugins.nodejs-api :as nodejs]
            [clojure.spec.alpha :as spec]
            [me.raynes.fs :as fs]
            [clojure.java.io :as io]
            [environ.core :refer [env]]))

(defprotocol Plugin
  (get-config [plugin] "Get plugin configuration")
  (get-methods [plugin] "Get plugin methods")
  (call-method [plugin method config options] "Call plugin option"))


(defrecord NodejsPlugin [id name description major minor plugin-file]
  Plugin
  (get-config [_] (nodejs/get-config plugin-file))
  (get-methods [_] (nodejs/get-methods plugin-file))
  (call-method [_ method config options] (nodejs/call-method plugin-file method config options)))

I also have two targets:

Seems pretty straightforward. Let’s run lein clean followed by firing up repl target (Clojure REPL) in debug mode and try:

(type (first (doall (map map->NodejsPlugin (nodejs/list-plugins (env :plugins-dir))))))
=> data-engine.plugins.core.NodejsPlugin
(first (doall (map map->NodejsPlugin (nodejs/list-plugins (env :plugins-dir)))))
=> #data-engine.plugins.core.NodejsPlugin{:id "foo",
                                       :name "foo",
                                       :description "Legacy plugin foo",
                                       :major 0,
                                       :minor 1,
                                       :plugin-file #object[java.io.File
                                                            0x1bd23317
                                                            "foo"]}

(extends? Plugin NodejsPlugin)
=> true
(satisfies? Plugin (first (doall (map map->NodejsPlugin (nodejs/list-plugins (env :plugins-dir))))))
=> false

Huh? Why it does not satisfies Plugin protocol? And here comes another surprise. Try lein clean followed by starting „leiningen” repl target.

(type (first (doall (map map->NodejsPlugin (nodejs/list-plugins (env :plugins-dir))))))
=> data-engine.plugins.core.NodejsPlugin
(first (doall (map map->NodejsPlugin (nodejs/list-plugins (env :plugins-dir)))))
=> #data-engine.plugins.core.NodejsPlugin{:id "foo",
                                       :name "foo",
                                       :description "Legacy plugin foo",
                                       :major 0,
                                       :minor 1,
                                       :plugin-file #object[java.io.File
                                                            0x3686129e
                                                            "foo"]}
 (extends? Plugin NodejsPlugin)
=> true
 (satisfies? Plugin (first (doall (map map->NodejsPlugin (nodejs/list-plugins (env :plugins-dir))))))
=> true

Why does Clojure REPL differs from lein repl? Also, stopping Clojure REPL and starting it again does resolve the issue, until next lein clean. I am out of ideas and this is really annoing.

1 Like

Do you require the namespaces in both cases?

Also, can you try not in debug mode? I’m not sure what debug mode does.