I fail to inject nrepl middleware from the command line #10

Closed
opened 2022-08-27 19:44:51 +00:00 by PEZ · 8 comments

I am trying to inject shadow-cljs nrepl middleware from the command line. (I need this for Calva jack-in/connect). I'm sorry if this is not a particularly minimal repro, but I really don't know how to minimize it further. Mostly because I don't understand the issue enough.

I'm not even sure my expectations are valid.

Reproduction

My reproduction is using this tiny project and assumes node is installed: https://github.com/PEZ/shadow-w-backend

Steps:

  1. Install npm dependencies:
    npm install
    
  2. Start the Clojure REPL and the nREPL server, injecting cider dependencies + cider and shadow nrepl middleware:
    lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :dependencies conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- update-in '[:repl-options,:nrepl-middleware]' conj '[cider.nrepl/cider-middleware,shadow.cljs.devtools.server.nrepl/middleware]' -- repl :headless
    
  3. Connect to the nREPL server:
    lein repl :connect
    
  4. Start shadow-cljs server and an :app watcher
    (do (require 'shadow.cljs.devtools.server) (shadow.cljs.devtools.server/start!) (require 'shadow.cljs.devtools.api) (shadow.cljs.devtools.api/watch :app))
    
  5. Start the ClojureScript REPL and attach to it:
    (do (require 'shadow.cljs.devtools.api) (shadow.cljs.devtools.api/nrepl-select :app))
    

Now what is expected is to get output like this:

[:selected :app]

Instead I get:

:missing-nrepl-middleware

Notes

  • This works if I add the shadow nrepl middleware in project.clj
  • I get errors if I add the cider nrepl middleware in project.clj
    [WARNING] No nREPL middleware descriptor in metadata of #'cider.nrepl/cider-middleware, see nrepl.middleware/set-descriptor!
    Execution error (IllegalArgumentException) at nrepl.middleware.dynamic-loader/update-stack!$fn (dynamic_loader.clj:40).
    Key must be integer
    

So my expectations here are that command line injections should be applied after the configuration is read from project.clj, and that it should be full equivalency if I configure both these middlewares either on the command line or in project.clj. Are these expectations reasonable?

I am trying to inject shadow-cljs nrepl middleware from the command line. (I need this for Calva jack-in/connect). I'm sorry if this is not a particularly minimal repro, but I really don't know how to minimize it further. Mostly because I don't understand the issue enough. I'm not even sure my expectations are valid. ## Reproduction My reproduction is using this tiny project and assumes node is installed: https://github.com/PEZ/shadow-w-backend Steps: 1. Install npm dependencies: ``` npm install ``` 2. Start the Clojure REPL and the nREPL server, injecting cider dependencies + cider and shadow nrepl middleware: ``` lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :dependencies conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- update-in '[:repl-options,:nrepl-middleware]' conj '[cider.nrepl/cider-middleware,shadow.cljs.devtools.server.nrepl/middleware]' -- repl :headless ``` 3. Connect to the nREPL server: ``` lein repl :connect ``` 4. Start shadow-cljs server and an `:app` watcher ``` (do (require 'shadow.cljs.devtools.server) (shadow.cljs.devtools.server/start!) (require 'shadow.cljs.devtools.api) (shadow.cljs.devtools.api/watch :app)) ``` 5. Start the ClojureScript REPL and attach to it: ``` (do (require 'shadow.cljs.devtools.api) (shadow.cljs.devtools.api/nrepl-select :app)) ``` Now what is expected is to get output like this: ``` [:selected :app] ``` Instead I get: ``` :missing-nrepl-middleware ``` ## Notes * This works if I add the shadow nrepl middleware in `project.clj` * I get errors if I add the cider nrepl middleware in `project.clj` ``` [WARNING] No nREPL middleware descriptor in metadata of #'cider.nrepl/cider-middleware, see nrepl.middleware/set-descriptor! Execution error (IllegalArgumentException) at nrepl.middleware.dynamic-loader/update-stack!$fn (dynamic_loader.clj:40). Key must be integer ``` So my expectations here are that command line injections should be applied after the configuration is read from `project.clj`, and that it should be full equivalency if I configure both these middlewares either on the command line or in `project.clj`. Are these expectations reasonable?

I guess this is difficult because there are a lot of moving parts, so let's try to break it down a bit. Middleware is one of the most unreliable things because of how many plugins try to activate it implicitly.

So maybe by identifying the individual steps we can break down the problem.

  • First, the update-in command makes a series of changes to the project map
  • Then it loads the plugins and activates their middleware
  • Then it runs the repl command, which merges in the repl profile before starting the server

Does it look like the middleware is active before the repl command runs? If you replace the repl task with pprint (using the lein-pprint plugin) you may be able to debug to see if the problem is happening upstream of that task.

If this is a new issue in 2.9.9 or 2.9.10 it may be that the fix for #5 is responsible for this breaking, although I think that should only affect composite profiles, so it seems unlikely. But it would be helpful to know.

I guess this is difficult because there are a lot of moving parts, so let's try to break it down a bit. Middleware is one of the most unreliable things because of how many plugins try to activate it implicitly. So maybe by identifying the individual steps we can break down the problem. * First, the update-in command makes a series of changes to the project map * Then it loads the plugins and activates their middleware * Then it runs the repl command, which merges in the repl profile before starting the server Does it look like the middleware is active before the repl command runs? If you replace the repl task with pprint (using the lein-pprint plugin) you may be able to debug to see if the problem is happening upstream of that task. If this is a new issue in 2.9.9 or 2.9.10 it may be that the fix for https://codeberg.org/leiningen/leiningen/issues/5 is responsible for this breaking, although I think that should only affect composite profiles, so it seems unlikely. But it would be helpful to know.

I'll try to debug a bit using those hints. Thanks!

If this is a new issue in 2.9.9 or 2.9.10 it may be that the fix for #5 is responsible for this breaking, although I think that should only affect composite profiles, so it seems unlikely. But it would be helpful to know.

That I have tried. I had a pretty old version on another machine of mine and it was the same there.

I'll try to debug a bit using those hints. Thanks! > If this is a new issue in 2.9.9 or 2.9.10 it may be that the fix for #5 is responsible for this breaking, although I think that should only affect composite profiles, so it seems unlikely. But it would be helpful to know. That I have tried. I had a pretty old version on another machine of mine and it was the same there.

pprint does seem to tell me something, even though I'm not savvy enough to interpret the message, so I'll paste the whole output to avoid deleting some clue:

$ lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :dependencies conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :plugins conj '[lein-pprint,"1.3.2"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- update-in '[:repl-options,:nrepl-middleware]' conj '[cider.nrepl/cider-middleware,shadow.cljs.devtools.server.nrepl/middleware]' -- pprint
{:description "FIXME: write description",
 :compile-path
 "/Users/pez/Projects/tests/shadow-w-backend/target/default/classes",
 :deploy-repositories
 [["clojars"
   {:url "https://repo.clojars.org/",
    :password :gpg,
    :username :gpg}]],
 :group "lein-app",
 :resource-paths
 ("/Users/pez/Projects/tests/shadow-w-backend/dev-resources"
  "/Users/pez/Projects/tests/shadow-w-backend/resources"),
 :uberjar-merge-with
 {"META-INF/plexus/components.xml" leiningen.uberjar/components-merger,
  "data_readers.clj" leiningen.uberjar/clj-map-merger,
  #"META-INF/services/.*"
  [clojure.core/slurp
   (fn*
    [p1__7737__7739__auto__ p2__7738__7740__auto__]
    (clojure.core/str
     p1__7737__7739__auto__
     "\n"
     p2__7738__7740__auto__))
   clojure.core/spit]},
 :name "lein-app",
 :checkout-deps-shares
 [:source-paths
  :test-paths
  :resource-paths
  :compile-path
  #'leiningen.core.classpath/checkout-deps-paths],
 :source-paths ("/Users/pez/Projects/tests/shadow-w-backend/src"),
 :eval-in :subprocess,
 :repositories
 [["central"
   {:url "https://repo1.maven.org/maven2/", :snapshots false}]
  ["clojars" {:url "https://repo.clojars.org/"}]],
 :test-paths ("/Users/pez/Projects/tests/shadow-w-backend/test"),
 :target-path
 "/Users/pez/Projects/tests/shadow-w-backend/target/default",
 :prep-tasks ["javac" "compile"],
 :native-path
 "/Users/pez/Projects/tests/shadow-w-backend/target/default/native",
 :offline? false,
 :root "/Users/pez/Projects/tests/shadow-w-backend",
 :pedantic? ranges,
 :clean-targets [:target-path],
 :plugins [[lein-pprint "1.3.2"] [cider/cider-nrepl "0.28.5"]],
 :profiles
 {:uberjar
  {:aot [:all], :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}},
 :plugin-repositories
 [["central"
   {:url "https://repo1.maven.org/maven2/", :snapshots false}]
  ["clojars" {:url "https://repo.clojars.org/"}]],
 :aliases {"downgrade" "upgrade"},
 :version "0.1.0-SNAPSHOT",
 :jar-exclusions [#"^\." #"\Q/.\E"],
 :main main.server,
 :global-vars {},
 :repl-options,
 {:nrepl-middleware]
  ([cider.nrepl/cider-middleware
    shadow.cljs.devtools.server.nrepl/middleware])},
 :uberjar-exclusions
 [#"(?i)^META-INF/[^/]*\.(SF|RSA|DSA)$" #"^module-info.class$"],
 :jvm-opts
 ["-XX:-OmitStackTraceInFastThrow"
  "-XX:+TieredCompilation"
  "-XX:TieredStopAtLevel=1"],
 :dependencies
 ([cider/cider-nrepl "0.28.5"]
  [cider/cider-nrepl "0.28.5"]
  [cider/cider-nrepl "0.28.5"]
  [nrepl "1.0.0"]
  [org.clojure/clojure "1.11.1"]
  [org.clojure/clojurescript "1.11.60"]
  [thheller/shadow-cljs "2.19.9"]
  [binaryage/devtools "1.0.6"]
  [reagent/reagent "1.1.1"]
  [nrepl/nrepl "0.9.0" :exclusions ([org.clojure/clojure])]
  [org.nrepl/incomplete "0.1.0" :exclusions ([org.clojure/clojure])]),
 :release-tasks
 [["vcs" "assert-committed"]
  ["change" "version" "leiningen.release/bump-version" "release"]
  ["vcs" "commit"]
  ["vcs" "tag"]
  ["deploy"]
  ["change" "version" "leiningen.release/bump-version"]
  ["vcs" "commit"]
  ["vcs" "push"]],
 :repl-options
 {:nrepl-middleware
  [cider.nrepl/wrap-apropos
   cider.nrepl/wrap-classpath
   cider.nrepl/wrap-clojuredocs
   cider.nrepl/wrap-complete
   cider.nrepl/wrap-content-type
   cider.nrepl/wrap-debug
   cider.nrepl/wrap-enlighten
   cider.nrepl/wrap-format
   cider.nrepl/wrap-info
   cider.nrepl/wrap-inspect
   cider.nrepl/wrap-macroexpand
   cider.nrepl/wrap-ns
   cider.nrepl/wrap-out
   cider.nrepl/wrap-slurp
   cider.nrepl/wrap-profile
   cider.nrepl/wrap-refresh
   cider.nrepl/wrap-resource
   cider.nrepl/wrap-spec
   cider.nrepl/wrap-stacktrace
   cider.nrepl/wrap-test
   cider.nrepl/wrap-trace
   cider.nrepl/wrap-tracker
   cider.nrepl/wrap-undef
   cider.nrepl/wrap-version
   cider.nrepl/wrap-xref
   cider.nrepl/wrap-apropos
   cider.nrepl/wrap-classpath
   cider.nrepl/wrap-clojuredocs
   cider.nrepl/wrap-complete
   cider.nrepl/wrap-content-type
   cider.nrepl/wrap-debug
   cider.nrepl/wrap-enlighten
   cider.nrepl/wrap-format
   cider.nrepl/wrap-info
   cider.nrepl/wrap-inspect
   cider.nrepl/wrap-macroexpand
   cider.nrepl/wrap-ns
   cider.nrepl/wrap-out
   cider.nrepl/wrap-slurp
   cider.nrepl/wrap-profile
   cider.nrepl/wrap-refresh
   cider.nrepl/wrap-resource
   cider.nrepl/wrap-spec
   cider.nrepl/wrap-stacktrace
   cider.nrepl/wrap-test
   cider.nrepl/wrap-trace
   cider.nrepl/wrap-tracker
   cider.nrepl/wrap-undef
   cider.nrepl/wrap-version
   cider.nrepl/wrap-xref]},
 :test-selectors {:default (constantly true)}}

I notice:

  1. [:repl-options :nrepl-middleware] appears twice
  2. the first time it appears it looks broken
  3. in the second apperance any shadow middleware is absent
  4. in the second appearance all entries are appearing twice

If I completely remove the [:repl-options :nrepl-middleware] injection, pprint still reports the last entry. Where the same cider.nrepl middlewares are included, but only once:

lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :dependencies conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :plugins conj '[lein-pprint,"1.3.2"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- pprint
{:description "FIXME: write description",
 :compile-path
 "/Users/pez/Projects/tests/shadow-w-backend/target/default/classes",
 :deploy-repositories
 [["clojars"
   {:url "https://repo.clojars.org/",
    :password :gpg,
    :username :gpg}]],
 :group "lein-app",
 :resource-paths
 ("/Users/pez/Projects/tests/shadow-w-backend/dev-resources"
  "/Users/pez/Projects/tests/shadow-w-backend/resources"),
 :uberjar-merge-with
 {"META-INF/plexus/components.xml" leiningen.uberjar/components-merger,
  "data_readers.clj" leiningen.uberjar/clj-map-merger,
  #"META-INF/services/.*"
  [clojure.core/slurp
   (fn*
    [p1__7737__7739__auto__ p2__7738__7740__auto__]
    (clojure.core/str
     p1__7737__7739__auto__
     "\n"
     p2__7738__7740__auto__))
   clojure.core/spit]},
 :name "lein-app",
 :checkout-deps-shares
 [:source-paths
  :test-paths
  :resource-paths
  :compile-path
  #'leiningen.core.classpath/checkout-deps-paths],
 :source-paths ("/Users/pez/Projects/tests/shadow-w-backend/src"),
 :eval-in :subprocess,
 :repositories
 [["central"
   {:url "https://repo1.maven.org/maven2/", :snapshots false}]
  ["clojars" {:url "https://repo.clojars.org/"}]],
 :test-paths ("/Users/pez/Projects/tests/shadow-w-backend/test"),
 :target-path
 "/Users/pez/Projects/tests/shadow-w-backend/target/default",
 :prep-tasks ["javac" "compile"],
 :native-path
 "/Users/pez/Projects/tests/shadow-w-backend/target/default/native",
 :offline? false,
 :root "/Users/pez/Projects/tests/shadow-w-backend",
 :pedantic? ranges,
 :clean-targets [:target-path],
 :plugins [[lein-pprint "1.3.2"] [cider/cider-nrepl "0.28.5"]],
 :profiles
 {:uberjar
  {:aot [:all], :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}},
 :plugin-repositories
 [["central"
   {:url "https://repo1.maven.org/maven2/", :snapshots false}]
  ["clojars" {:url "https://repo.clojars.org/"}]],
 :aliases {"downgrade" "upgrade"},
 :version "0.1.0-SNAPSHOT",
 :jar-exclusions [#"^\." #"\Q/.\E"],
 :main main.server,
 :global-vars {},
 :uberjar-exclusions
 [#"(?i)^META-INF/[^/]*\.(SF|RSA|DSA)$" #"^module-info.class$"],
 :jvm-opts
 ["-XX:-OmitStackTraceInFastThrow"
  "-XX:+TieredCompilation"
  "-XX:TieredStopAtLevel=1"],
 :dependencies
 ([cider/cider-nrepl "0.28.5"]
  [cider/cider-nrepl "0.28.5"]
  [nrepl "1.0.0"]
  [org.clojure/clojure "1.11.1"]
  [org.clojure/clojurescript "1.11.60"]
  [thheller/shadow-cljs "2.19.9"]
  [binaryage/devtools "1.0.6"]
  [reagent/reagent "1.1.1"]
  [nrepl/nrepl "0.9.0" :exclusions ([org.clojure/clojure])]
  [org.nrepl/incomplete "0.1.0" :exclusions ([org.clojure/clojure])]),
 :release-tasks
 [["vcs" "assert-committed"]
  ["change" "version" "leiningen.release/bump-version" "release"]
  ["vcs" "commit"]
  ["vcs" "tag"]
  ["deploy"]
  ["change" "version" "leiningen.release/bump-version"]
  ["vcs" "commit"]
  ["vcs" "push"]],
 :repl-options
 {:nrepl-middleware
  [cider.nrepl/wrap-apropos
   cider.nrepl/wrap-classpath
   cider.nrepl/wrap-clojuredocs
   cider.nrepl/wrap-complete
   cider.nrepl/wrap-content-type
   cider.nrepl/wrap-debug
   cider.nrepl/wrap-enlighten
   cider.nrepl/wrap-format
   cider.nrepl/wrap-info
   cider.nrepl/wrap-inspect
   cider.nrepl/wrap-macroexpand
   cider.nrepl/wrap-ns
   cider.nrepl/wrap-out
   cider.nrepl/wrap-slurp
   cider.nrepl/wrap-profile
   cider.nrepl/wrap-refresh
   cider.nrepl/wrap-resource
   cider.nrepl/wrap-spec
   cider.nrepl/wrap-stacktrace
   cider.nrepl/wrap-test
   cider.nrepl/wrap-trace
   cider.nrepl/wrap-tracker
   cider.nrepl/wrap-undef
   cider.nrepl/wrap-version
   cider.nrepl/wrap-xref]},
 :test-selectors {:default (constantly true)}}

I tested that Calva works without the [:repl-options :nrepl-middleware] injection, and it works just fine, so maybe the injection has never really worked?

`pprint` does seem to tell me something, even though I'm not savvy enough to interpret the message, so I'll paste the whole output to avoid deleting some clue: ``` $ lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :dependencies conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :plugins conj '[lein-pprint,"1.3.2"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- update-in '[:repl-options,:nrepl-middleware]' conj '[cider.nrepl/cider-middleware,shadow.cljs.devtools.server.nrepl/middleware]' -- pprint {:description "FIXME: write description", :compile-path "/Users/pez/Projects/tests/shadow-w-backend/target/default/classes", :deploy-repositories [["clojars" {:url "https://repo.clojars.org/", :password :gpg, :username :gpg}]], :group "lein-app", :resource-paths ("/Users/pez/Projects/tests/shadow-w-backend/dev-resources" "/Users/pez/Projects/tests/shadow-w-backend/resources"), :uberjar-merge-with {"META-INF/plexus/components.xml" leiningen.uberjar/components-merger, "data_readers.clj" leiningen.uberjar/clj-map-merger, #"META-INF/services/.*" [clojure.core/slurp (fn* [p1__7737__7739__auto__ p2__7738__7740__auto__] (clojure.core/str p1__7737__7739__auto__ "\n" p2__7738__7740__auto__)) clojure.core/spit]}, :name "lein-app", :checkout-deps-shares [:source-paths :test-paths :resource-paths :compile-path #'leiningen.core.classpath/checkout-deps-paths], :source-paths ("/Users/pez/Projects/tests/shadow-w-backend/src"), :eval-in :subprocess, :repositories [["central" {:url "https://repo1.maven.org/maven2/", :snapshots false}] ["clojars" {:url "https://repo.clojars.org/"}]], :test-paths ("/Users/pez/Projects/tests/shadow-w-backend/test"), :target-path "/Users/pez/Projects/tests/shadow-w-backend/target/default", :prep-tasks ["javac" "compile"], :native-path "/Users/pez/Projects/tests/shadow-w-backend/target/default/native", :offline? false, :root "/Users/pez/Projects/tests/shadow-w-backend", :pedantic? ranges, :clean-targets [:target-path], :plugins [[lein-pprint "1.3.2"] [cider/cider-nrepl "0.28.5"]], :profiles {:uberjar {:aot [:all], :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}}, :plugin-repositories [["central" {:url "https://repo1.maven.org/maven2/", :snapshots false}] ["clojars" {:url "https://repo.clojars.org/"}]], :aliases {"downgrade" "upgrade"}, :version "0.1.0-SNAPSHOT", :jar-exclusions [#"^\." #"\Q/.\E"], :main main.server, :global-vars {}, :repl-options, {:nrepl-middleware] ([cider.nrepl/cider-middleware shadow.cljs.devtools.server.nrepl/middleware])}, :uberjar-exclusions [#"(?i)^META-INF/[^/]*\.(SF|RSA|DSA)$" #"^module-info.class$"], :jvm-opts ["-XX:-OmitStackTraceInFastThrow" "-XX:+TieredCompilation" "-XX:TieredStopAtLevel=1"], :dependencies ([cider/cider-nrepl "0.28.5"] [cider/cider-nrepl "0.28.5"] [cider/cider-nrepl "0.28.5"] [nrepl "1.0.0"] [org.clojure/clojure "1.11.1"] [org.clojure/clojurescript "1.11.60"] [thheller/shadow-cljs "2.19.9"] [binaryage/devtools "1.0.6"] [reagent/reagent "1.1.1"] [nrepl/nrepl "0.9.0" :exclusions ([org.clojure/clojure])] [org.nrepl/incomplete "0.1.0" :exclusions ([org.clojure/clojure])]), :release-tasks [["vcs" "assert-committed"] ["change" "version" "leiningen.release/bump-version" "release"] ["vcs" "commit"] ["vcs" "tag"] ["deploy"] ["change" "version" "leiningen.release/bump-version"] ["vcs" "commit"] ["vcs" "push"]], :repl-options {:nrepl-middleware [cider.nrepl/wrap-apropos cider.nrepl/wrap-classpath cider.nrepl/wrap-clojuredocs cider.nrepl/wrap-complete cider.nrepl/wrap-content-type cider.nrepl/wrap-debug cider.nrepl/wrap-enlighten cider.nrepl/wrap-format cider.nrepl/wrap-info cider.nrepl/wrap-inspect cider.nrepl/wrap-macroexpand cider.nrepl/wrap-ns cider.nrepl/wrap-out cider.nrepl/wrap-slurp cider.nrepl/wrap-profile cider.nrepl/wrap-refresh cider.nrepl/wrap-resource cider.nrepl/wrap-spec cider.nrepl/wrap-stacktrace cider.nrepl/wrap-test cider.nrepl/wrap-trace cider.nrepl/wrap-tracker cider.nrepl/wrap-undef cider.nrepl/wrap-version cider.nrepl/wrap-xref cider.nrepl/wrap-apropos cider.nrepl/wrap-classpath cider.nrepl/wrap-clojuredocs cider.nrepl/wrap-complete cider.nrepl/wrap-content-type cider.nrepl/wrap-debug cider.nrepl/wrap-enlighten cider.nrepl/wrap-format cider.nrepl/wrap-info cider.nrepl/wrap-inspect cider.nrepl/wrap-macroexpand cider.nrepl/wrap-ns cider.nrepl/wrap-out cider.nrepl/wrap-slurp cider.nrepl/wrap-profile cider.nrepl/wrap-refresh cider.nrepl/wrap-resource cider.nrepl/wrap-spec cider.nrepl/wrap-stacktrace cider.nrepl/wrap-test cider.nrepl/wrap-trace cider.nrepl/wrap-tracker cider.nrepl/wrap-undef cider.nrepl/wrap-version cider.nrepl/wrap-xref]}, :test-selectors {:default (constantly true)}} ``` I notice: 1. `[:repl-options :nrepl-middleware]` appears twice 1. the first time it appears it looks broken 1. in the second apperance any shadow middleware is absent 1. in the second appearance all entries are appearing twice If I completely remove the `[:repl-options :nrepl-middleware]` injection, pprint still reports the last entry. Where the same cider.nrepl middlewares are included, but only once: ``` lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :dependencies conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :plugins conj '[lein-pprint,"1.3.2"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- pprint {:description "FIXME: write description", :compile-path "/Users/pez/Projects/tests/shadow-w-backend/target/default/classes", :deploy-repositories [["clojars" {:url "https://repo.clojars.org/", :password :gpg, :username :gpg}]], :group "lein-app", :resource-paths ("/Users/pez/Projects/tests/shadow-w-backend/dev-resources" "/Users/pez/Projects/tests/shadow-w-backend/resources"), :uberjar-merge-with {"META-INF/plexus/components.xml" leiningen.uberjar/components-merger, "data_readers.clj" leiningen.uberjar/clj-map-merger, #"META-INF/services/.*" [clojure.core/slurp (fn* [p1__7737__7739__auto__ p2__7738__7740__auto__] (clojure.core/str p1__7737__7739__auto__ "\n" p2__7738__7740__auto__)) clojure.core/spit]}, :name "lein-app", :checkout-deps-shares [:source-paths :test-paths :resource-paths :compile-path #'leiningen.core.classpath/checkout-deps-paths], :source-paths ("/Users/pez/Projects/tests/shadow-w-backend/src"), :eval-in :subprocess, :repositories [["central" {:url "https://repo1.maven.org/maven2/", :snapshots false}] ["clojars" {:url "https://repo.clojars.org/"}]], :test-paths ("/Users/pez/Projects/tests/shadow-w-backend/test"), :target-path "/Users/pez/Projects/tests/shadow-w-backend/target/default", :prep-tasks ["javac" "compile"], :native-path "/Users/pez/Projects/tests/shadow-w-backend/target/default/native", :offline? false, :root "/Users/pez/Projects/tests/shadow-w-backend", :pedantic? ranges, :clean-targets [:target-path], :plugins [[lein-pprint "1.3.2"] [cider/cider-nrepl "0.28.5"]], :profiles {:uberjar {:aot [:all], :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}}, :plugin-repositories [["central" {:url "https://repo1.maven.org/maven2/", :snapshots false}] ["clojars" {:url "https://repo.clojars.org/"}]], :aliases {"downgrade" "upgrade"}, :version "0.1.0-SNAPSHOT", :jar-exclusions [#"^\." #"\Q/.\E"], :main main.server, :global-vars {}, :uberjar-exclusions [#"(?i)^META-INF/[^/]*\.(SF|RSA|DSA)$" #"^module-info.class$"], :jvm-opts ["-XX:-OmitStackTraceInFastThrow" "-XX:+TieredCompilation" "-XX:TieredStopAtLevel=1"], :dependencies ([cider/cider-nrepl "0.28.5"] [cider/cider-nrepl "0.28.5"] [nrepl "1.0.0"] [org.clojure/clojure "1.11.1"] [org.clojure/clojurescript "1.11.60"] [thheller/shadow-cljs "2.19.9"] [binaryage/devtools "1.0.6"] [reagent/reagent "1.1.1"] [nrepl/nrepl "0.9.0" :exclusions ([org.clojure/clojure])] [org.nrepl/incomplete "0.1.0" :exclusions ([org.clojure/clojure])]), :release-tasks [["vcs" "assert-committed"] ["change" "version" "leiningen.release/bump-version" "release"] ["vcs" "commit"] ["vcs" "tag"] ["deploy"] ["change" "version" "leiningen.release/bump-version"] ["vcs" "commit"] ["vcs" "push"]], :repl-options {:nrepl-middleware [cider.nrepl/wrap-apropos cider.nrepl/wrap-classpath cider.nrepl/wrap-clojuredocs cider.nrepl/wrap-complete cider.nrepl/wrap-content-type cider.nrepl/wrap-debug cider.nrepl/wrap-enlighten cider.nrepl/wrap-format cider.nrepl/wrap-info cider.nrepl/wrap-inspect cider.nrepl/wrap-macroexpand cider.nrepl/wrap-ns cider.nrepl/wrap-out cider.nrepl/wrap-slurp cider.nrepl/wrap-profile cider.nrepl/wrap-refresh cider.nrepl/wrap-resource cider.nrepl/wrap-spec cider.nrepl/wrap-stacktrace cider.nrepl/wrap-test cider.nrepl/wrap-trace cider.nrepl/wrap-tracker cider.nrepl/wrap-undef cider.nrepl/wrap-version cider.nrepl/wrap-xref]}, :test-selectors {:default (constantly true)}} ``` I tested that Calva works without the `[:repl-options :nrepl-middleware]` injection, and it works just fine, so maybe the injection has never really worked?

lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :dependencies conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :plugins conj '[lein-pprint,"1.3.2"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- update-in '[:repl-options,:nrepl-middleware]' conj '[cider.nrepl/cider-middleware,shadow.cljs.devtools.server.nrepl/middleware]' -- pprint

Yeah, looking more closely at it, this is just invoking the task incorrectly. In particular, this bit: update-in '[:repl-options,:nrepl-middleware]' is incorrect; it should just be update-in :repl-options:nrepl-middleware instead.

As per the docstring:

Acts a lot like calling clojure.core/update-in on your project map
and then invoking a task on it, but with a few differences. Instead of
a vector of keys for reaching into nested maps, just mash keywords
together like ":repl-options:port".

Let me know if you have any further questions.

> lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :dependencies conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :plugins conj '[lein-pprint,"1.3.2"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- update-in '[:repl-options,:nrepl-middleware]' conj '[cider.nrepl/cider-middleware,shadow.cljs.devtools.server.nrepl/middleware]' -- pprint Yeah, looking more closely at it, this is just invoking the task incorrectly. In particular, this bit: `update-in '[:repl-options,:nrepl-middleware]'` is incorrect; it should just be `update-in :repl-options:nrepl-middleware` instead. As per the docstring: > Acts a lot like calling `clojure.core/update-in` on your project map and then invoking a task on it, but with a few differences. Instead of a vector of keys for reaching into nested maps, just mash keywords together like ":repl-options:port". Let me know if you have any further questions.

Oh, wow. This has been like this in Calva since the start!

Iirc, I did what CIDER did. I'll have to ask Bozhidar if that could be so.

Thanks!

Oh, wow. This has been like this in Calva since the start! Iirc, I did what CIDER did. I'll have to ask Bozhidar if that could be so. Thanks!

OK, so I am back at this and still can't quite figure it out. Trying with a simple, Clojure-only project. Starting the REPL like so:

lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :repl-options:nrepl-middleware conj '[cider.nrepl/cider-middleware]' -- repl :headless

Gives me:

ERROR:
java.io.FileNotFoundException: Could not locate [[cider/nrepl__init.class, [[cider/nrepl.clj or [[cider/nrepl.cljc on classpath.
        at clojure.lang.RT.load(RT.java:462)
        at clojure.lang.RT.load(RT.java:424)
        at clojure.core$load$fn__6908.invoke(core.clj:6161)
        at clojure.core$load.invokeStatic(core.clj:6160)
        at clojure.core$load.doInvoke(core.clj:6144)
        at clojure.lang.RestFn.invoke(RestFn.java:408)
        at clojure.core$load_one.invokeStatic(core.clj:5933)
        at clojure.core$load_one.invoke(core.clj:5928)
        at clojure.core$load_lib$fn__6850.invoke(core.clj:5975)
        at clojure.core$load_lib.invokeStatic(core.clj:5974)
        at clojure.core$load_lib.doInvoke(core.clj:5953)
        at clojure.lang.RestFn.applyTo(RestFn.java:142)
        at clojure.core$apply.invokeStatic(core.clj:669)
        at clojure.core$load_libs.invokeStatic(core.clj:6016)
        at clojure.core$load_libs.doInvoke(core.clj:6000)
        at clojure.lang.RestFn.applyTo(RestFn.java:137)
        at clojure.core$apply.invokeStatic(core.clj:669)
        at clojure.core$require.invokeStatic(core.clj:6038)
        at clojure.core$require.doInvoke(core.clj:6038)
        at clojure.lang.RestFn.invoke(RestFn.java:408)
        at nrepl.misc$requiring_resolve.invokeStatic(misc.clj:73)
        at nrepl.misc$requiring_resolve.doInvoke(misc.clj:66)
        at clojure.lang.RestFn.invoke(RestFn.java:423)
        at nrepl.middleware.dynamic_loader$update_stack_BANG_$fn__1445$fn__1446.invoke(dynamic_loader.clj:36)
        at clojure.core$map$fn__5935.invoke(core.clj:2772)
        at clojure.lang.LazySeq.sval(LazySeq.java:42)
        at clojure.lang.LazySeq.seq(LazySeq.java:51)
        at clojure.lang.RT.seq(RT.java:535)
        at clojure.core$seq__5467.invokeStatic(core.clj:139)
        at clojure.core$concat$fn__5558.invoke(core.clj:727)
        at clojure.lang.LazySeq.sval(LazySeq.java:42)
        at clojure.lang.LazySeq.seq(LazySeq.java:51)
        at clojure.lang.RT.seq(RT.java:535)
        at clojure.core$seq__5467.invokeStatic(core.clj:139)
        at clojure.core$filter$fn__5962.invoke(core.clj:2826)
        at clojure.lang.LazySeq.sval(LazySeq.java:42)
        at clojure.lang.LazySeq.seq(LazySeq.java:58)
        at clojure.lang.RT.seq(RT.java:535)
        at clojure.core$seq__5467.invokeStatic(core.clj:139)
        at clojure.core$seq__5467.invoke(core.clj:139)
        at nrepl.middleware$extend_deps.invokeStatic(middleware.clj:116)
        at nrepl.middleware$extend_deps.invoke(middleware.clj:108)
        at nrepl.middleware$linearize_middleware_stack.invokeStatic(middleware.clj:183)
        at nrepl.middleware$linearize_middleware_stack.invoke(middleware.clj:179)
        at nrepl.middleware.dynamic_loader$update_stack_BANG_$fn__1445.invoke(dynamic_loader.clj:38)
        at clojure.lang.AFn.applyToHelper(AFn.java:152)
        at clojure.lang.AFn.applyTo(AFn.java:144)
        at clojure.core$apply.invokeStatic(core.clj:667)
        at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1990)
        at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1990)
        at clojure.lang.RestFn.invoke(RestFn.java:425)
        at nrepl.middleware.dynamic_loader$update_stack_BANG_.invokeStatic(dynamic_loader.clj:29)
        at nrepl.middleware.dynamic_loader$update_stack_BANG_.invoke(dynamic_loader.clj:27)
        at nrepl.middleware.dynamic_loader$wrap_dynamic_loader$fn__1488.invoke(dynamic_loader.clj:86)
        at nrepl.middleware$wrap_conj_descriptor$fn__966.invoke(middleware.clj:16)
        at nrepl.server$default_handler$fn__1971.invoke(server.clj:136)
        at nrepl.server$default_handler.invokeStatic(server.clj:135)
        at nrepl.server$default_handler.doInvoke(server.clj:120)
        at clojure.lang.RestFn.invoke(RestFn.java:3894)
        at lein_project.core$eval2775.invokeStatic(form-init8873394651217862800.clj:1)
        at lein_project.core$eval2775.invoke(form-init8873394651217862800.clj:1)
        at clojure.lang.Compiler.eval(Compiler.java:7194)
        at clojure.lang.Compiler.eval(Compiler.java:7184)
        at clojure.lang.Compiler.eval(Compiler.java:7184)
        at clojure.lang.Compiler.load(Compiler.java:7653)
        at clojure.lang.Compiler.loadFile(Compiler.java:7591)
        at clojure.main$load_script.invokeStatic(main.clj:475)
        at clojure.main$init_opt.invokeStatic(main.clj:477)
        at clojure.main$init_opt.invoke(main.clj:477)
        at clojure.main$initialize.invokeStatic(main.clj:508)
        at clojure.main$null_opt.invokeStatic(main.clj:542)
        at clojure.main$null_opt.invoke(main.clj:539)
        at clojure.main$main.invokeStatic(main.clj:664)
        at clojure.main$main.doInvoke(main.clj:616)
        at clojure.lang.RestFn.applyTo(RestFn.java:137)
        at clojure.lang.Var.applyTo(Var.java:705)
        at clojure.main.main(main.java:40)
[WARNING] No nREPL middleware descriptor in metadata of null, see nrepl.middleware/set-descriptor!
nREPL server started on port 51217 on host 127.0.0.1 - nrepl://127.0.0.1:51217

There's clearly something I don't understand here...

OK, so I am back at this and still can't quite figure it out. Trying with a simple, Clojure-only project. Starting the REPL like so: ``` lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :repl-options:nrepl-middleware conj '[cider.nrepl/cider-middleware]' -- repl :headless ``` Gives me: ``` ERROR: java.io.FileNotFoundException: Could not locate [[cider/nrepl__init.class, [[cider/nrepl.clj or [[cider/nrepl.cljc on classpath. at clojure.lang.RT.load(RT.java:462) at clojure.lang.RT.load(RT.java:424) at clojure.core$load$fn__6908.invoke(core.clj:6161) at clojure.core$load.invokeStatic(core.clj:6160) at clojure.core$load.doInvoke(core.clj:6144) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core$load_one.invokeStatic(core.clj:5933) at clojure.core$load_one.invoke(core.clj:5928) at clojure.core$load_lib$fn__6850.invoke(core.clj:5975) at clojure.core$load_lib.invokeStatic(core.clj:5974) at clojure.core$load_lib.doInvoke(core.clj:5953) at clojure.lang.RestFn.applyTo(RestFn.java:142) at clojure.core$apply.invokeStatic(core.clj:669) at clojure.core$load_libs.invokeStatic(core.clj:6016) at clojure.core$load_libs.doInvoke(core.clj:6000) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.core$apply.invokeStatic(core.clj:669) at clojure.core$require.invokeStatic(core.clj:6038) at clojure.core$require.doInvoke(core.clj:6038) at clojure.lang.RestFn.invoke(RestFn.java:408) at nrepl.misc$requiring_resolve.invokeStatic(misc.clj:73) at nrepl.misc$requiring_resolve.doInvoke(misc.clj:66) at clojure.lang.RestFn.invoke(RestFn.java:423) at nrepl.middleware.dynamic_loader$update_stack_BANG_$fn__1445$fn__1446.invoke(dynamic_loader.clj:36) at clojure.core$map$fn__5935.invoke(core.clj:2772) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:51) at clojure.lang.RT.seq(RT.java:535) at clojure.core$seq__5467.invokeStatic(core.clj:139) at clojure.core$concat$fn__5558.invoke(core.clj:727) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:51) at clojure.lang.RT.seq(RT.java:535) at clojure.core$seq__5467.invokeStatic(core.clj:139) at clojure.core$filter$fn__5962.invoke(core.clj:2826) at clojure.lang.LazySeq.sval(LazySeq.java:42) at clojure.lang.LazySeq.seq(LazySeq.java:58) at clojure.lang.RT.seq(RT.java:535) at clojure.core$seq__5467.invokeStatic(core.clj:139) at clojure.core$seq__5467.invoke(core.clj:139) at nrepl.middleware$extend_deps.invokeStatic(middleware.clj:116) at nrepl.middleware$extend_deps.invoke(middleware.clj:108) at nrepl.middleware$linearize_middleware_stack.invokeStatic(middleware.clj:183) at nrepl.middleware$linearize_middleware_stack.invoke(middleware.clj:179) at nrepl.middleware.dynamic_loader$update_stack_BANG_$fn__1445.invoke(dynamic_loader.clj:38) at clojure.lang.AFn.applyToHelper(AFn.java:152) at clojure.lang.AFn.applyTo(AFn.java:144) at clojure.core$apply.invokeStatic(core.clj:667) at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1990) at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1990) at clojure.lang.RestFn.invoke(RestFn.java:425) at nrepl.middleware.dynamic_loader$update_stack_BANG_.invokeStatic(dynamic_loader.clj:29) at nrepl.middleware.dynamic_loader$update_stack_BANG_.invoke(dynamic_loader.clj:27) at nrepl.middleware.dynamic_loader$wrap_dynamic_loader$fn__1488.invoke(dynamic_loader.clj:86) at nrepl.middleware$wrap_conj_descriptor$fn__966.invoke(middleware.clj:16) at nrepl.server$default_handler$fn__1971.invoke(server.clj:136) at nrepl.server$default_handler.invokeStatic(server.clj:135) at nrepl.server$default_handler.doInvoke(server.clj:120) at clojure.lang.RestFn.invoke(RestFn.java:3894) at lein_project.core$eval2775.invokeStatic(form-init8873394651217862800.clj:1) at lein_project.core$eval2775.invoke(form-init8873394651217862800.clj:1) at clojure.lang.Compiler.eval(Compiler.java:7194) at clojure.lang.Compiler.eval(Compiler.java:7184) at clojure.lang.Compiler.eval(Compiler.java:7184) at clojure.lang.Compiler.load(Compiler.java:7653) at clojure.lang.Compiler.loadFile(Compiler.java:7591) at clojure.main$load_script.invokeStatic(main.clj:475) at clojure.main$init_opt.invokeStatic(main.clj:477) at clojure.main$init_opt.invoke(main.clj:477) at clojure.main$initialize.invokeStatic(main.clj:508) at clojure.main$null_opt.invokeStatic(main.clj:542) at clojure.main$null_opt.invoke(main.clj:539) at clojure.main$main.invokeStatic(main.clj:664) at clojure.main$main.doInvoke(main.clj:616) at clojure.lang.RestFn.applyTo(RestFn.java:137) at clojure.lang.Var.applyTo(Var.java:705) at clojure.main.main(main.java:40) [WARNING] No nREPL middleware descriptor in metadata of null, see nrepl.middleware/set-descriptor! nREPL server started on port 51217 on host 127.0.0.1 - nrepl://127.0.0.1:51217 ``` There's clearly something I don't understand here...

I don't use cider so it's hard for me to say what's going on here, but
as far as I can tell this is working fine from Leiningen's
perspective. You can see that the right dependencies are present since
this command works normally:

$ lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :repl-options:nrepl-middleware conj '[cider.nrepl/cider-middleware]' -- run -m clojure.main -e "(require 'cider.nrepl)"

I would guess that whatever you're running into must be an issue in nrepl or cider.

I don't use cider so it's hard for me to say what's going on here, but as far as I can tell this is working fine from Leiningen's perspective. You can see that the right dependencies are present since this command works normally: $ lein update-in :dependencies conj '[nrepl,"1.0.0"]' -- update-in :plugins conj '[cider/cider-nrepl,"0.28.5"]' -- update-in :repl-options:nrepl-middleware conj '[cider.nrepl/cider-middleware]' -- run -m clojure.main -e "(require 'cider.nrepl)" I would guess that whatever you're running into must be an issue in nrepl or cider.

Thanks! I'll see if I can figure it out with that clue.

Thanks! I'll see if I can figure it out with that clue.
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: leiningen/leiningen#10
There is no content yet.