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
Interrupt is broken on JVM 20+ #296
Comments
For reference, this is how it was solved in jshell: openjdk/jdk#10166 Looks like they override the jdk internal(!) MethodVisitor to add a check to a new static method on every single JVM Few things about that:
|
@socksy Thanks for sharing this! I'm hoping we'd be able to come up with something simpler and more future-proof, although all my research so far indicates that'd be pretty hard. In essence |
I found an official JDK guide regarding this deprecation. Anything there you could use? |
@bsless I don't see anything that can help us there. As we're running user code on the session eval thread we can't really add code there that would make it interruptible. |
@bbatsov Perhaps it's worth bringing this up on the JDK mailing list to see if they would reconsider removing it, perhaps putting it behind a flag? |
I'm guessing that ship has sailed if there's already a release without it. I've never heard of the JDK team going back on a removal. |
@bbatsov yeah, Alternatively, if you wanted to be (even more) hacky, perhaps we could write a fake |
FYI - @alexander-yakushev proposed a potential fix for this in #318 @PEZ and @danielcompton - please, take a look, as the fix will require some client co-operation as it involves loading a JVMTI agent. |
Thanks for headsup, @bbatsov! In the PR you say that CIDER will inject this as jack-in params. Can you share what that would look like. As Calva's jack-in is quite similar, I think we can consider to do whatever CIDER does. |
For tools.deps, this means adding |
I looked at this issue recently too and came up with a POC that uses the JDWP agent and JDI to forcibly stop threads. The JDWP native lib has a way of stopping threads and is part of the JVM, so using it avoids the need to build our own native code. Unfortunately none of that lib is accessible via JNI (as far as I can tell), so we need to start the JDWP agent and communicate with it via JDI. Just like the native agent solution, the JVM must be invoked with One big tradeoff is that JDWP only supports a single transport. As it stands now the POC would prevent the use of JDWP debuggers completely. This could be mitigated by either:
It's a bigger imposition on users than #318 but less code and less build complexity. What do you think @alexander-yakushev @bbatsov? |
Thank you, Michael! If only you had shown your POC earlier, I wouldn't bother with the agent, and now we wouldn't have the trouble of choice 😄. I like the fact about JDWP approach that we don't have to compile and ship any native code. And I don't like that approach having a runtime impact. If I understand the numbers in the article that you linked correctly, then the runtime overhead from JDWP is ~6% which is significant (not arguing whether it is big or not, but it's not within a measurement error). What also bothers me is that the overhead exists even if the debugger is disabled which means it comes from the capabilities requested by JDWP in its Agent_OnLoad section. Those caps influence how JVM behaves in regard to optimizations, tweak JIT and inliner, so you get a differently behaving environment, even if slightly. Here's the comparison of two solutions as a table:
|
nREPL relied on
Thread.stop
to kill the session thread when needed and the function was finally removed from Java in Java 20 (after being deprecated for ages). The current nREPL implementation triesTread.interrupt
first and fallbacks onThread.stop
if that fails.Any ideas for fixing this on Java 20+ are welcome!
See clojure-emacs/cider#3351 for more details.
The text was updated successfully, but these errors were encountered: