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.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.