Java thread trobleshooting for SwingWorker like tasks - java

Thread dump contains wealth of information. For example, if I suspect some action fired more than once, then all I need to do is dumping stack trace each time the action is fired, then investigate the stacks for erroneous action firing.
In certain situations developers are encouraged to abandon conceptual simplicity of sequential execution. For example, Swing offers SwingWorker helper to work around limitations of single threaded EDT. Now, if I dump stack trace, it is useless, because the action is fired by SwingWorker, and there is no information on who initiated SwingWorker task.
So, how do I troubleshoot? Is there a clever trick of "redirecting" thread dump to follow the genuine cause?

You can extend SwingWorker to record the stack when it is created (or when execute but then you need to create another execute method since it is final). Creating the cause is relative expensive though so you might want to do it only when debug (check log level or some such)
import java.util.concurrent.ExecutionException;
import javax.swing.SwingWorker;
public abstract class TracedSwingWorker<T, V> extends SwingWorker<T, V> {
private final Exception cause;
public TracedSwingWorker() {
super();
this.cause = new Exception("TracedSwingWorker created at:");
}
#Override
protected final T doInBackground() throws Exception {
try {
return doWorkInBackground();
}
catch(Exception e) {
if(this.cause != null) {
Throwable cause = e;
while(cause.getCause() != null) {
cause = cause.getCause();
}
cause.initCause(this.cause);
}
throw e;
}
}
protected abstract T doWorkInBackground();
// just for testing
public static void main(String[] args) {
new TracedSwingWorker<Void, Void>() {
#Override
protected Void doWorkInBackground() {
throw new IllegalArgumentException("Exception in TracedSwingWorker!");
}
#Override
protected void done() {
try {
get();
}
catch (InterruptedException e) {
e.printStackTrace();
}
catch (ExecutionException e) {
e.printStackTrace();
}
}
}.execute();
}
}
prints:
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Exception in SwingWorker!
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
<snip>
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.Exception: SwingWorker created at:
at TracedSwingWorker.<init>(TracedSwingWorker.java:15)
at TracedSwingWorker$2.<init>(TracedSwingWorker.java:60)
at TracedSwingWorker.main(TracedSwingWorker.java:60)

I might be telling you something you already know but I suggest ThreadDump
http://www.oracle.com/technetwork/java/javase/tooldescr-136044.html#gbmpn
If you use IDE, then this is good:
NetBeans
http://netbeans.org/kb/docs/java/debug-multithreaded.html
I used Eclipse for this a lot. Debugger view has means of visualizing and tracking multiple threads, printing stack and pausing them.

Related

Retrieve contents of all stack traces being printed to the console?

I want to individually log every unique error I have, as searching though a dozen log files each +10k lines in length is time wasting and tedious.
I catch all exceptions I possibly can, but oftentimes other threads or libraries will shoot off their own errors without any way to process them myself.
Is there any workaround for this?
(E.G. an event for when printStackTrace() is called.)
Is there any workaround for this?
(E.G. an event for when printStackTrace() is called.)
Remap System.err to intercept throwables. If you look at the source code for Throwable.printStackTrace() you'll see that it indirectly calls System.err.println(this);
For example:
import java.io.PrintStream;
public class SpyPrintStream extends PrintStream {
public static void main(String[] args) {
System.setErr(new SpyPrintStream(System.err));
System.setOut(new SpyPrintStream(System.out));
new Exception().printStackTrace();
}
public SpyPrintStream(PrintStream src) {
super(src);
}
#Override
public void println(Object x) {
if (x instanceof Throwable) {
super.println("Our spies detected "+ x.getClass().getName());
}
super.println(x);
}
}
Keep in mind there is all kinds of issues with using this code and it is not going to work in cases where printStackTrace is called with stream that is not standard stream.
You could always do a deep dive into java.lang.instrument if you really want to trap all exceptions.
I catch all exceptions I possibly can, but oftentimes other threads or libraries will shoot off their own errors without any way to process them myself.
Most libraries either throw exceptions back to the caller or use a logging framework. Capture the exception or configure the logging framework.
I want to individually log every unique error I have, as searching though a dozen log files each +10k lines in length is time wasting and tedious.
Logging frameworks include options to deal with this. DuplicateMessageFilter is an example.
Food for thought:
public class DemoClass {
private Map<String, Exception> myExceptions = new HashMap<>();
public void demoMethod() {
try {
// throwing an exception for illustration
throw new IOException("some message");
} catch (IOException e) {
myExceptions.putIfAbsent(e.getLocalizedMessage(), e);
// actually handle the exception
...
}
}
public void finished() {
for (Exception e : myExceptions.values()) {
e.printStackTrace();
}
}
}
You could store any exception you haven't seen yet. If your specific scenario allows for a better way to ensure you only save an exception only once you should prefer that over mapping by Exception.getLocalizedMessage()

Correct use of ProgressMonitorDialog's cancel button, interrupting threads, and showing progress

I've been using Java for a few years, but my thread knowledge is rubbish. I've Googled pretty heavily and found some good information about general use of ProgressMonitorDialog but nothing like my exact circumstances.
I'm currently using a ProgressMonitorDialog as a wrapper around an instance of IRunnableWithProgress, which in turn is a wrapper around a Thread. This works fine but now I'm trying to make the cancel button trigger an interrupt on the running thread, which I can handle to gracefully terminate the operation.
One important thing to note is that I have two plugins; "Data" and "UI". The data plugin contains all of the real work, and must be independent from the UI or any Eclipse plugins. The UI plugin should be as thin as possible.
Here's a distilled version of the code I've got so far.
Data:
public class Data {
public static Thread createThread() {
return new Thread() {
#Override
public void run() {
Thing t = new Thing();
t.operationA();
t.operationB();
t.operationC();
}
}
}
}
UI:
public class UI {
public void doOperation() {
try {
new ProgressMonitorDialog(getShell()).run(true, true, new MyOperation());
}
catch (Exception e) {
e.printStatckTrace();
}
}
public class MyOperation implements IRunnableWithProgress {
#Override
public void run(IProgressMonitor monitor) throws InterruptedException, InvocationTargetException {
monitor.beginTask("Task", 2);
try {
Thread myThread = Data.createThread();
myThread.start();
monitor.worked(1);
while (myThread.isAlive() && !monitor.isCanceled()) {}
if (monitor.isCanceled()) {
myThread.interrupt();
}
monitor.worked(1);
}
finally {
monitor.done();
}
}
}
}
So when the cancel button is clicked, myThread.interrupt() is called. Now the thread needs to respond to the interrupt. Data.createThread() now looks something like this:
public static Thread createThread() {
return new Thread() {
#Override
public void run() {
Thing t = new Thing();
t.operationA();
if (Thread.currentThread.isInterrupted()) {
// Tidy up
return;
}
t.operationB();
if (Thread.currentThread.isInterrupted()) {
// Tidy up
return;
}
t.operationC();
if (Thread.currentThread.isInterrupted()) {
// Tidy up
return;
}
}
}
}
It might be rather verbose polling the interrupted state like this, but I can't see this causing any problems.
But, what if Thing.operationA() wasn't atomic, and could be interrupted within that function:
public class Thing {
public void operationA() {
atomic1();
// How would I detect and handle a change to the interrupted state here?
atomic2();
}
public void operationB() {
// One atomic operation
}
public void operationC() {
// One atomic operation
}
}
How would I detect and handle a change to the interrupted state between atomic1() and atomic2()? Is it as simple as polling Thread.currentThread.isInterrupted() again? Or will I need to pass around some volatile object to track the interrupted state? Should I be throwing InterruptedException somewhere?
My second question is about tracking and reporting progress. I understand how IProgressMonitor.worked() should be used. As already seen, my Data thread contains 3 operations. Is it possible to pass that information up to the UI so I can track the progress in the ProgressMonitorDialog?
Ideally, something like this:
public static Thread createThread() {
return new Thread() {
#Override
public void run(IProgressMonitor monitor) {
Thing t = new Thing();
t.operationA();
monitor.worked(1);
if (Thread.currentThread.isInterrupted()) {
// Tidy up
return;
}
t.operationB();
monitor.worked(1);
if (Thread.currentThread.isInterrupted()) {
// Tidy up
return;
}
t.operationC();
monitor.worked(1);
if (Thread.currentThread.isInterrupted()) {
// Tidy up
return;
}
}
}
}
However as stated, Data cannot depend on Eclipse and therefore passing the IProgressMonitor doesn't work in this case.
Could I have a variable tracking progress in my thread, and then call something like myThread.getProgress() asynchronously from the UI thread to update the progress bar with new work? I'm not sure how feasible this is (it popped into my head as I was writing this question) so I'll try that next.
Lots of information and question marks in here, sorry if my style is a bit scattered. I could elaborate more if needs be but this is already a wall of text. Any information, advice or ideas appreciated.
Between atomic1() and atomic2() you do need to check for Thread.currentThread.isInterrupted() to cleanup in case of canceling. No need to throw an exception if you handle what is needed.
As for progress tracking, you can create your own listener object in the Data plugin and allow passing it to the thread. the UI will instantiate it and pass it to the thread. this way the Data can pass progress events to the UI without dependencies.

Catch EDT exceptions in a NetBeans environment

I want to catch all uncaught exceptions and bring up a dialog. First I removed the default exception handler from NetBeans and added my handler as default handler:
java.util.logging.Logger global = java.util.logging.Logger.getLogger("");
for (Handler handler : global.getHandlers()) {
if (handler.getClass().getName().equals("org.netbeans.core.startup.TopLogging$LookupDel"))
{
global.removeHandler(handler);
break;
}
}
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
The handler looks like this:
public static final class ExceptionHandler implements UncaughtExceptionHandler
{
#Override
public void uncaughtException(Thread thread, Throwable throwable)
{
logger.error(throwable.getMessage(), throwable);
ExceptionViewPanel.showException(throwable);
}
}
With that construct, I can only catch exceptions which are thrown outside the EDT. I've read about ThreadGroups, but I can't use that solution due we use NetBeans with Maven and so I can't wrap the start thread with a ThreadGroup. The hack from pre-1.7 is also no longer possible and overwriting the EventQueue has no effect.
I've tried many solutions, none of them worked. Does anyone has another solution for me that might work?
Thanks in advance
Teazl
In my own project I've superseded NetBeans error handler to my own. My example:
#ServiceProvider(service = Handler.class, supersedes = "org.netbeans.core.NbErrorManager")
public class MyHandler extends Handler {
#Override
public void publish(LogRecord record) {
if (record.getThrown() != null) {
record.getThrown(); // do with it something
}
}
#Override
public void flush() {
}
#Override
public void close() throws SecurityException {
}
}
See also org.netbeans.core.NbErrorManager and org.netbeans.core.NotifyExcPanel to know how NetBeans uses default handler.
You only need to add this class in your project.

Get and send messages with Java Threads

I want to make a thread, which runs, computes something with the data i give it, and returns a few values, or an object. The thread is a part of a Swing GUI.
My question: How can I make a method that runs when I make the thread, and returns an object (or whatever I want it to return)?
My code:
private void nextTurn () {
// do something
if (turn == white) {
try {
Engine e = new Engine(); // Engine is implemented by runnable
e.start();
Move m = e.getBestMove (board);
// thread should work, next code should be excecuted immediately
}
catch (Exception e) {}
}
// end of Main class
}
This is the first time I am working with Threads, and I know you should avoid them if possible, but I need it this time for my GUI.
The info on the Oracle site on Threads did not help me out. I am able to make a program with multiple Threads that runs indefinately, but I can't make it work with functions.
Since this is with a Swing GUI, consider using a SwingWorker object which creates a background thread (all the code run in the doInBackground method), and then can return a final result and/or interim results. Information on how to use this is well documented in the tutorials here:
Concurrency in Swing
SwingWorkers have property change support and thus will allow listeners to observe its state (as a SwingWorker.StateValue) via a PropertyChangeListener. This is one way your program can determine that the thread has completed its processing, get the returned result and go from there.
On an unrelated note, this isn't in your production code is it?:
catch (Exception e) {}
If so, you will likely want to fix this as ignored exceptions can bite you in the tail big time.
e.g.,
if (turn == white) {
try {
final SwingWorker<Move, Void> mySwingWorker = new SwingWorker<Move, Void>() {
#Override
protected Move doInBackground() throws Exception {
Engine e = new Engine(); // Engine is implemented by runnable
e.start();
Move m = e.getBestMove(board);
return m;
}
};
mySwingWorker.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (StateValue.DONE == mySwingWorker.getState()) {
try {
Move m = mySwingWorker.get();
// TODO: insert code to run on the EDT after move determined
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
});
mySwingWorker.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
I suggest you use an ExecutorService. It allows you to create a thread pool, you can pass tasks to it and get the results later.
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

How to throw a checked exception from a java thread?

Hey, I'm writing a network application, in which I read packets of some custom binary format. And I'm starting a background thread to wait for incoming data. The problem is, that the compiler doesn't let me to put any code throwing (checked) exceptions into run(). It says:
run() in (...).Listener cannot implement run() in java.lang.Runnable; overridden method does not throw java.io.IOException
I want the exception to kill the thread, and let it be caught somewhere in the parent thread. Is this possible to achieve or do I have to handle every exception inside the thread?
To be able to send the exception to the parent thread, you can put your background thread in a Callable (it allows throwing also checked exceptions) which you then pass to the submit method of some Executor. The submit method will return a Future which you can then use to get the exception (its get method will throw an ExecutionException which contains the original exception).
Caveat: this may not meet your needs if you have to use the exception mechanism.
If I understand you correctly, you don't actually need the exception to be checked (you've accepted the answer suggesting an unchecked exception) so would a simple listener pattern be more appropriate?
The listener could live in the parent thread, and when you've caught the checked exception in the child thread, you could simply notify the listener.
This means that you have a way of exposing that this will happen (through public methods), and will be able to pass more information than an exception will allow. But it does mean there will be a coupling (albeit a loose one) between the parent and the child thread. It would depend in your specific situation whether this would have a benefit over wrapping the checked exception with an unchecked one.
Here's a simple example (some code borrowed from another answer):
public class ThingRunnable implements Runnable {
private SomeListenerType listener;
// assign listener somewhere
public void run() {
try {
while(iHaveMorePackets()) {
doStuffWithPacket();
}
} catch(Exception e) {
listener.notifyThatDarnedExceptionHappened(...);
}
}
}
The coupling comes from an object in the parent thread having to be of type SomeListenerType.
This answer is based on Esko Luontola one but it provides a working example.
Unlike the run() method of the Runnable interface the call() method of Callable allows to throw some exceptions. Here is an implementation example :
public class MyTask implements Callable<Integer> {
private int numerator;
private int denominator;
public MyTask(int n, int d) {
this.numerator = n;
this.denominator = d;
}
#Override
// The call method may throw an exception
public Integer call() throws Exception {
Thread.sleep(1000);
if (denominator == 0) {
throw new Exception("cannot devide by zero");
} else {
return numerator / denominator;
}
}
}
Executor provides a mechanism to run a Callable inside a thread and to handle any kind of exceptions :
public class Main {
public static void main(String[] args) {
// Build a task and an executor
MyTask task = new MyTask(2, 0);
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
try {
// Start task on another thread
Future<Integer> futureResult = threadExecutor.submit(task);
// While task is running you can do asynchronous operations
System.out.println("Something that doesn't need the tasks result");
// Now wait until the result is available
int result = futureResult.get();
System.out.println("The result is " + result);
} catch (ExecutionException e) {
// Handle the exception thrown by the child thread
if (e.getMessage().contains("cannot devide by zero"))
System.out.println("error in child thread caused by zero division");
} catch (InterruptedException e) {
// This exception is thrown if the child thread is interrupted.
e.printStackTrace();
}
}
}
What I do is to catch the exception in the thread and store it as a member variable of the Runnable. This exception is then exposed via a getter on the Runnable. I then scan all the threads from the parent to see if any had exceptions, and take the appropriate action.
If you really cannot do anything useful when the exception is raised you can wrap the checked exception in a RuntimeException.
try {
// stuff
} catch (CheckedException yourCheckedException) {
throw new RuntimeException("Something to explain what is happening", yourCheckedException);
}
the thread can't throw the exception to any other thread (nor to the main thread). and you cannot make the inherited run() method throw any checked exceptions since you can only throw less than the inherited code, not more.
If your thread's code throw a RuntimeExpection, you doesn't need to add run() throw Exception.
But use this solution only when appropriate because this can be a bad pratice:
http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html
Any RuntimeException or unchecked Exception can help you. Maybe you'll need to create your own RuntimeException
On the assumption that your code is in some kind of loop, you'd write:
public class ThingRunnable implements Runnable {
public void run() {
try {
while(iHaveMorePackets()) {
doStuffWithPacket()
}
} catch(Exception e) {
System.out.println("Runnable terminating with exception" + e );
}
}
}
The exception will automatically break you out of your loop, and at the end of the run() method, the thread will stop.
Use this Runnable to create your Thread:
public abstract class TryRunner implements Runnable{
protected abstract void tryToRun();
protected void onException(Exception e){}
#Override
final public void run() {
try{ tryToRun(); }catch(Exception e){ e.printStackTrace(); onException(e); }
}
}
Wrapping your exception inside a RuntimeException seems to do the trick.
someMethod() throws IOException
{
try
{
new Thread(() ->
{
try
{
throw new IOException("a checked exception thrown from within a running thread");
}
catch(IOException ex)
{
throw new RuntimeException("a wrapper exception", ex); // wrap the checked exception inside an unchecked exception and throw it
}
}).start();
}
catch(RuntimeException ex) // catch the wrapped exception sent from within the thread
{
if(ex.getCause() instanceof IOException)
throw ex.getCause; // unwrap the checked exception using getCause method and use it however you need
else
throw ex;
}
}

Categories