@cfleming Sure thing. I’m working on this one https://github.com/aratare-jp/epsilon-clj
Ok, and how can I reproduce it? Just set up a REPL and run?
Yep. Just right click the project and choose Run REPL
One thing I’ve noticed is that this happens so randomly I can’t really give you a more concrete way to reproduce it. But of all the time that it did occur, it’s always caused by Run REPL
.
When I tried it a couple of months back, running lein repl
in a terminal would somehow make this go away. When I tried it yesterday, the error persisted even after multiple lein repl
.
Yeah, I just tried it and it worked fine. Do you have any plugins in your user.clj?
Nope. I tend to keep things in my projects instead.
Do you have profiles selected in your run config?
Actually yes. I was trying with dev
yesterday.
When I try with dev, I get:
Error loading nrepl.server: Could not locate nrepl/server__init.class, nrepl/server.clj or nrepl/server.cljc on classpath.
Error loading complete.core: Could not locate complete/core__init.class, complete/core.clj or complete/core.cljc on classpath.
Syntax error (ClassNotFoundException) compiling at (/private/var/folders/__/8l603gyx7t15k39pyjk0c0xr0000gn/T/form-init1414398454383792338.clj:1:1190).
nrepl.server
I think the problem is with lein-cloverage
, here: https://github.com/cloverage/cloverage/blob/dba7d72547748cf494f2bbc784b8a70ed8d9901f/lein-cloverage/src/leiningen/cloverage.clj#L46
But I don’t know what would provoke the exception.
I can try to track down why the error isn’t having more useful data output, but it would be really helpful to be able to reproduce it.
Ok, I fixed those errors by including nrepl and clojure-complete in the dependencies. Still no failure though.
Can you email me your log file to <mailto:cursive@cursive-ide.com|cursive@cursive-ide.com>? Help | Show log in Finder/Explorer
This is what I’m experiencing at the moment.
Sure will do now.
Sent
Thanks. So there’s nothing related in the logs unfortunately, but I think I see what the problem is with some of the exception data being lost.
Actually, looking at that line in Cloverage, it looks like it’s totally eating the exception data anyway.
I also don’t understand how that might get invoked from just starting a REPL.
Correct me if I’m wrong, but when you select profiles in the Leiningen
tab in Cursive, that’s just for compiling stuff right?
Because I have test
checked as one of the profiles
That’s for what gets synced to the project. If you’re running your REPL with Leiningen, it shouldn’t matter.
Well other than that, I honestly have no idea why Cloverage would be invoked because I think I haven’t done any weird setup afaict.
But if I intentionally invoke Cloverage with lein cloverage
, it works fine 😅
Hang on, I’ll try to create a dev build with better logging, to see if that helps.
Thanks a lot for looking into this 🙂
Are there any plans to get “Interrupt Current Evaluation” working for socket repls?
@potetm afaik, nREPL uses Thread#stop
which has long been deprecated
I have a similar problem with the nREPL server of babashka. I can't use Thread#stop
there because it's not supported anymore in the GraalVM JDK
Someone on the graalvm slack suggested to me to use safepoints
haven't looked into it though
It does use stop, but I’ve never had a problem with it.
AFAIK the biggest problem with stop is that it doesn’t release monitors — which aren’t really an issue in clojure.
at any rate, an interrupt would probably do
an interrupt won't kill a thread running (doall (range))
There’s no way to kill that (or in general, any uncooperative REPL process) except Thread/kill
you mean Thread#stop
right
Yes, that one.
BTW the problem is not actually that monitors are not released, it’s quite the opposite: > Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
From here: https://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
The risk is pretty low for a REPL IMO
Ah yeah, that’s right.
I'm not sure that's possible, I think it's a feature of nrepl
It’s possible. It’s a matter of what payload you use to set things up.
nrepl just wraps every execution on a thread, and it calls Thread/kill
on cancelation
At worst cursive would rely on the user to set up a specific :accept
fn.
I see. I'm probably not well-informed in the topic, I only based my initial comment on what I read in the article I linked