I've installed samestep/boot-refresh 0.1.0. In the boot REPL, when I change a source file and type:
boot.user=> (boot (refresh))
I get:
java.lang.IllegalStateException: Can't set!: *e from non-binding thread
What am I doing wrong?
Here's the full stack trace:
boot.user=> *e
#error {
:cause "Can't set!: *e from non-binding thread"
:via
[{:type java.lang.IllegalStateException
:message "Can't set!: *e from non-binding thread"
:at [clojure.lang.Var set "Var.java" 218]}]
:trace
[[clojure.lang.Var set "Var.java" 218]
[clojure.tools.namespace.repl$print_and_return invokeStatic "repl.clj" 22]
[clojure.tools.namespace.repl$print_and_return invoke "repl.clj" 20]
[clojure.tools.namespace.repl$do_refresh invokeStatic "repl.clj" 96]
[clojure.tools.namespace.repl$do_refresh invoke "repl.clj" 82]
[clojure.tools.namespace.repl$refresh invokeStatic "repl.clj" 145]
[clojure.tools.namespace.repl$refresh doInvoke "repl.clj" 128]
[clojure.lang.RestFn invoke "RestFn.java" 397]
[samestep.boot_refresh$eval541$fn__542$fn__547$fn__548$fn__549 invoke "boot_refresh.clj" 14]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 646]
[clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1881]
[clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1881]
[clojure.lang.RestFn invoke "RestFn.java" 425]
[samestep.boot_refresh$eval541$fn__542$fn__547$fn__548 invoke "boot_refresh.clj" 13]
[boot.core$run_tasks invoke "core.clj" 1019]
[boot.core$boot$fn__918 invoke "core.clj" 1029]
[clojure.core$binding_conveyor_fn$fn__4676 invoke "core.clj" 1938]
[clojure.lang.AFn call "AFn.java" 18]
[java.util.concurrent.FutureTask run "FutureTask.java" 266]
[java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1142]
[java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 617]
[java.lang.Thread run "Thread.java" 745]]}
My own code isn't mentioned in the stack trace. I have seen (boot (refresh))
work from the REPL before, but I haven't been able to find out what I'm doing differently to cause this error.
Update 1
After a long binary search with many print statements—since, as explained in @amalloy's answer, the stack trace for the real exception is inaccessible—I discovered this:
In a namespace called move-test
, this statement:
(def subset-sum-spec fargish.workspace-test/subset-sum-spec)
was causing (boot (refresh))
to fail. When I replaced it with:
(:require … [fargish.workspace-test :refer [subset-sum-spec]] …)
in the ns
statement, (boot (refresh))
worked again. That fixes the current problem for now, but I'd still like to know what's going on.
Update 2
Continuing to try to get (boot (refresh))
to work, it's become clear that the problem is different every time. @amalloy's answer suggests that the real answer to this question would be some way to find the exception and stack trace that c.t.n.repl/print-and-return is failing to store in *e
. I've tried a few ideas, but the relevant variables seem to be private and hard to dig out.
How can you find out the error that causes (boot (refresh))
to fail?