Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NPE on connect with embedded nREPL server #447

Closed
DerGuteMoritz opened this issue Oct 17, 2017 · 20 comments
Closed

NPE on connect with embedded nREPL server #447

DerGuteMoritz opened this issue Oct 17, 2017 · 20 comments
Labels

Comments

@DerGuteMoritz
Copy link

Expected behavior

Embedding an nREPL server as described in https://github.com/clojure-emacs/cider-nrepl#via-embedding-nrepl-in-your-app works.

Actual behavior

With version 0.15.x this still worked but with 0.16.0-SNAPSHOT (specifically version bd7b2bc4c780549594bd7f03c772465216c1e9ca), the server runs into a NullPointerException when a client connects, like this:

18:26:38.661 ERROR [clojure.tools.nrepl.server] (clojure-agent-send-off-pool-3) Unhandled REPL handler exception processing message {:op describe, :session 2a63e04c-29af-4e9b-acbb-5247dcc140f2, :id 61}
java.lang.NullPointerException: null
	at clojure.core$deref_future.invokeStatic(core.clj:2297) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.core$deref.invokeStatic(core.clj:2317) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.core$deref.invoke(core.clj:2303) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at cider.nrepl$wrap_pprint_fn$fn__24216.invoke(nrepl.clj:85) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__23554.invoke(middleware.clj:22) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at cider.nrepl$wrap_tracker$fn__24336.invoke(nrepl.clj:410) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__23554.invoke(middleware.clj:22) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.tools.nrepl.middleware.session$session$fn__23873.invoke(session.clj:192) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__23554.invoke(middleware.clj:22) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at cider.nrepl$wrap_apropos$fn__24230.invoke(nrepl.clj:124) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__23554.invoke(middleware.clj:22) ~[foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.tools.nrepl.server$handle_STAR_.invokeStatic(server.clj:19) [foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.tools.nrepl.server$handle_STAR_.invoke(server.clj:16) [foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.tools.nrepl.server$handle$fn__23930.invoke(server.clj:28) [foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.core$binding_conveyor_fn$fn__5478.invoke(core.clj:2027) [foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at clojure.lang.AFn.call(AFn.java:18) [foo-0.1.0-SNAPSHOT-standalone.jar:na]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_144]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_144]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_144]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]

Steps to reproduce the problem

  1. Embed an nREPL server as described in https://github.com/clojure-emacs/cider-nrepl#via-embedding-nrepl-in-your-app
  2. Connect to the server using the Emacs CIDER client

Environment & Version information

cider-nrepl version

0.16.0-SNAPSHOT (bd7b2bc4c780549594bd7f03c772465216c1e9ca)

Java version

1.8

Operating system

Linux

@DerGuteMoritz
Copy link
Author

Oh right, forgot to mention that you need to run it as a standalone app (e.g. from an uberjar) rather than from lein repl or something (with that it works for me). My guess is that it is related to the dynamic middleware loading refactoring.

@orb
Copy link

orb commented Oct 25, 2017

I'm having this problem too. I don't know which commit specifically broke this, but reverting to [cider/cider-nrepl "0.16.0-20170916.095133-1"] fixes it. (there's nothing special about that version except it's a known good version from a previous release)

And, as with the original reporter, we are running without lein. It's not an uberjar, but effectively the same thing. (https://github.com/orb/lein-metajar)

@orb
Copy link

orb commented Oct 28, 2017

A little more investigation.

Given thisproject.clj

(defproject nrepl-bug "0.1.0-SNAPSHOT"
  :description "CIDER nrepl test"
  :url "https://github.com/clojure-emacs/cider-nrepl/issues/447"
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/tools.nrepl "0.2.12"]
                 [cider/cider-nrepl "0.16.0-SNAPSHOT"]]
  :profiles {:uberjar {:aot [nrepl-bug.core]}}
  :main nrepl-bug.core)

And this source:

(ns nrepl-bug.core
  (:gen-class)
  (:require [clojure.tools.nrepl.server :as nrepl-server]
            [cider.nrepl :as cider]))

(defn -main []
  (println (format "Starting with classpath: %s" (System/getProperty "java.class.path")))
  (nrepl-server/start-server
   :port 6666
   :handler cider/cider-nrepl-handler))

I get a failure with with cider-jack-in to localhost 6666, running the server with:

$ lein uberjar
$ java -jar target/nrepl-bug-0.1.0-SNAPSHOT-standalone.jar

Changing the cider link to be more resolves the problem:

(ns nrepl-bug.core
  (:gen-class)
  (:require [clojure.tools.nrepl.server :as nrepl-server]))

(defn nrepl-handler []
  (require 'cider.nrepl)
  (ns-resolve 'cider.nrepl 'cider-nrepl-handler))

(defn -main []
  (println (format "Starting with classpath: %s" (System/getProperty "java.class.path")))
  (nrepl-server/start-server
   :port 6666
   :handler (nrepl-handler)))

I haven't looked at the code to see why this might cause the problem, but this is a good workaround for now, at the very least.

@bbatsov
Copy link
Member

bbatsov commented Dec 9, 2017

That's likely related to the deferred middleware changes introduced by @vspinu in 0.16. His PR should give you a good idea what exactly caused this I guess.

@bbatsov bbatsov added the bug label Dec 10, 2017
@bbatsov
Copy link
Member

bbatsov commented Dec 10, 2017

Ops I forgot to post it - #438

@vspinu
Copy link
Contributor

vspinu commented Dec 10, 2017

This problem is related but different from what I have reported in the pull - the parallel loading of middleware, which is now fixed. The fact that splitting cider.nrepl out of main (ns ... (:require ...)) suggests (again) that something is amis with the require itself. I wish I could replicate this outside of cider somehow.

@daveliepmann
Copy link
Contributor

This issue bit me as well. @orb's workaround helped.

Should I make a PR mentioning this issue in the embedding-nrepl-in-your-app instructions, at least until it's resolved?

@bbatsov
Copy link
Member

bbatsov commented Feb 12, 2018

@daveliepmann It'd be best to solve this #464 I guess, but anything's better than nothing until a proper fix.

@otwieracz
Copy link

Any progress here? With 0.18.0-SNAPSHOT I still had to use workaround

(defn cider-nrepl-handler []
  (require 'cider.nrepl)
  (ns-resolve 'cider.nrepl 'cider-nrepl-handler))

otherwise I am getting NPE.

@timvisher
Copy link

I am seeing an NPE even after applying this workaround when launched from an uberjar.

@timvisher
Copy link

I've been able to track it down (the failure of the workaround) to some kind of bad interaction with another library being on the classpath.

@timvisher
Copy link

It wound up being a transitive dependency that was :refer [cider-nrepl-handler]ing. That was fun to track down. (-‸ლ)

@bbatsov
Copy link
Member

bbatsov commented Apr 16, 2019

That's weird. I'm glad you managed to work this out!

@jiacai2050
Copy link

I'm using CIDER 0.23.0 (Lima) and meet this NPE in my cljs project, it turns out that my project have explict [com.cemerick/piggieback "0.2.1"] dependency, which seems cause this NPE, after remove this, everything is fine.

@bbatsov
Copy link
Member

bbatsov commented Nov 24, 2019

@jiacai2050 A while ago the coordinates of com.cemerick/piggieback were changed to cider/piggieback.

@agriffis
Copy link

agriffis commented Jan 4, 2020

I'm working in a project that uses @orb 's workaround from this issue to start a REPL in a Tomcat server:

(defn nrepl-handler []
  (require 'cider.nrepl)
  (ns-resolve 'cider.nrepl 'cider-nrepl-handler))

I'd like to add more middleware to the default list, specifically refactor-nrepl and iced-nrepl. This seems to involve re-implementing cider-nrepl-handler and also resolve-or-fail in my project just to add the extra middleware. Am I on the right track?

@agriffis
Copy link

agriffis commented Jan 4, 2020

Here's what I ended up with. Open to suggestions if there's a better approach.

(def development (Boolean/getBoolean "development"))

(defn cider-middleware
  "Roundabout way of getting the list of cider middleware, see
  https://github.com/clojure-emacs/cider-nrepl/issues/447"
  []
  (require 'cider.nrepl)
  (map resolve (var-get (ns-resolve 'cider.nrepl 'cider-middleware))))

(defn dev-middleware
  "Extra nrepl middleware for development, especially for vim-iced.
  https://liquidz.github.io/vim-iced/vim-iced.html#vim-iced-install-manually"
  []
  (when development
    (mapcat (fn [[ns syms]] (require ns) (map (partial ns-resolve ns) syms))
      [['refactor-nrepl.middleware ['wrap-refactor]] ['iced.nrepl ['wrap-iced]]])))

(defn nrepl-handler
  "Re-implement cider-nrepl-handler so we can add middleware to the default list."
  []
  (apply nrepl-server/default-handler (concat (cider-middleware) (dev-middleware))))

@bbatsov
Copy link
Member

bbatsov commented Jan 5, 2020

Looks like a good approach to me. Still, at some point we'll have to tackle the underlying issue with the deferred middleware loading.

@v3nd3774
Copy link

Here's what I ended up with. Open to suggestions if there's a better approach.

(def development (Boolean/getBoolean "development"))

(defn cider-middleware
  "Roundabout way of getting the list of cider middleware, see
  https://github.com/clojure-emacs/cider-nrepl/issues/447"
  []
  (require 'cider.nrepl)
  (map resolve (var-get (ns-resolve 'cider.nrepl 'cider-middleware))))

(defn dev-middleware
  "Extra nrepl middleware for development, especially for vim-iced.
  https://liquidz.github.io/vim-iced/vim-iced.html#vim-iced-install-manually"
  []
  (when development
    (mapcat (fn [[ns syms]] (require ns) (map (partial ns-resolve ns) syms))
      [['refactor-nrepl.middleware ['wrap-refactor]] ['iced.nrepl ['wrap-iced]]])))

(defn nrepl-handler
  "Re-implement cider-nrepl-handler so we can add middleware to the default list."
  []
  (apply nrepl-server/default-handler (concat (cider-middleware) (dev-middleware))))

Ty @agriffis , this workaround is still working now.

@AL4AL
Copy link

AL4AL commented Apr 24, 2021

Today the workaround for me, for java.lang.ClassNotFoundException: com.sun.tools.javac.util.List error was to upgrade cider version to 0.26.0
to do so in vs code you should go in calva setting in vscode preferences

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests