Sometimes, you just have to catch Throwable, e.g. when writing a dispatcher queue that dispatches generic items and needs to recover from any errors (said dispatcher logs all caught exceptions, but silently, and then execution is continued on other items).
One best practice I can think of is to always rethrow the exception if it's InterruptedException, because this means someone interrupted my thread and wants to kill it.
Another suggestion (that came from a comment, not an answer) is to always rethrow ThreadDeath
Any other best practices?
Probably the most important one is, never swallow a checked exception. By this I mean don't do this:
try {
...
} catch (IOException e) {
}
unless that's what you intend. Sometimes people swallow checked exceptions because they don't know what to do with them or don't want to (or can't) pollute their interface with "throws Exception" clauses.
If you don't know what to do with it, do this:
try {
...
} catch (IOException e) {
throw new RuntimeException(e);
}
The other one that springs to mind is to make sure you deal with exceptions. Reading a file should look something like this:
FileInputStream in = null;
try {
in = new FileInputStream(new File("..."));;
// do stuff
} catch (IOException e) {
// deal with it appropriately
} finally {
if (in != null) try { in.close(); } catch (IOException e) { /* swallow this one */ }
}
Depends on what you are working on.
if you are developing an API to be used by some one else, its better to re-throw the Exception or wrap it into a custom exception of yours and throw.
Whereas if you are developing an enduser application you need to handle this exception and do the needful.
What about OutOfMemoryError (or perhaps its super class VirtualMachineError)? I can't imagine there is much you can do after something that serious.
If you're writing a dispatcher queue, then by the time the exception comes back to you there's no point in doing anything with it other than logging it. The Swing event queue has basically that type of behavior.
Alternatively, you could provide a hook for an "uncaught exception handler," similar to ThreadGroup. Be aware that the handler could take a long time, and end up delaying your dispatcher.
As far as InterruptedException goes: the only thing that cares about that is your dispatch loop, which should be checking some external state to see if it should stop processing.
Related
I'm in the process of updating from picocli 3.9.6 to 4.2.0, and I'm running into an issue when replacing old deprecated calls with the new versions.
In my original version, I had a code block like this:
try {
return commandLine.parseWithHandlers(
new RunLast().useOut(ps),
new ExceptionHandler(),
args);
}
catch(Exception e) {
// handle exceptions
}
The ExceptionHandler handles both parameter and execution exceptions -- both are rethrown, but parameter exceptions get the help text added to the exception text. The catch would get hit in cases where, e.g., a command was given bad args. The catch would ensure the error was printed in the UI.
I attempted to update it like this:
try {
commandLine.setOut(pw);
ExceptionHandler handler = new ExceptionHandler();
commandLine.setExecutionExceptionHandler(handler);
commandLine.setParameterExceptionHandler(handler);
commandLine.execute(args);
return commandLine.getExecutionResult();
}
catch(Exception e) {
// handle exceptions
}
With this new version, exceptions are thrown as before, but they are no longer caught by the catch block after being rethrown by the ExceptionHandler. How can I catch these exceptions?
One of the changes in picocli 4.x is the new execution framework. The user manual has a section on migration that may be useful.
By design, the CommandLine::execute method never throws an exception. So there is no need to surround the call to CommandLine::execute with a try/catch block (unless you need to catch an Error or Throwable).
Instead, you can optionally specify custom exception handlers, like you already do in your example. These exception handlers is where you can show an error message to the users. (Perhaps a combination of what was in the previous ExceptionHandler and the logic that previously was in the catch block.)
The ParameterExceptionHandler is invoked when the user provided invalid input. The default handler shows an error message, may suggest alternative spellings for options or subcommands that look like a typo, and finally displays the usage help message. The Handling Errors section of the user manual has an example ShortErrorMessageHandler that may be useful when the usage help message is so long that it obscures the error message.
The ExecutionExceptionHandler is invoked when the business logic throws an exception. The default handler just rethrows the exception, which results in a stack trace being printed. The Business Logic Exceptions section of the user manual shows an alternative.
It sounds like you need a custom ExecutionExceptionHandler that prints a stack trace followed by the usage help message.
I am using the jSerialComm library to communicate to and from the SerialPort. I have written a SerialDataListener to read the bytes with an overridden serialEvent method that looks like this:
#Override
public void serialEvent(SerialPortEvent event) {
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) return;
int numBytesAvailable = serialPort.bytesAvailable();
if (numBytesAvailable < 0) {
logger.error("Port is not open.. returning without any action");
return;
}
byte[] newData = new byte[numBytesAvailable];
int readData = serialPort.readBytes(newData, numBytesAvailable);
for (int i = 0; i < numBytesAvailable; i++) {
byte b = newData[i];
logger.info("Starting new response");
response = new Response();
response.addByte(b);
}
}
Now, if I do receive data and the subsequent code gets into a NUllPointerException somehow (one example being that the response's constructor is invoked and throws an NPE), then the SerialPort has been programmed inside the library's SerialPort class to
stop listening and
Swallow the exception
As a consequence of 1 and 2, no more data arriving on the SerialPort can be processed. There is neither an exposed API to see if the listener is stopped and restart it. I can neither take any action like reopening the SerialPort.
Here is that piece of code:
//Line 895 of the class SerialPort) (from dependency: com.fazecast:jSerialComm:1.3.11).
while (isListening && isOpened) { try { waitForSerialEvent(); } catch (NullPointerException e) { isListening = false; } }
Here are the questions:
Why was the exception swallowed and listening stopped inside the library? Are there any design reasons?
The SerialPort class itself is final and hence writing my own implementation of the class to replace the swallow is out of question. How do I proceed? Apart from this issue, jSerialComm appears to satisfy most other use cases decently well, so I may not migrate from it anytime soon.
One way is to catch it myself and do the handling. But I do not want to do it unless the answer for Q1 is clear. I have tried to investigate but not found any practical reasons for disabling the listening and not announcing the exception.
Why just a NPE, other exceptions could arise too. So then at least, I will have to handle the exceptions myself. Is this approach of my own handlers correct then?
TIA
Rahul
1) Why was the exception swallowed and listening stopped inside the library? Are there any design reasons?
You would need to ask the author of the code.
However, it does seem to be intentional, since the waitForSerialEvent is declared as throws NullPointerException.
If I were you, I would dig deeper into where the NPEs are thrown and why. Modify the code to print a stacktrace instead of just squashing the exception entirely. It could be a "hack" workaround, or there could be a legitimate reason for doing this.
If we make the assumption that the client's listener code could throw an NPE, then in my view it is a mistake for the event thread to assume that all NPEs can be squashed.
But looking at the code, I can also see places where NPE's are being thrown deliberately to (apparently) signal there is an error; e.g. in the read methods in SerialPortInputStream. So it is not clear to me that the NPEs should be squashed at all.
2) The SerialPort class itself is final and hence writing my own implementation of the class to replace the swallow is out of question. How do I proceed?
The code is on GitHub, so you could fork the repository, develop a patch and submit a pull request.
4) Why just a NPE, other exceptions could arise too. So then at least, I will have to handle the exceptions myself. Is this approach of my own handlers correct then?
Good question.
But really, all of these questions are best addressed to the author of the code. He does seem to respond to questions posted as issues ... if they are pertinent.
I have a service, and I would like it to have the following behavior:
If service receives InterruptedException, or JVM shuts down, it should try to stop gracefully
If there's some "catastrophic" event, the service should just quit
Any other exception should be logged, state should reset, and loop should keep running
Loop should not quit under any other circumstance.
So here's a overly simplified version of what I came up with.
On class level:
private static volatile boolean keepRunning = true;
static {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
keepRunning = false;
}
});
}
And then the loop:
while(keepRunning) {
try {
// Do something useful
Thread.sleep(10000); // just an example of something that can cause InterruptedException
}
catch(InterruptedException e) {
keepRunning = false;
}
catch(Exception e) { // catches all exceptions, but not any errors
// log it
// reset state
}
}
if(!keepRunning) {
// shut down gracefully
}
It seems satisfies all 4 conditions, but there are some problems and unclear parts:
(problem) Catching Exception and not doing anything is against all good practices. But is it acceptable in this case, or there's a better solution?
(question) Is not catching Error all I need to do to satisfy condition #2? Or are there other situations I should be aware of?
(unclear) Usually it's recommended that the "shut down gracefully" code goes into finally section after exception, and I don't really like that I have to check it after loop (if(!keepRunning)). But it seems doesn't fit in finally in this case. Is there a better way to do that?
(question) This code is written for Java 7. Would anything be changed/improved with Java 8?
I will appreciate either direct answers to my questions, or pointers to different patterns/solutions. Thanks in advance.
It is ok to catch the Exception in your case.
Not catching Error is a good practice if you run tests.
The finally block is what you should use to shut down gracefully and yes - the if statement in the finally block is needed and generally ok.
If an error occurs, your finally block will still execute so it is all good.
This code is ok for both Java 7 and Java 8
As the title suggested, I have some code wrapped in a while(true) infinite loop, and all of them are fully caught by try and catch block. This thread is started in the main method, however, after long run, this worker thread is vanished mysteriously when I check using the jstack and causing work accumulated.
Below is my code:
public void run() {
while (true) {
try {
// Consumer consumes from Kafka server
Global.KAFKA_METRIC_DATA_CONSUMER.consume(topic, handler);
} catch (Exception e) {
logger.error("Kafka consumer process was interrupted by exception!");
} finally {
try {
// Prevent restart too often
Thread.sleep(30 * BaseConst.SECOND);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
For my understanding, this structure will keep the thread running so is the consumer. Even if the consume() methods failed, it will restart infinitely. However, as I mentioned above, the whole thread disappear silently without any error log. Could anyone provide some clue please?
Some more information that might be helpful:
I have checked the consume method will never shutdown the consumer
nor close the socket to the server. It will continuously try to
connect server after fail.
I analysed the java heap dump, and I found there is a memory leak
somewhere else in the project, causing memory occupation extremely
high and the gc very often. However, the main method is still
running.
OutOfMemoryError is not an Exception. It's an Error derived from Throwable.
If that was thrown somewhere in your consume(topic, handler), finally would still be called, delaying the inevitable some 30s... but after that the error would be passed upward and your loop would be terminated.
You are catching Exception so there's a chance that a java.lang.Error or a java.lang.Throwable is being thrown (eg OutOfMemoryError)
If you really want to catch everything, you'll need to catch Throwable and not just Exception subclasses.
Your thread is probably killed by an error.
An error is not an exception! But they both extend Throwable
Add another catch block that catches errors.
Throwable should never be caught, because errors require a different handling than exceptions
I am designing an Android Application where i want to check details if crash happens. So i used Thread.UncaughtExceptionHandler() Class. It generate detail of Crashed Thread but Application Stuck once crash occur. I want to close my application immediately after crash but also want to detail of Thread. I include following code in the Activity class. Any suggestion?
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.e("UserApp", "uncaught_exception_handler: uncaught exception in thread " + thread.getName(), ex);
if(ex instanceof RuntimeException)
throw (RuntimeException)ex;
if(ex instanceof Error)
throw (Error)ex;
Log.e("UserApp", "uncaught_exception handler: unable to rethrow checked exception");
}
you can try finish(); in your exception block
Try this...
You can use,
YourActivityname.this.finish(); or
android.os.Process.killProcess(android.os.myPid());
You should use first one because it is a best practice, which is to just call finish() and let the OS take care of killing off your process when/if it needs to.
In spite of if you use second one, kill your process in the middle of event handling, all kinds of bad things -it is a bad practice.