-1

I wish to harvest the exception stack to open debugger on new Thread while unblocking the thread which threw the original exception. Is it possible in Java?

In Squeak, this method does the work:

StandardToolSet>>#debugException: anException
        "For convenience. Construct a helper process to debug an exception 
that occurred in the active process later on so that the active process 
can (try to) resume. Uses a temporary variable to access and copy the 
signaler context now before it gets GC'ed."
    
    | helperProcess |
    helperProcess := (Process
        forContext: anException signalerContext copyStack
        priority: Processor activeProcess priority)
            shouldResumeFromDebugger: false;
            yourself.

    Project current addDeferredUIMessage: [
        helperProcess
            debugWithTitle: anException description
            full: false].
    ```
rabbit
  • 111
  • 9
  • Unclear what you're asking. You can print or get the stack trace from any exception on any thread, and there is nothing about that process or the catching process that blocks the catching thread. – user207421 Jul 20 '20 at 03:14
  • Well, not so unclear if you read the Squeak method I posted. That explains clearly what I am after. In particular: `anException signalerContext copyStack`. I am uninterested in printing the stack trace, I wish to open a resumable debugger on the thrown exception, after having copied the stack out of the current Process to allow that current Process (my event loop) to proceed handling new message sends through its queue of pending sends. Without this the opening of a debugger blocks the event loop. It seems Java is incapable of providing this capability. Woe! So sad. – rabbit Jul 20 '20 at 13:25
  • For starters, I cannot get an active stack from an Exception. So mark 1 for Squeak. Then, I suppose as a result of not being able to get a stack, one cannot create a new Thread on that stack. Continuations seem to require starting with a runnable, then yields throughout to stop processing and then resume the continuation where is was yielded. That will not work for PromisesLocal. The Java stack unwinds as handler contexts are sought. Just dumping good info over the gunwhale, into the sea, lost forever. So lame is Java. Get her some crutches and a wheelchair! – rabbit Jul 20 '20 at 13:45
  • **The _Squeak_ method above `StandardToolSet>>#debugException:` cannot be implemented in _Java_. So LAME!** – rabbit Jul 20 '20 at 13:47
  • The issue becomes, how will Java implement Promises A+ [1]? Especially when the Promise is rejected. [1] [Promises A+ spec](https://promisesaplus.com/) – rabbit Jul 20 '20 at 13:55
  • 1
    @RobertWithers No need to rant about Java, we all know that it is different from Smalltalk and that Smalltalkers love their Smalltalk... – JayK Jul 20 '20 at 14:11
  • @RobertWithers I don't see how the Java implementation of contexts prevents the implementation of Promises. For one, Java already has a similar concept, called Futures (being designed with concurrency in mind, basic Java does not need the workarounds about living in only one thread as JavaScript does). And otherwise the Promises framework may just install a catch-all in the framework code to reject on errors in the then-callbacks. – JayK Jul 20 '20 at 14:12
  • Yes, I have links to Promises implemented in Java. I will research them. They must have a different specification when an exception is thrown within the Promises framework. It may open a debugger but block the single thread the promises are running on, stopping the system. Or the idea is that they get handled and unblock the thread? I do not know. I will look to replicate the solution they tend to specify. – rabbit Jul 20 '20 at 14:19
  • Squeak/Smalltalk/JITVM vs Java/JITVM debate revolves around issue: _Do you have the capability to do ...?_ So many times the answer for Java is NO. i.e. A) Can you add methods to pre-existing classes for your project local purposes? Squeak: **YES!** Java _NO_. B) Can one object become another on the heap and retain its identityHash? Java: **NO**, Squeak _YES!_. The excuse is security & public sfety...just like drug prohibition. **`We are protecting you from what you could do`** It is an invalid argument for either as it strips us of our God-given inalienable Declarational Liberty. _**natch**_ – rabbit Jul 20 '20 at 14:29
  • But yes, Smalltalkers do love their Smalltalk, you are entirely correct. I do not get the feeling that Java devs share in this enthusiasm towards Java. Perhaps one IDE over another...but no the language. What is to get excited about? Applets? Cheese. – rabbit Jul 20 '20 at 14:34
  • The whole point of one thread is to ensure thread safe operation. If each object can only be interacted with on one thread, then no need to semaphores and their troubles. So there is method to madness. – rabbit Jul 20 '20 at 14:36
  • I think you are drifting off topic now. Language and concurrency designs come in various flavors and discussing their merits and shortcomings is clearly out of scope of your question. In general Stack Overflow is a place for solutions, not for debate. – JayK Jul 20 '20 at 14:51
  • Agreed. My apologies but I think I make sense. Perhaps not appropriate. This comes down to **In Java, how to handle exceptions without blocking the throwing thread?**. I agree a _Java_ Promise probably handles a promise rejection differently than opening a debugger but not blocking the event loop thread. It is what it is. Please, carry on. – rabbit Jul 20 '20 at 14:55
  • Fine, no room to compare language/runtime features. Still, I would point out that while this post has an answer that I posted, there is **NO SOLUTION!** – rabbit Jul 20 '20 at 15:17
  • Here is a new thread: [Squeak versus Java VM](https://stackoverflow.com/questions/62998833/squeak-versus-java-vm), to rebase to the correct scope of discussion, after you guided me. Also looking for solutions. Java 15? addMethod:/#become:/addMethod:/#copyStack. – rabbit Jul 20 '20 at 15:32

2 Answers2

1

Since you are asking with a reference to Squeak/Smalltalk, I am not sure how mighty you want your tool to be. Especially concerning the stack copying in anException signalerContext copyStack and possibly continuing the copied ongoing computation, the effort in Java might be significantly higher.

To simply view the stack frames, you can use Throwable.getStackTrace. You can get hold of an exception (which is a Throwable) by catching it somewhere with try { ... } catch (...) { ... }. You can also get the trace from the currently running Thread anywhere.

After extracting the stack trace, the thread will continue normally on the next line. So it is "unblocked", but not duplicated. Note that if the exception was thrown and you were in a catch block, the stack is already unwound to that point, unlike in Squeak/Smalltalk, which puts the exception handling frames on top of the signaling context. The Java program will continue after the catch block (unless you throw another or the same exception again).

The stack trace you thus obtain is not as powerful as dealing with Squeak/Smalltalk contexts. The StackTraceElements allow you to view some aspects of the trace, but not control them.

For anything debugger-like such as stepping and inspecting local variables, you could study the Java Debug Interface of the Java Platform Debugger Architecture (JPDA). Another way is to study how the Eclipse debugger works. I cannot tell you whether any of this allows you to debug a copy of a Thread though.

JayK
  • 3,006
  • 1
  • 20
  • 26
  • Oh! This is most unfortunate! What a limitation of the Java ecosystem! `Note that if the exception was thrown and you were in a catch block, the **stack is already unwound to that point**, unlike in Squeak/Smalltalk, which puts the exception handling frames on top of the signaling context.` It completely escaped me that this is the case. I have programmed a lot in Java and you get the debugger open on the catch block rewind and replay to the site the exception gets thrown. This is the dev workflow dealing with exceptions. In Squeak, the stack includes the signaler context. – rabbit Jul 20 '20 at 13:15
  • This is for the Java version of Squeak's PromisesLocal, such that the exception is captured and displayed, while the event loop proceeds. In Squeak doIt to: `Installer ss project: 'Cryptography'; install: 'PromisesLocal'.` See my altered method: `StandardToolSet>>#debugEventualException: anException` – rabbit Jul 20 '20 at 13:19
  • I have looked at: [Continuations in Java](https://stackoverflow.com/questions/1456083/continuations-in-java) [Class Continuation](http://commons.apache.org/sandbox/commons-javaflow/apidocs/index.html) [Apache Commons Javaflow](http://commons.apache.org/sandbox/commons-javaflow/tutorial.html) [Why Continuations are coming to Java](https://www.infoq.com/presentations/continuations-java/) [Project Loom](http://cr.openjdk.java.net/~rpressler/loom/JVMLS2018.pdf) On page 9 the slides shows the Continuation being created with SCOPE. What is SCOPE? Is that the stack? – rabbit Jul 20 '20 at 13:35
1

I would change the title to In Java, how to handle exceptions without blocking?, if I could. The answer seems to be one cannot do so. Not possible..

So, this question is answered in the negative. Not possible.

rabbit
  • 111
  • 9