public void backendExecute(Map appParams, BackendTaskMetaData metaData) throws Throwable {
try {
PeriodicTaskData ptd = (PeriodicTaskData) appParams.get(PeriodicTaskData.PARAM_KEY);
String bizKey = ptd.getBusinessKey();
} catch (Exception e) {
LogServices.app.error("RPTPeriodicReportGenTask:"+ e.getMessage());
}
}
With regards to the method above, if object pointed to is null, would come across as NullPointerException, I want to know if this exception would be caught or thrown to the invoker method? thanks
Exception is a parent class of NullPointerException, so it will catch it and not throw it to the calling method.
As you are catching Exception class and NullPointerException is its subclass , exception will get catched not throwed.
Regard to above method, if object ptd is null, would come across nullpointexception,
Yes.
i want to know this exception would be catch or throw it to invoker method?
The exception would be caught by the handler. The handler will catch Exception and any exception that is descended from it. NullPointerException is a subclass of RuntimeException which is (in turn) a subclass of Exception. Therefore, it will be caught.
Now, if this may be just an illustrative example ... but it is a bad idea to:
declare a method as throws Throwable, or
catch Exception ... unless you are about to terminate the application.
Declaring a method as throwing Throwable makes it next to impossible for the caller to know what exceptions could be thrown. Instead, the compiler will insist that the caller catches ... or propagates Throwable.
Catching Exception has the problem that you will catch every subtype of Exception ... including various unchecked exceptions that 1) you are not expecting, and 2) are probably symptoms of bugs that you cannot safely recover from.
NullPointerException is a subclass of Exception and thus will be catched, however it is recommended that you don't try and catch runtime exceptions. It is better to avoid them.
For example a null pointer could be avoided by doing the following:
if(ptd != null) {
ptd.getBusinessKey();
} else {
//Notify the user in some way or do something else.
}
catch (Exception e)
means that this will catch any exception (i.e. any subclass of Exception) thrown inside the preceding try block - which, yes, includes NullPointerException. Note that this is generally considered a bad practice, as you almost always will want to handle different sorts of exceptions in different ways, hence the need for multiple catch statements.
For instance, consider a method that could potentially throw an IllegalAccessException at compile time or a NullPointerException at runtime - it's difficult to imagine a situation where you'd want to handle them the same way, so you'll typically want to do something like this:
try {
PeriodicTaskData ptd = (PeriodicTaskData) appParams.get(PeriodicTaskData.PARAM_KEY);
String bizKey = ptd.getBusinessKey();
} catch (NullPointerException e) {
//do something
} catch (IllegalAccessException e) { //for example...
//do something different
}
Related
What is the point of catching and then also throwing an Exception like below? Is it bad practice to do both?
try{
//something
} catch (Exception e){
throw new RuntimeException("reason for exception");
}
Usually, such code is used to re-wrap exceptions, that means transforming the type of the exception. Typically, you do this when you are limited in what exceptions are allowed out of your method, but internally other types of exceptions can happen. For example:
class MyServiceImplementaiton implements MyService {
void myService() throws MyServiceException { // cannot change the throws clause here
try {
.... // Do something
} catch(IOException e) {
// re-wrap the received IOException as MyServiceException
throw new MyServiceException(e);
}
}
}
This idiom enables to keep propagating exceptions to the caller, while conforming to the throws clause in the interface and hide the details of the internals (the fact that IOExceptions can happen).
In practice, this is always better than just calling e.printStackTrace() which will actually "swallow" the error condition and let the rest of the program run as if nothing had happened. In this respect, behaviour of Eclipse is quite bad as it tends to auto-write such bad-practice constructs if the developer is not careful.
This is called rethrowing an exception, and it is a common pattern.
It allows you to change the class of the exception (such as in this case), or to add more information (also the case here, as long as that error string is meaningful).
It is often a good idea to attach the original exception:
throw new RuntimeException("cause of the problem", e);
Rethrowing as an unchecked exception (a RuntimeException) is sometimes necessary when you still want to throw an exception, but the API of your method does not allow a checked exception.
In your example, an Exception is caught and a RuntimeException is thrown, which effectively replaces a (potentially) checked exception with an unchecked exception that doesn't have to be handled by the caller, nor declared by the throwing method in a throws clause.
Some examples :
This code passes compilation :
public void SomeMethod ()
{
try {
//something
} catch (Exception e){
throw new RuntimeException("reason for exception");
}
}
This code doesn't pass compilation (assuming "something" may throw a checked exception) :
public void SomeMethod ()
{
//something
}
An alternative to catching the Exception and throwing an unchecked exception (i.e. RuntimeException) is to add a throws clause :
public void SomeMethod () throws Exception
{
//something
}
This is one use case of catching one type of exception and throwing another. Another use case is to catch one type of exception and throw another type of checked exception (that your method declares in its throws clause). It is sometimes done in order to group multiple exceptions that may be thrown inside a method, and only throw one type of exception to the caller of the method (which makes it easier for them to write the exception handling code, and makes sense if all those exceptions should be handled in the same manner).
Is it meaningful to declare a method to throw an exception
and a subclass of this exception,
e.g. IOException and FileNotFoundException?
I guess that it is used in order to handle both exceptions by a caller method differently.
However, is it possible to handle both exceptions if the method throws only the most generic i.e IOException?
However, is it possible to handle both exceptions if the method throws only the most generic i.e IOException?
Absolutely. You can still catch them separately:
try {
methodThrowingIOException();
} catch (FileNotFoundException e) {
doSomething();
} catch (IOException e) {
doSomethingElse();
}
So it makes no difference to what the caller can do if the method declares both - it's redundant. However, it can emphasize exceptions that you might want to consider. This could be done better in Javadoc than just the throws declaration.
Is it meaningful to declare a method to throw an exception and a subclass of this exception, e.g. IOException and FileNotFoundException?
Usually not - most IDEs I know of even issue warnings for such declarations. What you can and should do is to document the different exceptions thrown in Javadoc.
However, is it possible to handle both exceptions if the method throws only the most generic i.e IOException?
Yes it is, you just need to ensure that the catch blocks are in the right order, i.e. more specific first. Catch blocks are evaluated in the order they are defined, so here
try {
...
} catch (FileNotFoundException e) {
...
} catch (IOException e) {
...
}
if the exception thrown is a FileNotFoundException, it will be caught by the first catch block, otherwise it will fall to the second and dealt with as a general IOException. The opposite order would not work as catch (IOException e) would catch all IOExceptions including FileNotFoundException. (In fact, the latter would result in a compilation error IIRC.)
However, is it possible to handle both exceptions if the method throws only the most generic i.e >IOException?
catch(IOException ex){
if(ex instanceof FileNotFoundException){}
}
But this doesn't look clean, Throwing both exception looks good, even caller would come to know to that this method may throw these these exceptions, so they will handle it properly
Yes, it's possible to handle both if the method only throws IOException.
The best way to answer such a question is to write a test to demonstrate it and try it out. Let the JVM tell you the answer. It'll be faster than asking here.
yes. when certain specialized exceptions can be handled correct. It is, if you handle the exceptions as follow:
try {
} catch (FileNotFoundException f) {
//Try a different file
} catch (IOException ioe) {
//Fatal, Maybe bad blocks ... Bail out...
} catch (Exception e) {
//Something went wrong, see what it is...
}
Declaring, that the method may throw (more generic) IOException, and (more specific) FileNotFoundException is usually a good thing - it's an additional information for people using your code later. Note that you should explicitely state in the JavaDoc, under what circumstances is each of the exceptions thrown.
They will still be able to distinguish the exceptions, and handle them differently using catch constructs like this one:
try {
yourAwesomeMethod()
} catch (FileNotFoundException ex) {
// handle file-not-found error
} catch (IOException ex) {
// handle other IO errors
}
I have basic doubt in Java Exceptions
i.e., All checked exceptions extends from Exception class and Unchecked Exceptions extend from RuntimeException. But Runtime Exception also extends from Exception.
But why to propagate try... catch block with checked Exceptions but not in Unchecked Exceptions?
In general, you should add different catch blocks for each specific type of exception you intend to handle. If you're trying to handle (by rethrowing) checked exceptions, then you should know which type of exceptions to rethrow -- just add a catch block to rethrow each of those exception types.
I think you are asking, "How can I catch Exception but not RuntimeException ?
You probably should not be trying to do that. You should catch specific types of exceptions when possible. If you need to handle all errors, then you should catch Exception and that catches everything.*
You would rarely want to do catch (NullPointerException) because if you ever know that you can have a null then you should check for it. If your code is causing NullPointerException or ArrayOutOfBoundsException then you should fix the code so that it no longer throws those.
This code should show you how to do what you asked about:
public static void throwSomething(Exception throwMe)
{
try {
throw throwMe;
}
catch(Exception ex) {
// Check if the object is a RuntimeException
if(ex instanceof RuntimeException) {
// Throw the same object again.
// Cast to RuntimeException so the compiler will not
// require "throws Exception" on this method.
throw (RuntimeException) ex;
}
System.out.println("Caught an instance of a " +
ex.getClass().toString());
}
}
*Actually, catch(Throwable) will catch everything including Errors.
The easiest way is this:
try {
//do stuff
} catch(RuntimeException e) {
throw e;
} catch(SpecificCheckedException e) {
//handle
} catch(Exception e) {
//handle
}
I'd like to catch an exception, log it, set a flag, and the rethrow the same exception
I have this code:
public Boolean doJobWithResult() {
boolean result = true;
final Feed feed = Feed.findById(feedId);
try {
feed.fetchContents();
} catch (Exception ex) {
result = false;
Logger.info("fetching feed(%d) failed", feedId);
throw ex;
}
return result;
}
But eclipse complains at throw ex, telling that "Unhandled exception type Exception", and suggests me to add a try-catch block around it.
In fact, I want the process calling this method to handle the exception, and not handle it myself... I just want to return true if everything goes ok, and log it if there's an exception
On the other hand, I can wrap the exception inside another exception, but I can't throw the same one..
any idea?
I think there are various things to mention here:
You either want doJobWithResult() to return true on success and false on failure, or return nothing on success and throw an exception on failure.
Both at the same time is not possible. In the first case, catch the Exception, log it and return false, in the second case change your signature to return void and throw an exception and handle it in the caller.
It's a Don't to catch an exception, log it and rethrow it. Why? Because a potential caller of your method does not know that you are already logging it, and migh log it as well.
Either throw an exception (in which case the caller has to deal with it) or catch it and handle it (log it).
Note that throwing Exception does not give the caller of your method any clue about what might potentially go wrong in your method, it's always better to throw more specific exceptions, or to wrap an exception in a user-defined one and rethrow it.
Moreover, if you throw Exception, a caller might be tempted to catch Exception without noticing that this will also catch every RuntimeException (since its derived from Exception), which might not be desired behavior.
Your doJobWithResult method needs to declare that it can throw Exception:
public Boolean doJobWithResult() {
becomes
public Boolean doJobWithResult() throws Exception {
You can throw the same exception if you add throws Exception to your method signature.
Otherwise you can throw a RuntimeException.
public Boolean doJobWithResult() {
boolean result = true;
final Feed feed = Feed.findById(feedId);
try {
feed.fetchContents();
} catch (Exception ex) {
result = false;
Logger.info("fetching feed(%d) failed", feedId);
throw new RuntimeException(ex);
}
return result;
}
In such a case, you won't need to indicate that public Boolean doJobWithResult() throws something but make sure you handle it properly later on (catch or expect your thread to stop... it's a RuntimeException afterall).
Since Exception is checked, an alternative to catching the Exception is to declare your method as throwing it:
public Boolean doJobWithResult() throws Exception {
// ...
}
If doJobWithResult doesn't have to handle the exception, then remove the catch block and add "throws Exception" to the method signature. The exception logging can be done in the class/method that have to deal with the Exception in a corresponding try/catch block.
There is no need to set the result as false in the catch block, as the value won't be returned(as we are throwing an exception).
Your method should also declare that it throws an exception and so the client will be forced to handle it.
Also consider using a more specific exception which will be thrown in this particular case.
Add throws Exception to your method. You also don't need to add result = false; in your catch block.
I think the way you handle this exception is really appropriate if any failure of feed.fetchContents() method cannot be recovered. (Idea is better to halt rather than continuing)
Apart from that I would suggest you to use more specific exception hierarchy.
And another thing I got from effective java book is if you write such a method you must document with #throw (in comments) with the reason.
You could throw an unchecked exception
Logger.info("fetching feed(%d) failed", feedId);
throw new RuntimeException(ex);
I spent the last hour looking for it since not even the Complete Reference book mentions this explicitly: unhandled throw ThrowableInstance works only with unchecked exceptions.. And only runtime exceptions are unchecked. By unhandled I mean something like this:
class ThrowDemo {
static void demoproc() {
try {
throw new NullPointerException("demo");
} catch(NullPointerException e) {
System.out.println("Caught inside demoproc.");
throw e; // re-throw the exception
}
}
public static void main(String args[]) {
try {
demoproc();
} catch(NullPointerException e) {
System.out.println("Recaught: " + e);
}
}
}
This example is taken verbatim from the Complete Reference book (9th edition).
The first throw statement i.e throw new NullPointerException("demo"); is handled by the following catch block, but the second throw statement i.e. throw e; is unhandled by the demoproc() method. Now this works here and the above code compiles successfully because NullPointerException is a runtime/ unchecked exception. If the e instance were a checked exception or even an Exception class instance then you'd get an error saying the exception e is unhandled and you'd either have to handle it within demoproc() or you'd have to explicitly declare that demoproc() throws an exception using throws in the method signature.
public void foo() {
begin();
try {
...
commit();
} catch (Exception e) {
rollback();
throw e;
}
}
In the sample above, there is an error because foo has no throws Exception. Adding that wouldn't make do the method's usability a lot of good either.
What's the best way to do this? How do you do something if an error occurs without really "handling" the error?
Since Java 8 we use
/**
* Cast a CheckedException as an unchecked one.
*
* #param throwable to cast
* #param <T> the type of the Throwable
* #return this method will never return a Throwable instance, it will just throw it.
* #throws T the throwable as an unchecked throwable
*/
#SuppressWarnings("unchecked")
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T {
throw (T) throwable; // rely on vacuous cast
}
You can rethrow a checked exception, but only by avoiding the compilers checked exception validation.
public void foo() throws MyCheckedException {
begin();
try {
...
commit();
} catch (Exception e) {
rollback();
// same as throwing an exception without the compiler knowing.
Thread.currentThread().stop(e);
}
}
Before you use stop() you should read http://download.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Thread.currentThread().stop(e) .. is behaviorally identical to Java's throw operation, but circumvents the compiler's attempts to guarantee that the calling method has declared all of the checked exceptions that it may throw:
At least two approaches come to mind, which are usually going to be combined depending on what you want foo to do:
1. Catch and rethrow only the relevant exceptions
There are only so many exceptions the code in your main flow can throw (probably mostly SqlExceptions). So only catch and rethrow those, and declare that you're doing so. More to the point, rethrow only the ones you're not actually handling (in your simplified sample code, you're not handling any, but your real life code is probably more subtle).
Mind you, some of the exceptions may be runtime exceptions, and so you may want to combine this with the below.
2. Don't catch the exception at all
Like this:
// Signature changes to include any exceptions that really can be thrown
public void foo() throws XYZException, ABCException {
// A flag indicating that the commit succeeded
boolean done = false;
begin();
try {
// Don't have any `return` statements in here (or if you do,
// set `done` to `true` first)
...
commit();
done = true; // Commit didn't throw an exception, we're done
} finally {
// finally clause always happens regardless
if (!done) {
// We must be processing an exception; rollback
try {
rollback();
} catch (Exception e) {
// quash it (e.g., leave this block empty), we don't want
// to mask the real exception by throwing a different one
}
}
}
}
Naturally your signature needs to include any exceptions that may be thrown in the main flow, but that's what you're trying to do, if I'm understanding you correctly.
Again, you may well combine these two approaches, because you may want to handle some exceptions and not others.
Wrap it with some RuntimeException which is unchecked.
Adding that wouldn't make do the method's usability a lot of good either.
No. It will be good at documentation, also caller will take care handling it.
Also See
exception-thrown-inside-catch-block-will-it-be-caught-again
throws-or-try-catch
I'd say that in this case rolling back is handling the exception appropriately. It's one of the few cases where it's legitimate to catch and re-throw.
Simply catching and logging an exception is not what I would consider handling. Rather than rethrowing, in that case I'd rather see checked exceptions added to the method signature and let it bubble up.
you may throw a subclass of RuntimeException - they don't require a catch()
the key point is, why should you throw a new Exception from a catch block.
if you use catch then handle your exception there in your catch. If you have to inform the caller method with an exception, then don't catch the exception with try-catch, instead, sign your method with throws and let the caller catch the e xception.
or throw a RuntimeException, i find this idea less useful because of lack of readability, then you don't need to sign your method with throws.
Here you've chanced on one of the biggest religious schisms in the Java, ( if not wider ) , world. It boils down to those that feel, as TJ seems to, and I do too, that checked exceptions are valuable for many reasons, VS the Rod Johnson/Spring school that in the design of Java, checked exceptions were used in many instances where they shouldn't, say closing a resultset or socket, so because it was wrongly used in many cases, it makes them useless so all exceptions should be unchecked. There are many classes in the Spring framework that are very thin wrappers around standard Java objects, but convert checked exceptions to unchecked. It drives me berserk!
Anyway, put me down as strongly agreeing with everything TJ has said, but know that you'll probably never find a "right" answer.
It's worth mentioning some advances in this area.
First, in Java 7, it's possible to catch and throw generic exceptions, as long as what's declared inside the try block is caught or declared in the outer block. So this would compile:
void test() throws SQLException {
try {
conn.commit();
} catch (Throwable t) {
// do something
throw t;
}
}
This is well explained here : http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
Another way is described here : http://blog.jooq.org/2012/09/14/throw-checked-exceptions-like-runtime-exceptions-in-java/
The reason you may want to use that has often to do with lambdas, or throwing exceptions from some generic methods. I ran into this when I wanted to replace repeating constructs of:
try {
do_operation
flag_success
} catch (Throwable e) {
flag_error
throw e;
}
With using a method of:
public static void wrapExec(RunnableT s) {
try {
s.run();
flag_success
} catch (Throwable t) {
flag_error
doThrow(t);
}
}
and therefore replacing the whole try/catch block with just
wrapExec(()->{do_operation})