Related
I have a simple restarting Runnable:
static void launchThreads(){
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
try {
exec.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
try {
System.out.println("line"); <--breakpoint
}
catch (Exception e) {
e.printStackTrace(); <--breakpoint
}
}
}, 1, 1000, TimeUnit.MILLISECONDS);
}catch (Exception e) {
e.printStackTrace(); <--breakpoint
}
}
If I launch that method from the main() method of the class, it works as expected - writes a line that looks like "line", once a second, forever.
line
line
line
line
...
But if I launch that from a TestNG test method:
#Test
public class PostpackagesIntegratorTest {
#Test
public void testLaunchThreads10SmallestWithoutFees() {
PostpackagesIntegrator.launchThreads();
}
}
,it outputs only one "line" and the test is passed. "Successfully".
If I make a JUnit4 test to launch the same method,
public class PostpackagesIntegratorJUnit4Test {
#Test
public void launchThreadsTest() {
PostpackagesIntegrator.launchThreads();
}
}
, the test is also passed, again with only one "line" in output.
If I am not running, but debugging the tests, my IntelliJ stops at printing the "line", but does not notice any catch content.
I do not understand, what prevents the ScheduledExecutorService from repetitions. According to docs, such non-repeating should happen at an exception, but no exception happens.
Is it possible to make ScheduledExecutorService in TestNG tests or must I use other classes? Due to the whole project, I am limited by Java 6 version and TestNG.
Edit: #Eugene advised to declare exec as private static final ScheduledExecutorService exec, for blocking erroneous GC, but it did not help and even didn't change anything - the problem is elsewhere.
I would start by dumping a lot of thread details.
Thread.currentThread().dumpStack() (or just (new Throwable()).printStackTrace()) would show any peculiar classes frames above your runnable. These could be quite different if junit/ng are fiddling with thread factories or such.
Then you can also inspect the thread.currentThread() for isDaemon() and the threadgroup's isDeamon(). Your new executorsvc may be part (and making worker threads in) a threadgroup that is interrupted. You might be able to reveal that by writing your own thread factory and issuing threads whose interrupt() is proxied for the sake of trapping it (before forwarding it). A main() is normally a non-daemon thread, so it would spawn non daemon threads too for the execsvc. I wouldn't be surprised is junit/ng are wrapping the test in a pseudo thread sandbox to 'try' to detect and perhaps stop leaked/forgotten threads from a test.
If your are in a debugger, you should be able to browse the top frame local variables and the thread instance already without much code, to reveal all of the above (except the unanticipated interrupt call, if any).
This is a plain Java 8+ question, no frameworks used.
We are producing an API for a higher layer which deals with the presentation layer among other activities. We have and interface agreed with the invoker, so they are happy to receive some particular exceptions we throw.
At the same time, we are also using other APIs under the same agreement, so we can do stuff by ourselves and throw exceptions or we can invoke other APIs which throw the agreed exceptions.
Currently, we do nothing with the exceptions thrown by the APIs we are invoking.
Thing is, we are the best positioned in this infrastructure to deal with intermediate activities while exceptions are thrown, so we need to capture both, our exceptions and the exceptions provided by those we are invoking; basically reporting the issue, raising system controls, etc, and then re-throw the original exception so the top layer keeps as it is now.
We have around 300 methods in the entry point class of our API:
public void method1 (arguments for method 1) {
...
}
...
public void method300 (arguments for method 300) {
...
}
I clearly understand that I can create a method to centralise the actions to be taken in the exception management, something like:
public void myExceptionHandler (Exception e) {
if (e instanceOf X) {
} else if ...
...
throw particularExceptionAccordingTheCase
}
But I'd also avoid modifying those 300 methods.
Any idea how to inject a try-catch in those 300 methods to send the Exception to myExceptionHandler without really adding a try-catch in each of them?
Any comments and ideas are much appreciated!
----------- After mprev0 suggestion -------------------------------
I tried this approach. It really catches the exception and so on, but I can't re-trow an Exception: I'm forced to catch it, but this goes against the requirement of re-sending the exception back to the top layer.
While I can throw an Error, I got a compiler error at line throw new FileNotFoundException();
public class myExceptionHandler implements Thread.UncaughtExceptionHandler {
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("gotcha!");
if (e instanceof java.lang.Error) {
System.out.println("AAT-CORE: Fatal Error");
throw new java.lang.Error(e.getCause());
} else if (e instanceof java.lang.Exception) {
System.out.println("AAT-CORE: Exception Error");
throw new FileNotFoundException();
}
}
}
Any ideas?
------------ After some more digging, fixed with a decorator pattern -------
Previous class implementation does not work, as I can't change the signature of the method and I need to re-throw the java.lang.Exception.
Using a decorator and handling the interface there makes the trick.
As a summary:
Top layer class:
public class TopLayer {
public static void main (String[] args) {
MiddleLayer m = new MiddleLayer();
m.method1();
}
}
Bottom layer class contains specific APIs and some implementation, the only interesting thing is that it contains java.lang.Exceptions uncontrolled, expecting the top layer to do this job. But, we are working in the middle and we will do this job:
public class MiddleLayer extends BottomLayer {
public MiddleLayer () {
final UncaughtExceptionHandler subclass = Thread.currentThread().getUncaughtExceptionHandler();
Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
System.out.println("gotcha2!");
// carry on with prior flow
subclass.uncaughtException(thread, ex);
}
});
}
}
In this way, I can get the system.out and the java.lang.Exception is propagated to the Top Layer.
Decorator inspiration came from here: Rethrow UncaughtExceptionHandler Exception after Logging It
Additional comments are welcome!
You can solve this by implementing the java.lang.Thread.UncaughtExceptionHandler interface:
public class MyExceptionHandler implements Thread.UncaughtExceptionHandler {
#Overrides
public void uncaughtException(Thread t, Throwable e) {
if (e instanceOf X) {
} else if ...
...
throw particularExceptionAccordingTheCase
}
}
Then you associate it to all threads as follows:
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler())
This will configure the exception handler to handle all uncaught exceptions in all threads of your application.
Note that this will only work for exceptions that aren't yet explicitly handled somewhere in your code and if there is no other handler configured for some particular thread (the uncaught exception handler can also be set for some specific thread).
EDIT: As discovered by #JBC, the above approach will not work for checked exceptions since we are forced to catch them explicitly in our uncaughtException method (note that we cannot add a throws clause to an overridden method). While it will work without problems if we only want to re-throw subtypes of RuntimeException and Error, there is a little adaptation needed if we want to make it work - you can find it explained in #JBC's question.
As you can see in the question updates, the final solution is a combination of two different approaches, in one side, having the mprev0 approach of implementing the java.lang.Thread.UncaughtExceptionHandler and, on top of this, adding a Decoration pattern to be able to re-throw a run-time exception.
There were no additional approaches so far, so I'm closing the question and bring this as the most complete response.
More information about UncaughtExceptionHandler can be found in the Java documentation, but as always, is short on examples, and here:
Advanced exception handling
Thread.UncaughtExceptionHandler Example
More information on Decorator pattern usage, can be found here:
Decorator Design Pattern in Java
Design Patterns - Decorator Pattern
And how to use to manipulate exceptions here:
Rethrow UncaughtExceptionHandler Exception after Logging It
You could also create a proxy API on top of your current API, have an invocation handler method in the proxy and put this method in a try catch block.
https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html
https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html
A method I am calling in run() in a class that implements Runnable) is designed to be throwing an exception.
But the Java compiler won't let me do that and suggests that I surround it with try/catch.
The problem is that by surrounding it with a try/catch I make that particular run() useless. I do want to throw that exception.
If I specify throws for run() itself, the compiler complains that Exception is not compatible with throws clause in Runnable.run().
Ordinarily I'm totally fine with not letting run() throw an exception. But I have unique situation in which I must have that functionality.
How to I work around this limitation?
You can use a Callable instead, submitting it to an ExecutorService and waiting for result with FutureTask.isDone() returned by the ExecutorService.submit().
When isDone() returns true you call FutureTask.get(). Now, if your Callable has thrown an Exception then FutureTask.get() wiill throw an Exception too and the original Exception you will be able to access using Exception.getCause().
If you want to pass a class that implements Runnable into the Thread framework, then you have to play by that framework's rules, see Ernest Friedman-Hill's answer why doing it otherwise is a bad idea.
I have a hunch, though, that you want to call run method directly in your code, so your calling code can process the exception.
The answer to this problem is easy. Do not use Runnable interface from Thread library, but instead create your own interface with the modified signature that allows checked exception to be thrown, e.g.
public interface MyRunnable
{
void myRun ( ) throws MyException;
}
You may even create an adapter that converts this interface to real Runnable ( by handling checked exception ) suitable for use in Thread framework.
If run() threw a checked exception, what would catch it? There's no way for you to enclose that run() call in a handler, since you don't write the code that invokes it.
You can catch your checked exception in the run() method, and throw an unchekced exception (i.e., RuntimeException) in its place. This will terminate the thread with a stack trace; perhaps that's what you're after.
If instead you want your run() method to report the error somewhere, then you can just provide a callback method for the run() method's catch block to call; that method could store the exception object somewhere, and then your interested thread could find the object in that location.
Yes, there is a way to throw a checked exception from the run() method, but it's so terrible I won't share it.
Here's what you can do instead; it uses the same mechanism that a runtime exception would exercise:
#Override
public void run() {
try {
/* Do your thing. */
...
} catch (Exception ex) {
Thread t = Thread.currentThread();
t.getUncaughtExceptionHandler().uncaughtException(t, ex);
}
}
As others have noted, if your run() method is really the target of a Thread, there's no point in throwing an exception because it is unobservable; throwing an exception has the same effect as not throwing an exception (none).
If it's not a Thread target, don't use Runnable. For example, perhaps Callable is a better fit.
#FunctionalInterface
public interface CheckedRunnable<E extends Exception> extends Runnable {
#Override
default void run() throws RuntimeException {
try {
runThrows();
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
void runThrows() throws E;
}
Some people try to convince you that you have to play by the rules. Listen, but whether you obey, you should decide yourself depending on your situation. The reality is "you SHOULD play by the rules" (not "you MUST play by the rules"). Just be aware that if you do not play by the rules, there might be consequences.
The situation not only applies in the situation of Runnable, but with Java 8 also very frequently in the context of Streams and other places where functional interfaces have been introduced without the possibility to deal with checked exceptions. For example, Consumer, Supplier, Function, BiFunction and so on have all been declared without facilities to deal with checked exceptions.
So what are the situations and options?
In the below text, Runnable is representative of any functional interface that doesn't declare exceptions, or declares exceptions too limited for the use case at hand.
You've declared Runnable somewhere yourself, and could replace Runnable with something else.
Consider replacing Runnable with Callable<Void>. Basically the same thing, but allowed to throw exceptions; and has to return null in the end, which is a mild annoyance.
Consider replacing Runnable with your own custom #FunctionalInterface that can throw exactly those exceptions that you want.
You've used an API, and alternatives are available. For example, some Java APIs are overloaded so you could use Callable<Void> instead of Runnable.
You've used an API, and there are no alternatives. In that case, you're still not out of options.
You can wrap the exception in RuntimeException.
You can hack the exception into a RuntimeException by using an unchecked cast.
You can try the following. It's a bit of a hack, but sometimes a hack is what we need. Because, whether an exception should be checked or unchecked is defined by its type, but practically should actually be defined by the situation.
#FunctionalInterface
public interface ThrowingRunnable extends Runnable {
#Override
default void run() {
try {
tryRun();
} catch (final Throwable t) {
throwUnchecked(t);
}
}
private static <E extends RuntimeException> void throwUnchecked(Throwable t) {
throw (E) t;
}
void tryRun() throws Throwable;
}
I prefer this over new RuntimeException(t) because it has a shorter stack trace.
You can now do:
executorService.submit((ThrowingRunnable) () -> {throw new Exception()});
Disclaimer: The ability to perform unchecked casts in this way might actually be removed in future versions of Java, when generics type information is processed not only at compile time, but also at runtime.
Your requirement doesn't make any sense. If you want to notify the called of the thread about an exception that happened, you could do that through a call back mechanism. This can be through a Handler or a broadcast or whatever else you can think of.
I think a listener pattern might help you with this scenario. In case of an exception happening in your run() method, use a try-catch block and in the catch send a notification of an exception event. And then handle your notification event. I think this would be a cleaner approach. This SO link gives you a helpful pointer to that direction.
Yes, you can throw checked exceptions from the run() method. It can be done with generics by tricking the compiler. Look at this code:
public static void main(String[] args) {
new Main().throwException();
}
public void throwException() {
Runnable runnable = () -> throwAs(new Exception());
new Thread(runnable).start();
}
private <T extends Throwable> void throwAs(Throwable t) throws T {
throw ( T ) t;
}
This might be helpful if you want to throw checked exceptions from the run() method of Runnable
The easiest way is to define your own exception object which extend the RuntimeException class instead of the Exception class.
I would like to discuss one thing is that , when an exception is occurred in the body of run method in thread then where it will be reflected(Caller) and how to handle this.
here is my code:
class MyThread extends Thread{
public void run() throws IllegalInterruptedException{
Thread.currentThread().sleep(1234);
}
}
then who(Caller) will manage this exception.
There are 2 different cases :
JVM passes the exception to an exception handler, if already installed for the ThreadGroup.
Otherwise the JVM handles it.
Sample program :
public class ThreadGroupDemo extends ThreadGroup {
public ThreadGroupDemo() {
super("This is MyThreadGroupDemo");
}
public void uncaughtException(Thread t, Throwable ex) {
// Handle your exception here ....
}
}
Thread t = new Thread(new ThreadGroupDemo(), "My Thread") {
// Some code here ......
};
t.start();
NOTE : Check out this link.
If I understood good you want to be able to handle exceptions that are fired in another thread. Take a look at setDefaultUncaughtExceptionHandler, one page with sample:
Java2S
You can see run() like main() and get yourself your answer.
But I don't think you can override run() and declare new nonRuntime-Exceptions .. so you'll get a compile error.
ps: I can't find IllegalInterruptedException, maybe you wanna say InterruptedException
Exceptions are thrown by programs when something out of the ordinary occurs. A general tutorial is available here, but the summary is that your program will search within the class that throws the exception with hopes of finding something to handle it: probably a catch statement like:
catch (IllegalInterruptedException e) {
//what you want the program to do if an IllegalInterruptedException
//is thrown elsewhere and caught here. For example:
System.err.println( "program interrupted!" + e.getMessage() );
}
If your program can't find a catch statement in the class that throws the statement, it will look for something to handle it in a parent class. Be aware that whatever the child class was doing when an exception is thrown stops when it throws an exception. For this reason, you should enclose the block of code that may throw an exception in a 'try' block, and follow it with whatever you want to have execute in a 'finally' statement, which will execute no matter what.
The tutorial linked above is really helpful.
Yet another option - make the task a Callable and use Executors to submit it. You'll then get any exceptions wrapped automatically when you get the Future.
Is there a possibility in Java to get rid of the necessity to catch non-RuntimeException exceptions? Maybe compiler flags?
I know the reason why the catching is promoted, but want to do simple and straight tools that enforce their requirements. So if something can went wrong I don't like to catch up but exit the application, crashing with a meaningful exception. Usually this ends up like:
try {
connection.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
which introduces 4 lines of code mess, and introduces the wrapping RuntimeException mess on error output. Sometimes it even motivate people to wrap large try ... catch (Throwable ..) blocks around anything, which is the likely cause for our beloved 'Unknown error occured' alert boxes...
you can use throws keyword with method prototype to avoid try-catch block. which eventually throws the exception to JVM's Default Exception handler which halts the application if no catch block's are specified in your code to handle the exception raised.
Crashing the application at the first sight of an exception is very bad practice. Especially when some work is unsaved and the application is using some resources that needs to be freed and cleaned before the application terminates execution. Some very popular software used to do that... and instead of "fixing" the issue, they introduced a data recoverability features on application restart. However the trick, this is not good software engineering.
At the very least, your application should not crash on the first exception/error encountered, but recover with a meaningful message. It is being lazy to just wrap everything in a RuntimeException (or even Throwable) and, especially, not do anything with it.
Java does not support flags of any kind because there are 1) a workaround, and 2) better ways to handle this situation. For example :
1. Handle the exception in the calling method
You can add the throws keyword in your method declaration, up to your static public void main method, which, if not handling the exception, will eventually crash the application with a stacktrace.
class Foo {
public void someMethod(....) throws IllegalArgumentException, IOException {
...
}
static public void main(String...args) throws Throwable {
new Foo().someMethod();
}
}
This method does not offer any means of recoverability and will probably make your user unhappy (with a big meaningless stachtrace if they ran the application from a console, or just nothing at all if they launched it from a shortcut or GUI). Also, if you have some acquired resources, you will not be able to clean them when an exception occurs. At the very least, your main should catch (Throwable e) and output something before throwing the exception above. Something like :
class Foo {
public void someMethod(....) throws IllegalArgumentException, IOException {
...
}
static public void main(String...args) {
try {
new Foo().someMethod();
} catch (...) {
// output or log exception here and, optionally, cleanup and exit
}
}
}
** EDIT **
Consider this scenario : a program is initializing some resource for processing some data, then some runtime exception (or error) occurs during processing, the application crash, but the resources are not released or freed. In Java, however, one could do this
public E doSomething() throws RuntimeException {
// declare a bunch of resources
try {
// process resources with unchecked exceptions
} finally {
// free resources
}
// return some result
}
and cleanly exit the method on error or on success, perhaps even logging the runtime error for "posterity".
2. Log the error and return some meaningful value
Logging is a very good practice. You can show your user some message telling them that the operation could not be executed without crashing the whole thing, and giving you some traces of what and where the user were doing. A simplistic logging system could be :
class Foo {
static private final Logger LOG = Logger.getLogger(Foo.class.getName());
public boolean doSomethingImpl(...) {
boolean result = true;
try {
...
} catch (SomeException e) {
LOG.log(Level.SEVERE, "meaningful message why method could not do something!", e);
result = false;
}
return result;
}
public void doSomething() {
if (!doSomethingImpl(...)) {
// handle failure here
}
}
}
By default, the Logger will output everything to the err output stream, but you can add your own handlers :
// loggers are singletons, so you can retrieve any logger at anytime from
// anywhere, as long as you know the logger's name
Logger logger = Logger.getLogger(Foo.class.getName());
logger.setUseParentHandlers(false); // disable output to err
logger.addHandler(new MyHandler()); // MyHandler extends java.util.logging.Handler
Java already ships with some default logging handlers, one of which writes to file.
etc.
Is there a possibility in Java to get rid of the necessity to catch non-RuntimeException exceptions?
For a checked exception, you can chose between catching the exception and declaring it in the method header as thrown.
Maybe compiler flags?
No. There are no compiler flags to relax this. It is a fundamental part of the language design. Relaxing the checked exception rules via a compiler switch would cause serious library interoperability problems.
I don't think that there's any way around this for the JVM. Your best bet is to have your methods re-throw the exception, which gets rid of the "mess" in your code, and then have your main program throw Exception. This should propagate the error up to the top of your program.
Keep in mind, however, that the place where the exception actually happens is a much better place to let the user know what happened (i.e., exactly what it was doing when this particular IOException happened). You'll lose this resolution if all errors are simply propagated up to the top level.
You do have the ability to throw your exceptions up a level. Here's an example
public class Foo {
public Foo() {
super();
}
public void disconnect(connection) throws IOException {
connection.close();
}
}
Use "Throws" to avoid the error..but it will not be good programimg practice