Java TimerTask wants variable to be final - java

Anyway so im trying to make something like a chat program and someone told me to use this code to check for new messages while allowing the user to submit a message:
timer.schedule(new TimerTask() {
#Override
public void run() {
read.readChat(line);
}
}, 0, 1000);
//Wait for user input
while(true) {
String bar = scan.next();
}
Where the read.readChat(line); is the method which displays the messages from another file. Java tells me that read and line both have to be declared as final... I dont understand why especially for the "line" because that's a variable and I need it to change.
Additionally after I declare them as final I get this error:
unreported exception java.lang.Exception; must be caught or declared to be thrown
read.readChat(salt);
What am I doing wrong?

Second error tells you that the method read.readChat(line); throws a checked exception so you have to catch.
You cannot use local variables declared at outer class in the Anonymous inner classes. Make them final or declare them as fields (instance variables).
EDIT:
#Override
public void run() {
try
{
read.readChat(line);
}catch(Exception ex)
{
ex.printStackTrace();
}
}

Cody, which thread do you want that exception to be thrown to? Right now the timer task is going to run in another thread (Timer's). So, is the timer thread that is going to deal with it in your current design. If you just want the run to re-throw an exception, you can wrap it to a RuntimeException.
#Override
public void run() {
try {
read.readChat(line);
}catch(RuntimeException ex) {
throw ex;
}catch(Exception ex) {
throw new RuntimeException(ex);
}
}
But, for the Timer it is not going to change anything because the run() method is the last thing the Timer thread is going to see. If you need advanced an error handling, you have to deal with it inside run(). Can you tell a bit more about what you are trying to do?

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();
}
}

Java convert from one exception to another

I have a common project with some shared code that is being used in another project. I'm trying to convert/map the exception from the common project CommonException to a new type of Exception let's call it SuperAwesomeException.
The aim is to have a generic way of handling all custom exceptions in the project.
I've attempted to do this using an UncaughtExceptionHandler. This seems to work when running the project but not from within JUnit, since that wraps each test in a try/catch block as described here.
public final class ExceptionHandler implements Thread.UncaughtExceptionHandler {
#Override
public void uncaughtException(Thread thread, Throwable exception) {
if (exception instanceof CommonException) {
throw new SuperAwesomeException(exception.getMessage());
}
if (exception instanceof SuperAwesomeException) {
throw new CommonException(exception.getMessage());
}
else {
System.out.println("ERROR! caught some other exception I don't really care about");
System.out.println("Not doing anything");
}
}
}
Is there another way I can map from one Exception to another or can I somehow tell JUnit not to catch certain exceptions and check the Exception is mapped to the correct one?
UPDATE - How I initially tried to write the Test:
public class ClassThatThrowsException {
ClassThatThrowsException() {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
}
public void doSomething() {
throw new CommonException("Something boring blew up!");
}
}
public class ClassThatThrowsExceptionTest {
#Test(expected=SuperAwesomeException.class)
public void testAwesome() {
ClassThatThrowsException c = new ClassThatThrowsException();
c.doSomething();
}
}
which throws:
java.lang.Exception: Unexpected exception, expected<SuperAwesomeException> but was<CommonException>
The problem is: when you are using JUnit, the framework will catch your exception. Therefore the uncaught exception handler isn't called in the first place!
See here for more details.
Thus, you have to do two things:
A) write tests that make sure that your exception handler implementation works as desired
#Test(expected=SuperAwesomeException.class)
public void testAwesome() {
new ExceptionHandler().uncaughtException(null, new CommonException("whatever"));
}
B) thest the plumbing - you want to make sure that this specific uncaught handler gets actually set by your code:
#Test
public void testDefaultHandlerIsSet() {
// creating a new instance should update the handler!
new ClassThatThrowsException();
Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler();
assertThat(handler, not(nullValue()));
assertThat(handler, instanceOf(ExceptionHandler.class));
}
Finally - please note: you should not just do new XException(oldException.getMessage). Rather go for new XException("some message, oldException).
In other words: you got a cause here; so you better use the incoming exception as cause within the new one you intend to throw. Otherwise you loose all stack trace information.

Exception at calling one program from another program inside Runnable interface

I am facing problem while I am trying to call another program from Task3 program and try to execute it on scheduled time. Getting exception at line 14 as below.
Please let me know where I am going wrong in call program from run method of Runnable interface.
Task3.java:14: error: unreported exception Exception; must be caught or declar
to be thrown
Mult.main(new String[0]);
import java.util.Timer;
import java.util.TimerTask;
public class Task3 {
public static void main(String[] args) {
TimerTask task = new TimerTask() {
#Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
Mult.main(new String[0]);
}
};
Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1 * 1000;
// schedules the task to be run in an interval
timer.scheduleAtFixedRate(task, delay,
intevalPeriod);
} // end of main
}
Mult.main has a throws clause that includes a checked exception, so for the code to be accepted by the compiler you'd need to add that exception to the throws clause of the run method or catch the exception. You can't add that exception to the throws clause however, since you override TimerTask.run, which declares no exceptions.
The only remaining opitions are catching that error or change Mult.main to not throw any exceptions that are not subclasses of RuntimeException. You could e.g. catch the exception and throw a runtime exception or do something else, if an exception occurs:
TimerTask task = new TimerTask() {
#Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
try {
Mult.main(new String[0]);
} catch (Exception ex) {
// handle the exception,
// in this case by throwing a RuntimeException with ex as cause
throw new IllegalStateException("I didn't expect a exception.", ex);
}
}
};
This is a compile-time error. Your method Mult.main() can throw an Exception.
Surround it with try/catch to handle error, e.g.
try {
Mult.main(new String[0]);
} catch (Exception e) {
// Handle your error here
}
It's hard to tell without more code, but it looks like:
Mult.main(...) is defined as throwing an exception, in which case the code that calls must handle the exception.
Either:
Wrap the call to Mult.main(...) in a try-catch block, or
Define Task3.main(...) to throw Exception as well
P.S. or maybe it's timer.scheduleAtFixedRate(...), can't really tell without line numbers

can't show caught exception (newSingleThreadScheduledExecutor)

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.

Is there a standard JDK interface which a method like void run() throws Exception?

What I want is a standard JDK class that look like this:
interface ExplodingRunnable {
void run() throws Exception;
}
Callable is no good, because its call() method is required to return a value, but I need a void.
Runnable is no good, because its run() method doesn't declare throws Exception.
I sort of need a combination of the two. Any ideas?
EDIT: I should have mentioned that I tried Callable<Void> but it requires you to define a method:
public Void call() {
// run your code;
return null; // ugly!
}
I'm looking for something a bit nicer.
Why do I want this?
I'm implementing a standard why of catching "will never happen" Exceptions (they will never happen, but various APIs define their methods throwing Exceptions) and throwing any Exceptions that might occur by wrapping them in an (unchecked) RuntimeException, so the caller can simply pass a "ExplodingRunnable" in and not have to code loads of perfunctory try/catch blocks that will never be exercised.
FINAL EDIT It looks like what I was looking for doesn't exist. The accepted answer is the closest to "correct", but it looks like there is no solution to answer the question as asked.
Could you just use Callable<Void>?
An interface with only one method, which returns void and throws Exception.
Among all java and javax classes, only one fits that description:
package java.lang;
public interface AutoCloseable
{
void close() throws Exception;
}
Well... the word "close" has many meanings...
You want to surround a bunch of statements with some extra handling, there is no sin to define your own interface here. You may find that your API requires users to learn 4 new phrases
Util.muckException( new ExplodingRunnable() { public void run() throws Exception
^1 ^2 ^3 ^4
You can actually cut down two, and user code would look like this
new MuckException(){ public void run() throws Exception
{
statement_1;
...
statement_n;
}};
public abstract class MuckException
{
public abstract run() throws Exception;
public MuckException()
{
try{ run(); }
catch(Exception e){ throw new Error(e); }
}
}
Just use Callable, ignore the return value and document things as ignoring the returned value and recommend returning null. Just because you can return something does not mean you have to.
I would just use Callable<Void> and learn to love it. ;)
You can have the checked exception not declared with the following.
Runnable runs = new Runnable() {
public void run() {
try {
// do something
} catch(Exception e) {
// rethrows anything without the compiler knowing.
// the method is deprecated but can be used on the current thread.
Thread.currentThread().stop(e);
}
}
});
Future future = executorService.submit(run);
try {
future.get();
} catch (ExecutionException ee) {
Throwable e = ee.getCause(); // can be the checked exception above.
}
and not have to code loads of perfunctory try/catch blocks that will never be exercised.
I had the same issue and fixed it a little differently
// Exceptions class
public RuntimeException wrap(Exception e) {
return e instanceof RuntimeException ? ((RuntimeException)e) : new RuntimeException(e);
}
// user code
try {
foo.bar();
} catch (Exception e) {
throw Exceptions.wrap(e);
}

Categories

Resources