can't show caught exception (newSingleThreadScheduledExecutor) - java

for schedule executor:
executor = Executors.newSingleThreadScheduledExecutor();
Runnable ppt = new Runnable() {
public void run() {
try {
processTask();
} catch(Exception e) {
System.out.println(e.getMessage());
//need to be aware of this exception, no message is outputted
}
}
};
executor.scheduleWithFixedDelay(ppt, 0, 1000/20, TimeUnit.MILLISECONDS);
for processTask method:
private void processTask() {
try {
//task business logic
} catch(SomeOtherException e) {
System.out.println(e.getMessage());
//I want to be aware of this exception also
}
}
I know the task failed for a reason and I don't want it to continue after that point (I use executor.shutdown() to cancel it).
I just need to know what the error was when the exception is caught. It doesn't seem to do it in the above method.
Thanks in advance for any response.

You are putting try catch block in process task also that's why any problem in that method will resolve there and if you call shutdown then control would not return to the above method.
Runnable ppt = new Runnable() {
public void run() {
try {
processTask();
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
};
executor.scheduleWithFixedDelay(ppt, 0, 1000/20, TimeUnit.MILLISECONDS);
In this example you will get '/ by zero exception' and then scheduler will shutdown.
private static void processTask() {
try {
//task business logic
int x=2/0;
} catch(Exception e) {
System.out.println(e.getMessage());
//I want to be aware of this exception also
executor.shutdown();
}
}

Try to use e.printStackTrace(). getMessage() is a method of Throwable class (super class of all exceptions of Java) inherited by every exception class like ArithmeticException. The getMessage() method prints only the message part(If any message is available) of the output printed by object e. While printStackTrace() method prints full stack trace along with the line number where exception occurred with error message- See more at: http://way2java.com/exceptions/getmessage-printstacktrace/#sthash.QMvLohu3.dpuf
As answered by Kostja here
The message and the stacktrace are two distinct pieces of
information. While the stackstrace is mandatory, the message isnt.
Most exceptions deliver a message, and it is the best practice, but
some just don't and there's nothing to be done to fix it.
For more information you can see similar queries here link-1 and link-2.

Related

java Catch exception inside a async callback

I have a callback which may throw a custom exception.
I'm trying to throw it, but it's not being catched on the outer scope, nor the compiler let me catch it, it says: "Exception is never thrown is the corresponding try block", even though it is.
this is my code:
public void openAsync(MessageAsyncCallback callback) {
try {
this.sendChannelOpen(this.getChannel(), getChannelOpenData().getFlags(), new MessageAsyncCallback() {
#Override
public void onComplete() throws NanoException {
// INanoPacket message = transport.getMessageByClassName(AudioServerHandshake.class.getName());
INanoPacket message = transport.getMessageByClassName(AudioClientHandshake.class.getName());
Log.info("Got audio server handshake, trying to client-handshake it");
sendClientHandshakeAsync((AudioServerHandshake) message, callback);
}
});
} catch (NanoException e) {
System.exit(-2);
}
}
and it doesn't let me catch NanoException
EDIT:
inside transport.getMessageByClassName I throw a NanoException.
EDIT2:
this is the method who invokes the exception:
public INanoPacket getMessageByClassName(String destClassName) throws NanoException {//} throws NanoException {
long startTime = System.currentTimeMillis(); // fetch starting time
INanoPacket message = this.getMessageFromTCPQueue();
while (!(message.getClass().getName().equals(destClassName)) && isRuntimeValid(startTime)) {
this.insertToTCPQueue(message); // put message back in queue
message = this.getMessageFromTCPQueue();
}
if (!(message.getClass().getName().equals(destClassName))) {
// timeout...
throw new NanoException("Couldn't find destination message: " + destClassName);
}
return message;
}
and I want to handle the exception not even in openAsync but on the method that calls openAsync.
why? because I'm handling messages coming from a remote device, this is why it's async. and I'm using some kind of timeout to wait for a specific message, and if the message isn't coming I want to restart the whole program.
Please notice that in your code you are not invoking onComplete method, you are defining it.
The exception would be thrown in a separate part of the code, possibly separate Thread (as it seems to be async). Therefore the "Exception is never thrown is the corresponding try block" message is right, as the exception will never be thrown when invoking this.sendChannelOpen(...) method.
Your try-catch statement needs to wrap the place where you invoke the onComplete method. As only by invoking onComplete method can you expect NanoException.
EDIT based on comments:
If you need to handle the exception throw in getMessageByClassName you can do it in onComplete method and not rethrow it. If you want to handle it somewhere else, you'd need to provide us the code of sendChannelOpen method or a place where the callback is invoked.
EDIT2 (based on question edits):
Please see the code below, as an example of how you can communicate between threads. I've used Latch, but there are other classes in java.util.concurrent that you may find useful.
BTW, I'm not going into the discussion why you want to restart the whole app on your NanoException, although there might be other options worth considering for recovering from that Exception.
import java.util.concurrent.CountDownLatch;
class NanoException extends Exception {}
interface MessageAsyncCallback {
void onComplete() throws NanoException;
}
public class AsyncApp {
private static final CountDownLatch errorLatch = new CountDownLatch(1);
public static void main(String[] args) {
new AsyncApp().run();
}
void run() {
sendChannelOpen("something", new MessageAsyncCallback() {
#Override
public void onComplete() throws NanoException {
// the whole try-catch-sleep is not really needed, just to wait a bit before exception is thrown
try {
// not needed, just to wait a bit before exception is thrown
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new NanoException();
}
throw new NanoException();
}
});
try {
System.out.println("This is a main thread and we wait here, while the other thread executes...");
errorLatch.await();
System.out.println("Latch has reached 0, will now exit.");
System.exit(-2);
} catch (InterruptedException e) {
System.out.println("Error in main thread.");
System.exit(-1);
}
}
void sendChannelOpen(String notImportant, MessageAsyncCallback troublesomeCallback) {
runSomethingInSeparateThread(troublesomeCallback);
}
void runSomethingInSeparateThread(MessageAsyncCallback troublesomeCallback) {
new Thread(() -> {
try {
troublesomeCallback.onComplete();
} catch (NanoException e) {
System.out.println("You can catch it here, and do system exit here or synchronize with main Thread as below");
errorLatch.countDown();
}
}).start();
}
}

How to deal with the situation when the ExecutorService ThreadFactory returns a null instead of a thead

I asked this question before but was unable to get it opened again as my update didn't kick of the reopen process. So resubmitting it
My question is how to get an ExecutorService to realize that the thread is not valid(null) straight away without having to wait for the get on the future.
I have a use case where when creating a thread in a ThreadFactory I want to return null if the Thread cannot be set up correctly(for example it cant connect to a server).
When the ExecutorService runs a submit on a callable and the ThreadFactory returns null as below the code will run but will wait at future.get(5, TimeUnit.SECONDS); and then throw a TimeoutException. The problem is that ThreadFactory.newThread() doesn't allow me to throw an exception here.
public class TestThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
// try to create a conneciton that fails
// I cannot throw an exception here, so if there is a problem I have to return null
return null;
}
}
public class ExecutorServicePool {
public static ExecutorService getService() {
return Executors.newFixedThreadPool(10, new TestThreadFactory());
}
}
public static void main(String[] args) {
ExecutorService executorService = ExecutorServicePool.getService();
Callable callable = new Callable<String>() {
#Override
public String call() throws Exception {
return "callable";
}
};
Future<String> future = executorService.submit(callable);
try {
future.get(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
executorService.shutdown();
}
You could throw a RuntimeException which feels like a sensible thing to do.
RuntimeExceptions are great for situations that are generally not recoverable. Not being able to connect to a database for example is a prime example of one of those situations. Basically in this scenario you want to say:
"Something is really wrong and at the minute I can't process your
request. Try again later"
RuntimeExceptions can be thrown in method implementations even if the Interface does not declare them. So you can update your ThreadFactory implementation to throw a RuntimeException rather than returning null. You could even create a specific RuntimeException sub-class to ensure that it is clear what the error is within your application e.g. FailedToInitialiseThreadException
You can create custom executor service by extending ThreadPoolExecutor and
override methods where threadfactory is called to get new thread, to your need.

How to test a method using sleep() with Java?

I have the following method and I am struggling to get 100% code coverage.
public final class SleepingHelper {
public static void sleepInMillis(Duration timeOfNextTry) {
try {
Thread.sleep(timeOfNextTry.toMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The question is how can I force Thread.sleep to throw an exception?
Edit: since it was marked as duplicate, I am still wondering what I would assert in the test ? The other question Is more generic.
You need to interrupt it from another thread. For example:
Thread t = new Thread() {
public void run () {
SleeperMillis.sleepInMillis(new Duration(10000000l));
}
}.start();
Thread.sleep(100); // let the other thread start
t.interrupt;
You don't need to actually interrupt the thread. You can use PowerMockito to mock the static method Thread.sleep()
#RunWith(PowerMockRunner.class)
#PrepareForTest(Thread.class)
public class TestClass {
#Test
public void testSleepInMillis() throws Exception {
PowerMockito.mockStatic(Thread.class);
PowerMockito.doThrow(new InterruptedException ()).when(Thread.class);
try {
SleepHelper.sleepInMillis(11);
fail("expected exception");
} catch (InterruptedException e) {
System.out.println("all good");
}
}
You don't test it, because you can't assert its results, and you can't assert it because Thread.sleep is not accurate or guaranteed to sleep for this duration of time, and the test results will differ from run to run.
Mocking is a better option here.
Btw, it is not just that your tests aren't predictable, your code that uses Thread.sleep in production is going to be unpredictable for the same reasons. Thread.sleep(some magic number goes here) usually indicates a badly written program.
I wouldn't bother testing it. 100% coverage is excessive. However, you could do it like this:
#Test
public void testException() throws Exception {
// Capture the system error stream, so that we can test that the expected exception is printed.
ByteArrayOutputStream capturedErrors = new ByteArrayOutputStream();
System.setErr(new PrintStream(capturedErrors));
// Create a new thread on which to run the candidate method.
Thread thread = new Thread() {
#Override
public void run() {
SleepingHelper.sleepInMillis(Duration.ofMillis(10));
}
};
// Start the second thread.
thread.start();
// Interrupt the second thread. (The candidate method hasn't finished yet. It takes 10 milliseconds to run.)
thread.interrupt();
// Wait for the thread to die (and write out the stack-trace).
thread.join();
// Test that the expected exception's stack trace was printed to the system error stream.
// The output should start with the exception's name.
String output = capturedErrors.toString();
int lengthOfExceptionName = "java.lang.InterruptedException".length();
assertEquals(output.substring(0, lengthOfExceptionName), "java.lang.InterruptedException");
}

Catch Exception from running Thread

I want to catch an exception from a running thread and handle it in the calling thread. How would I to that the best way?
try {
Runnable connect = new Runnable() {
public synchronized void run() {
try {
... some code requiring long time
} catch(Exception e) {
..I want to catch here and send to calling thread
}
}
}
synchronized(connect) {
new Thread(connect).start();
connect.wait();
...if exception then handle it
...keep on with code if no exception occurred
}
} catch(Exception e) {
}
The best was is to not use Thread directly, but instead use a Future. you can run a FutureTask via a Thread if you desire, or get a Future by submitting a Callable to an Executor (the preferred method). the Future gives you a convenient way to wait for the task to complete and to deal with the results (regular or exceptional).

How to restart thread in java? [duplicate]

This question already has answers here:
How to start/stop/restart a thread in Java?
(9 answers)
Closed 7 years ago.
I have created a program which searches for files in a source folder. If it finds any file, it processes that file and moves it to a destination folder, then looks for a new file in the source folder. It has to keep on checking the source folder for a file.
I have used a thread to look for files in the source folder. The problem I am facing is whenever any exception is thrown during file processing, the thread gets stopped. I want the thread to be running even if an exception is thrown. It has to move the file that caused the error to some other folder and look for a new file in the source folder. How can I make the thread keep on running?
Eg:
public void run() {
try {
searchfile();
}
catch(Exception e) {
e.printStackTrace();
}
}
public void searchfile(){
...
}
Update :
I should be more clear in my question. Actually there are 4 source folders and 4 destination folders. I have to perform the same operation in each source & destination pair. So i have created 4 threads in one class and do the operation in separate class.
class MainClass
{
public static void main(String[] args){
for(int i=0;i<4;i++){
SearchClass search = new SearchClass();
Thread thread = new Thread(search);
thread.start();
}
}
}
class SearchClass
{
public void run() {
try {
searchfile();
} catch(Exception e) {
e.printStackTrace();
}
}
public void searchfile(){ ... } }
All the thread wont stop running eventhough it caught any exception in middle. How can i do that?
If a thread is dying due to an uncaught exception, the answer is simple: catch the exception at an appropriate place so that you can keep going. Either catch the exception within your searchfile method, or make the run method call searchfile in a loop.
If you want your thread to keep running use a loop.
public void run() {
while(!Thread.interrupted())
try {
searchfile();
}
catch(Exception e) {
e.printStackTrace();
}
}
Inside your catch, you can move the file to the error folder then create a new object of the same thread and start it again.
unless i got you wrong, your code is missing the "keep running" nature, i.e. you need to have a loop somewhere:
public static void main(String[] args){
ExecutorService service = Executors.newFixedThreadPool(4);
// for each of your 4 folders
while (true) {
Future<File> searchResult = service.submit(new SearchTask());
try {
File foundFile = searchResult.get();
// handle found file
} catch (Exception e) {
// handle exception
}
}
}
private static class SearchTask implements Callable<File> {
#Override
public File call() {
return searchFile();
}
public File searchFile() {
// search & return found file
}
}
note that this is just a very simple extension of your example. it is still missing the parametrization of the SearchTask to actually be specific for a folder, handling of files & exceptions, etc. as mentioned in previous answers, your SearchTask should implement Runnable (i prefer Callable...), and IMHO it's always better to use an ExecutorService than to spawn threads manually. hope this helps...
I'm not entirely sure if this will work, yet here's a try.
public void run() {
try {
searchFile();
} catch(Exeption e) {
e.printStackTrace();
if(!Thread.currentThread().isAlive())
Thread.currentThread().start();
}
}
you said that the exception may be thrown during file process , so i put the processFile() in a try-catch block. but if it may be thrown during search, you may put it in a try-catch too.
public void run() {
while(!terminated) {
findNextFile();
try {
processFile();
} catch {
// handle error
}
}
}
Here are my assumptions based on your question and your clarification:
Each thread, in the run() method, only calls searchfile() once and not in a loop
your searchfile() method has a loop in it and you want that loop to continue running even if an exception is thrown in it.
you have some way of initializing each thread that you aren't showing us (and that isn't terribly important for this specific quiestion)
searchfile() does not declare that it throws any Exception
You aren't using a logging framework, but are instead using System.out (although using a logging framework is a Really Good Idea
Java 5 is OK (otherwise you'll have to use a different for() loop below
With these assumptions, you don't want to plan to catch an Exception in your run() method except for the purpose of logging that something went very wrong:
public void run() {
try {
searchfile();
} catch (RuntimeException e) {
System.out.println("Something went very wrong! Unexpected RuntimeException");
e.printStackTrace();
}
}
Note that the code catches RuntimeException. Always catch the most specific Exception that will do what you need. Then what you need is something such as the following in your searchfile() method:
File[] files = directory.listFiles();
for (File file : files) {
try {
// Do your normal file/directory processing here
} catch (Exception e) {
System.out.println("Exception processing file " + file.getName() + " " + e);
// Move "file" to another area
}
}
Since you are trapping unexpected Exceptions in the main loop of your Thread, your thread will continue processing after handling the Exception.
You can easily go with a workaround. Just run the needed logic for some amount of times and finish the job based on some criteria.
public class ThreadRestartWorkaround extends Thread {
public static void main(String[] args) {
ThreadRestartWorkaround th = new ThreadRestartWorkaround(5);
th.start();
}
private int maxCycles;
private int currentCycle;
public ThreadRestartWorkaround(int maxCycles) {
this.maxCycles = maxCycles;
}
#Override
public void run() {
while(executeSomeLogicUntilReachingTheLimit());
System.out.println("Finished due to exceeding the maxCycles config");
}
private boolean executeSomeLogicUntilReachingTheLimit() {
currentCycle++;
System.out.println("Executing logic for " + currentCycle + " time");
return currentCycle < maxCycles;
}
}
And the output is
Executing logic for 1 time
Executing logic for 2 time
Executing logic for 3 time
Executing logic for 4 time
Executing logic for 5 time
Finished due to exceeding the maxCycles config

Categories

Resources