I have a strange problem with Babashka, nrepl, and Cognitect AWS API (not sure if other libraries are affected, this is the one that's tripping me up). If I run the following in bb repl it works fine:
Babashka v1.13.221
Type :repl/help for help
user=> (require '[cognitect.aws.client.api :as aws])
nil
user=> (aws/client {:api :dynamodb})
#object[babashka.impl.clojure.lang.ILookup 0x680a6cb3 "babashka.impl.clojure.lang.ILookup@680a6cb3"]
However, if I start the nrepl server, connect from Emacs, and try the exact same thing:
;; Connected to nREPL server -
;; CIDER 2.1.0-snapshot (package: 2.1.0-snapshot), nREPL 1.7.0
;; Clojure 1.12.6-SCI, Java 25.0.4
user> (require '[cognitect.aws.client.api :as aws])
;; => nil
user> (aws/client {:api :dynamodb})
java.lang.NullPointerException [at cognitect/aws/resources.clj:16:1]
With Babashka v1.13.220 and earlier it's working fine, but v1.13.221 and later all give this NPE when invoked via nrepl. Any idea what's going on?Does it work outside of nREPL?
Yes, it works if I start bb repl
Have you tried version 225?
Yes, I think that's the version where I first noticed the problem, then I did a binary search to try to identify where it started.
I see Babashka v1.13.221 above though?
Yes, that was the first version where I saw the problem. Let me double-check with v1.13.225...
ok, I think I see the problem, it has to do with (.getContextClassLoader (Thread/currentThread)) (clojure.lang.RT/baseLoader).
I siwtched nREPL to use nREPL's own source and this needs to be fixed.
I think a workaround is to do this in the nREPL first:
(.setContextClassLoader (Thread/currentThread) (.getClassLoader clojure.lang.RT))If I do that, I get a different error:
;; Connected to nREPL server -
;; CIDER 2.1.0-snapshot (package: 2.1.0-snapshot), nREPL 1.7.0
;; Clojure 1.12.6-SCI, Java 25.0.4
user> (.setContextClassLoader (Thread/currentThread) (.getClassLoader clojure.lang.RT))
;; => nil
user> (require '[cognitect.aws.client.api :as aws])
;; => nil
user> (aws/client {:api :dynamodb})
clojure.lang.ExceptionInfo: Cannot find resource cognitect/aws/dynamodb/service.edn. [at cognitect/aws/service.clj:32:5]
user> and if you do this?
(.setContextClassLoader (Thread/currentThread)
(some #(when (= "main" (.getName ^Thread %)) (.getContextClassLoader ^Thread %))
(.keySet (Thread/getAllStackTraces))))do it before anything else
That gives a NPE again
I'll try to make a fix so you can use the dev build
Thank you, much appreciate the help.
The workaround above: you need to restart the nREPL server first if you haven't done so and execute this before loading any aws namespace
I think I did, let me double-check...
OK, so if I start bb repl and start an nrepl server from the REPL, then connect with cider and try your work-around, it works. But if I start the nrepl with this Babashka task and try the work-around, I get the NPE I was seeing before:
{:doc "Start an nREPL server"
:depends [gen-version]
:extra-paths ["test"]
:extra-deps {org.clojure/test.check
{:mvn/version "0.9.0"}}
:requires ([babashka.nrepl.server :as srv])
task (srv/start-server! {:host "localhost" :port 1339})}
The gen-version dependency is just generating some code, it loads and clojure.string but no AWS libraries.this is a workaround that should cover all scenarios:
export BABASHKA_PRELOADS="(require 'nrepl.util.classloader) (alter-var-root (resolve 'nrepl.util.classloader/dynamic-classloader) (constantly (fn ([] (.getContextClassLoader (Thread/currentThread))) ([cl] cl))))"Meanwhile I've merged the fix. Once master CI finishes you can install the dev build and remove your workaround:
bash <(curl ) --dev-build --dir /tmp please test so I won't release a version that didn't fix it properly. should be good in 15 minutes
Thank you, confirmed it works with the BABASHKA_PRELOADS work-around. I will try the dev build in 15 mins or so.
👍 Make sure to unset BABASHKA_PRELOADS with the fixed version :)
Will do 🙂
Thank you so much for your help and the quick fix - I was at a complete loss.
thanks for reporting!