A possible reason because a NullPointerException is a runtime exception is because every method can throw it, so every method would need to have a "throws NullPointerException", and would be ugly. But this happens with RemoteException.
And a possible reason because RemoteException is not a runtime exception, is to tell it client to treat the exception. But every method in a remote environment need throws it, so there is no difference of throwing NullPointerException.
Speculations? Was I clear?
I won't discuss the decision, I'll just quote the explanation of the decision from Ann Wollrath (who lead the design and implementation of Java RMI). This is extracted from this message from the RMI-USERS archives (message from Jan 1999):
The decision to make RemoteException a
checked exception and requiring remote
methods to list the exception in its
throws clause is not a religious one.
The decision is based on how to make
distributed computing reliable. This
question comes up every once in a
while on our users list. I have a
detailed response that I posted a
while ago. Here it is if you are
interested. I couldn't find it in the
rmi-users archive, so I included it
below.
cheers,
-- Ann
I'd like to address the rationale for
making RemoteException a checked
Exception, rather than a
RuntimeException.
1) networks aren't reliable
I wish that they were, but in fact,
they're not. Every network has
transient failures. You can build in
network redundancy, but the fact is
that most networks don't have that.
Intranets have transient failures, as
does the Internet. So, every RPC made,
is subject to a failure. The types of
failures may not have anything to do
with the "network", per se; if your
server runs out of file descriptors,
your client will get a connect
exception. This isn't a network
failure, in the sense of the network
being broken; your server is in a
transient state of being resource
starved.
RMI is not designed to only handle the
limited case that the whole network
crashes when a single machine crashes.
Such a network would be considered
reliable, either everything is up or
everything is down--there is no
partial failure. RMI is targetted for
a more general audience.
2) RPC failure can't be hidden from
the client
Partial failure is a fact of
distributed programming; these
failures can't be hidden to the
program. A failure shows up in the
client, whether the exception is
checked or unchecked exception, it
still shows up. So, how should such
failures be indicated to the client?
3) checked exceptions foster more
robust programs
There was a time when Oak and the
earliest version of Java did not have
checked exceptions. Exception handling
was advisory, and it was an unsafe
world out there. It was our group (Jim
Waldo and me in particular :-) that
recommended that there be exceptions
checked by the compiler. Jim was quite
persuasive in his arguments, telling
of a world where robust code would
reign. After some consideration, Java
was retooled to have checked
exceptions. Only those exceptions for
which there was no recovery or reflect
application errors would be unchecked
(e.g., OutOfMemoryError,
NullPointerException respectively).
And the world was safe again.
Imagine the Java engineers' surprise
when many exceptions in the Java API
and compiler were changed from
unchecked to checked, and the compiler
enforced the distinction, they
uncovered bugs in the implementations!
So, the best efforts at handling error
conditions, however well intentioned,
was not good enough. That compiler is
useful for something :-)
4) RemoteException should be a checked
exception
Ok, so back on track here. Since a
RemoteException is a fact of life in a
RPC call (see #1, #2) and checked
exceptions force you to write safe
code (#3), we thought that making
RemoteException a checked exception
was a good idea. Writing robust
distributed programs is hard enough,
without having the compiler to help
you with exceptions.
So, some might argue that a
RemoteException is a like an
OutOfMemoryError; your program should
fall over dead if a remote call fails.
I disagree with this point. Yes, in
some cases, there is no recovery from
a RemoteException; but if you are
writing a reliable distributed
program, your client needs to catch
failures and retry appropriately.
Perhaps you need to contact another
server, or abort a transaction of some
sort. If the RemoteException is not
handled, it will percolate up and
crash your client (yuk).
Others have stated that there are some
remote interfaces that are used in
both the local case and the remote
case and the client should not have to
deal with the exceptions in the local
case, so RemoteException should not
have to be in a throws clause and
handling it should not be mandatory.
Now, if we allowed remote interface
methods to omit RemoteException and
had an "rmic" switch to generate stubs
that would throw an unchecked
RemoteException, the client has no
choice in the matter. The decision of
exception handling should remain with
the client. If you define an interface
that only throws unchecked exceptions
you can never write a client that
wants compiler help in dealing with
those exceptions. We have already
seen from the above example that
checked exceptions fosters robust
code.
Another issue that has popped up now
and again is that developers need to
simply translate local interfaces and
use them as remote interfaces. This
may work for a small set of cases, but
if the interface was not designed with
concurrency and partial failure and
call latency in mind, the protocol
captured by the interface may not be
appropriate to use in the distributed
case. Is enough information passed in
those operations to make the
operations idempotent? Perhaps, but
most likely not.
Putting RemoteException in every
throws clause may seem like a pain,
but its the price to pay for writing
robust distributed applications.
-- Ann Wollrath
There is vastly more potential for NullPointerException than RemoteException. Any code that calls a method on an object (meaning practically any Java code at all) could potentially throw a NullPointerException. Only RMI code can throw a RemoteException. This is a tiny subset of "all code."
When writing the RMI libraries, the designers decided to make the client code expect to deal with these exceptions. Considering the nature of remote code execution, I think that's reasonable.
The way I understand it is:
RuntimeExceptions are thrown for things that were preventable.
Exceptions are thrown for things that were unpreventable but recoverable
Errors are thrown for things that were unpreventable and unrecoverable.
For example, NullPointerExceptions can always be avoided and are therefore unchecked exceptions. A RemoteException could occur when there is a network failure, which cannot be reasonably prevented before the method call and therefore is checked.
Besides RemoteException only applying to code from java.rmi and javax.rmi packages (and their subpackages), RemoteException is a type of IOException, much like SocketException is... and all IOExceptions are checked exceptions.
Related
I'm trying to understand difference between error and exception but it looks same thing and on Oracle Official tutorials I read this line.
Checked exceptions are subject to the Catch or Specify Requirement.
All exceptions are checked exceptions, except for those indicated by
Error, RuntimeException, and their subclasses.
Now about I'm thinking it's same. But after searching more I found some difference as theoretical that.
Exception: are recoverable
Errors: not recoverable.
Exception Example:
try{
read file
}
catch(FileNotFoundException e){
// how I can recover here? can i create that file?
// I think we can just make log file to continue or exit.
}
Error Example:
try{
try to locate memory
}
catch(MemoryError e){
// I think we can just make log file to continue or exit.
}
Edited
I'm asking about recover-able and non-recoverable.
Error, as you already figured out, means you are in serious trouble. In a catch block you might be able to do something like logging, but basically that's it.
Non-recoverable exceptions are mostly runtime exceptions like NullPointerException. They are usually the result of some missed checks in the program code. Therefore the solution is normally to fix the code.
A recoverable exception is something that you know beforehand can happen and take certain measures. Think of a web application that calls some backend service. That service may or may not be available which can cause the execution of the operation to fail. Therefore you have a checked exception, in this case most likely a custom exception that you throw, and then handle it in the front end code in a manner where you tell the user, sorry backend service xy is down, try again later or contact support.
Recoverable does not mean that the application can do something to resolve the cause of the exception, though there may be cases where this is possible.
All classes that inherit from class Exception but not directly or indirectly from class RuntimeException are considered to be checked exceptions.Such exceptions are typically caused by conditions that are not under the control of the program.
Example
in file processing, the program can’t open a file if it does not
exist.
Recoverable
So It is very easy to know that if a file does not exists so you dont need to open that file hence that is recoverable
All exception types that are direct or indirect subclasses of RuntimeException (package java.lang) are unchecked exceptions. These are typically caused by defects in program’s code.
Example
ArrayIndexOutOfBoundsExceptions
ArithmeticExceptions
Error
Unrecoverable
So thatswhy program can not recover from these kind of errors or exceptions
Unrecoverable errors are the ones that put the application in an undefined state, like a broken database connection or a closed port, you may handle the error and continue to execute but it would not make sense. Modern languages like Rust and Go use the name panic for errors of these nature, to make the distinction clear. Best action to take is logging the error, if it is possible, and exiting the application.
A recoverable errors are the ones we can handle gracefully, like division by zero or validation errors. It is something expected and the resulting behavior is covered in the language spec. Yes, application behaves erratic when that a recoverable error happens but we can contain it or work around it.
The Object Throwable has 2 childs : Exception and Error.
All Exceptions are recoverable and all Errors are non-recoverable.
All Exceptions are recoverable because you can catch them and let your program continue its execution.
However all Errors , even when you add them to a catch block, will cause the abrupt termination of your program.
Examples of Errors: StackOverflowError, OutOfMemoryError,..
Remark : Checked and unchecked Exceptions are childs of Exception so recoverable.
When would you want to propagate an exception to another Class/Method versus catching the Exception in the same Class/Method?
You catch the exception where you have to handle it.
As a rule of thumb, you should let your exceptions bubble up, but if you don't want your subroutine to crash due to a (possibly expected) error, than you handle the exception, which normally involves logging an error and/or displaying an error message to the user.
The good practice is "throw early and catch late". That allows you to better understand the cause of the exception.
This topic is fairly broad; fortunately there are good resources already in place:
Guidelines on Exception propagation (in Java)
http://www.javacodegeeks.com/2012/04/exception-handling-guidelines-best.html
Best practices for exception management in Java or C#
The great majority of exceptions occuring in real-life code are not recoverable in the sense there's any meaningful code that will retry the operation or try to do it differently. The only recovery happening is aborting the current unit of work in an orderly manner—logging the exception, releasing any resources and similar.
This means that, as a first rule, you'll always want to propagate the exception towards that well-defined exception barrier that demarcates your unit of work.
If your code demands anything different than this, it is probably going to be obvious enough, so you don't need to think about it in the general.
I'm trying to better understand exception handling and logging in a j2ee environment to refactor some legacy code (we use log4j for our logging mechanism). Most of our current code does something like the code below on the business tier, however, I'd like to switch over to unchecked exceptions and just ignore them unless it makes sense to handle them somewhere:
try {
doSomething();
} catch (MyException e) {
log.error("Exception:", e);
throw e;
}
After the exception is thrown in the business tier, it is then propagated up to the presentation tier, which again catches the exception and usually wraps it in a PortletException or ServletException and throws it again. Then, it is handled by a Spring handler which shows a 'friendly' message to the user. I'd ultimately like to only handle exceptions for which we want to show a specific error message, and just ignore everything else.
Questions:
Is it necessary to log exceptions in the business tier? If not, do
I need to log exceptions at all (especially unchecked ones)?
What happens to uncaught exceptions that are not logged using log4j?
(If they're still printed in the console, what's the purpose of
log4j?)
I am confused as to how the process works...
Thanks.
EDIT: If an exception occurs in an outside library (Spring, Hibernate, etc), is it assumed that these exceptions will be printed out using whatever logging mechanism is being used? In that case, I guess that I would only need to log the exceptions that my code throws... or am I way off base here?
Before proceeding any further, please take a careful look at:
The following are some of the generally accepted principles of
exception handling:
If you can't handle an exception, don't catch it.
If you catch an exception, don't swallow it.
Catch an exception as close as possible to its source.
Log an exception where you catch it, unless you plan to rethrow it.
Structure your methods according to how fine-grained your exception handling must be.
Use as many typed exceptions as you need, particularly for application exceptions.
Point 1 is obviously in conflict with Point 3. The practical solution is a trade-off >?between how close to the source you catch an exception and how far you let it fall before you've completely lost the intent or content of the original exception.
IBM DeveloperWorks: EJB best practices
It is usually advised that you use checked exceptions for application exceptions at the business tier. I prefer to follow the business interface pattern to decouple the business tier from the user interface and web tier. This will allow me to think of your business tier as a service layer library and callers might want to handle different situations differently when calling this layer. That is one reason you might want to include checked exceptions, since you can react differently to different exceptions. Furthermore, including checked exceptions will usually help the caller code to be better aware of what different situations might arise from invoking some functionality. It could be worth it to take a look at the business delegate pattern and how it might help you with exception handling. In short, the business delegate pattern allows you to create a very thin layer between the business layer and the web layer where you can do things like exception handling.
No matter how you go about doing this, make sure that you understand the implication of adding an application exception to your Java EE application. You may need to investigate how it interacts with your transaction management logic, specifically when it comes to transaction rollbacks. In my line of work, I had to add an #ApplicationException(rollback=false) to forbid the transaction manager from rolling back my transaction when an exception is thrown and propagated upwards.
You may be able to tell I was working with EJB, but the concepts are probably very applicable to your design as well.
So back to your questions:
Is it necessary to log exceptions in the business tier?
It is not necessary if you plan to log it later on. You better devise a logging strategy at a high level and log all caught exceptions there.
If not, do I need to log exceptions at all (especially unchecked
ones)?
I think that you should log exceptions because that will help you debug any issues later on. The user is usually not savvy enough to capture any output that might be produced if the exception propagates and gets printed on his/her screen without you handling it.
What happens to uncaught exceptions that are not logged using log4j?
(If they're still printed in the console, what's the purpose of
log4j?)
I think it will eventually be caught by the web container and be printed out to the console. If an exception propagates upwards and reaches the web container exception handling safety nets, your exception is out of control. It is usually a sign of bad design. It is best if you keep your exceptions under control. Why wonder how a container will react to an uncaught exception? Also how beneficial will that exception be to the user? I think the information presented from uncaught exceptions are almost useless, as they are so far from the source of the error, that they become irrelevant and hard to work with when debugging.
You could create your own exception hierarchy to wrap them to quickly identify from where in your application architecture it is originating. Also one can go a step further to provide codes and reasons that covers majoority of the use cases.
What logging helps you is to identify the sequence of events, when potentially multiple clients are slamming the same use case or hitting a bottle neck. The logging give you a sequence to trace back because requests increasesed there was congestion in this query causing it to timeout and thus other users where seeing another exception.
While handling the application and showing it to the user is another issue.
Cheers!
We definitely do not have to handle exceptions just to log them. I believe we should catch exception if we then throw other exception that contains the source exception as its cause or if we implement some logic that must be implemented in current layer when exception is thrown.
Yes, it is a little bit verbose to declare all methods as throws MyException. This is the reason that Spring (that you use) prefer working with unchecked exceptions. BTW this is the new feature in Java 7: you can ignore exceptions without declaring that method throws it.
I believe that we still need checked exceptions for development of libraries that expose API to 3rd party applications. Application layer exceptions should be mostly runtime and be caught in one central place.
Is it necessary to log exceptions in the business tier?
No. But more logs = better understanding what is going on. In other way more logs = lower performance.
What happens to uncaught exceptions that are not logged using log4j?
You lost them. Logger pretty things that you can save logs in the place where you need and use filters to get only actual logs for now.
You don't need to catch the business exception (as long as it's unchecked). You don't need to handle them or to log them. You can just swallow them. The problem is - what is such exception for?
Exception signals some inappropriate behaviour in the workflow of your application. If it's checked you, typically, can do something about it - try do some operation again, do some workaround, try different action, etc.
If it's unchecked, it is typically an exception you don't know how or can't handle.
It's considered a code smell if all you do is catch an exception and log it. It's not as bad as swallowing it, but still - it's not good.
Some of the containers (i.e. EJB) is required to log occurred exceptions. Moreover, in EJB 3.x if you're in a JTA managed transaction, and you won't catch an unchecked exception which is not marked as #ApplicationException(rollback=false) than the transaction will be automatically rolled back. This might be the reason why you can see some try...catch blocks with just logging code inside.
If you want to get rid of exception handling code in your business logic, you might introduce an interceptor which will react appropriately upon particular exceptions.
HTH!
Firstly, you can and must log the exception stack trace of all exceptions. In fact, IMO if you only log that an exception happened you might as well not log it at all. However, very often what this leads to is a relaxed view of exceptions. What you should strive for is to have 2 log files or one specific category that if exceptions are in that category they mean something critical happened and must be addressed. Even if that means logging the same exception many times. Rather too many than not at all.
Secondly, it's fine to change all exceptions to checked exceptions - the majority of exceptions are not "recoverable". What I have done that worked well is simply wrap all transactions in an exception handling wrapper which logged the exception, then I can guarantee that all exceptions are logged. Furthermore, create a bunch of exception classes that extend runtime exception - this is much better than rethrowing exceptions as runtime exceptions as very often the inner exception stack trace is not logged in full when you wrap exceptions.
And thirdly, it is important to create a mechanism to map exceptions that do filter through to the front end with the back end cause. This is challenging but it's quite important. Errors that the user sees are far easy to track down if you can map them back to an exception stack trace in the log file.
Checked exceptions need to be caught or declared to be thrown at compilation time but runtimeexceptions need not ...why we give important only to checked exception ...
In Java, the original inventors of the language wanted to distinguish between common types of exceptions, which may occur in a program. They came up with these three types:
Checked exceptions are used for errors, which may occur at run-time and are expected (sort of), for example, IOException. When doing file or network I/O, for example, an error may occur at any time (disk full, connection lost, etc.) The programmer has to be aware, that any operation called may fail at any time, and thus, the language enforces this kind of awareness by forcing the programmer to do something about the exception.
Unchecked exceptions are used for programming errors, such as NullPointerException, IllegalArgumentException, etc. These errors are usually the result of an oversight of the programmer, and constitute bugs in the program. They should not be handled by most parts of the code, as all guarantees about the state, the program is currently in and its consistency, are gone. One of the distiguishing features of a run-time exception is, that it is unexpected (you don't really expect there to be a bug in your program, right? -- except on the general level of "of course, I would not bet my life on this program being bug-free")
Errors, from which a recovery is hardly possible, such as OutOfMemoryError, AssertionError, etc. These exceptions are the really bad ones. These guys are usually never handled, and if they occur, will cause the program to crash.
Of course, in practice, many application will handle run-time exceptions (at least by logging them), and even Errors. And frameworks like Spring tend to blur the distinction further by making all exceptions unchecked (i.e., run-time exceptions) anyway. Interestingly, checked exceptions were considered for inclusion in C# and omitted, because they add a heavy burden on the programmer. Opinions vary on that topic, even today.
Taken from http://en.wikipedia.org/wiki/Exception_handling
Unchecked exception types should not
be handled except, with consideration,
at the outermost levels of scope.
These often represent scenarios that
do not allow for recovery:
RuntimeExceptions frequently reflect
programming defects,[19] and Errors
generally represent unrecoverable JVM
failures. The view is that, even in a
language that supports checked
exceptions, there are cases where the
use of checked exceptions is not
appropriate
Clearly mentions that it represents scenarios that do not allow for recovery
The division gives you flexibility: when thinking what kind of exceptions to throw, you should throw checked exceptions only when the application can reasonably recover from them (for example: "can't write file" is rarely a good reason to crash; rather, let's show a message to the user). Runtime exceptions are supposed to be fatal (programming errors), so it's better to let the program crash right away.
It was supposed to be a good idea. But it's just too complex in practice. The core problem is that the library and language designers are supposed to decide what kind of errors are fatal to an application (which doesn't even exist at that time!).
Did you know that while 1 / 0 results in ArithmeticException, 1.0 / 0 is a perfectly legal Infinity? Obvious - or not... And java.text.Format is supposed to convert an arbitrary object to String, but for some reason it throws an unchecked exception (IllegalArgumentException) if the object to be converted is somehow wrong type (e.g. null), so in practice you must remember to write a try-catch block whenever you use Format. Obviously someone thinks that converting nulls to strings is a fatal programming error. I would rather return an empty string. Your mileage may vary. The JDK is full of this kind of weird choices, and it clearly shows the problem of choosing between checked vs. unchecked.
This problem has made many people advocate unchecked exceptions only. I think it's just silly; most exceptions should be taken care of, because they signal something important. If I was a language designer, I would make all exceptions checked, but instead of a try-catch -block, one could use a plain annotation to say "I don't care about this exception" (which essentially would convert that checked exception into a runtime exception). This would give the benefits of checked exceptions (nothing goes unnoticed unless explicitly told so) AND the benefits of unchecked exceptions (no heavy try-catch blocks all around). It would be the application programmer's call to decide what's fatal and what's expected.
Of course, you can catch runtime exceptions if you want to. A plain catch(Exception ex) does it.
Look at the name of the exception "RunTime".
At compile time the compiler can see exactly what and where things can go wrong with most of your code.
However some objects/values can only be evaluated at run-time and unfortunately the compiler cannot foresee this.
e.g. casting an object to int, when it is in fact a string. You can only determine it at run-time. Thus a run-time exception will be thrown
Have a look at the common RuntimeExceptions:
ArithmeticException
ArrayIndexOutOfBoundsException
ClassCastException
EmptyStackException
IllegalArgumentException
IllegalMonitorStateException
NullPointerException
UnsupportedOperationException
Practically speaking: Most of those exceptions can occure everywhere and are most likely a programmers error, and as such are only needed to be handled in some kind of bug reporting handler. Other Exceptions show problems with the environment of the JVM, and need to be handled, because they cannot be guaranteed no to be thrown be the program alone.
if exception occurred at runtime then immediately JVM creates exception object and that object message is printed on console.
unchecked exceptions are occurred due to poor logic of our program.so program will be terminated abnormally.but JVM will not be halted.so JVM creates Excpetion object.
if we consider checked exceptions,for example,if we want to load some external file into our program , JVM is responsible for that.so,if any problems are occurred while that file is loading then JVM will be halted .so,then who creates exception object.this is the problem with checked excpetions .
to over come above problem we have to handle checked excptions at compiletime using throws keyword.
if you handle checked exception the following is done
-- JVM executes one by one statement , when it identifies throws keyword followed by checked exception then it creates checked exception object.so,when the exception is occurred then already created exception object is used to print the exception information on the console.
When you can handle the recovery of the state of Object , go for Checked Exception.
When you cannot handle the recovery go for UnCheckedException.
Mostly API developers go for Runtime Exception ,
they do not want to enforce handling exception by the user,
since they themselves do not know how to handle it
Runtime exceptions can occur anywhere in a program, and in a typical one they can be very numerous. Having to add runtime exceptions in every method declaration would reduce a program's clarity. Thus, the compiler does not require that you catch or specify runtime exceptions (although you can).
There are lot of posts on java.lang.Error saying it should not be caught. My question is if it should not be caugth the what is the use of it. Since it is Throwable so we can catch it in try catch. I read some posts like only in some situation it should be caught, how to know these situations.
In short i want to know what can go wrong when i catch Error. What is process behind it. Why they have made Error and its Subclasses? If my app is not supposed to catch them then what catches them? Why my code cannot handle this caught Error? If i simply catch one Error and write some handling code in Catch block, won't that code run?
An Error (especially a subclass of VirtualMachineError) indicates that the JVM has encountered an internal issue - one that means that its internal state may no longer be consistent. If you catch an Error and attempt to recover, future behaviour is undefined. The reason that errors are Throwable is so they can be thrown - eg you may do it your self for errors in a native library that can't be recovered from (eg the library could have written to JVM memory, or corrupted its internal static state). The same stack walking and stack trace producing machinery is used in the case of all Throwables - it would be silly to have another mechanism to do the same thing.
Most errors in the JVM that are not VirtualMachineErrors are situations where a native library could have corrupted its static state - eg AWTError, ZipError.
However there are some rare cases where catching an Error is sane: AssertionError in a testing framework, and LinkageError where you have to deal with the absence / presence of different versions of libraries at runtime. This is a pretty rare requirement and may be better handled through reflection.
All rules have exceptions (except this one).
Even if everybody say you should not, there are plenty of cases where it's totally appropriate to catch those java.lang.Error. The logic behind the rule was: "do not try to continue running your application after a fatal condition was detected". You therefore must be careful before doing something after such an error is thrown. It is possible that the system might not be able to continue its task afterward.
It might be OK for a servlet to catch OutOfMemoryError, log the error and destroy the session. Maybe the problem was with that precise session. Destroying it would restore the memory and allow other users to continue using the system. However, you should have a mechanism to track those errors in real-time in order to:
Fix programming errors
(AssertionError, StackOverflowError)
Fix configuration errors
(UnsatisfiedLinkError)
Correct JVM sizing parameters (OutOfMemoryError)
This kind of handling should be done very "high" in the call stack (i.e. near the main()), where the main loop (or equivalent) is performed. I think it's not a good practice to catch Error in deep code, you should at least rethrow the error in those cases.
Similar question already answered here - When to catch java.lang.Error?
Basically, you should never attempt to catch it as its thrown on fairly serious issues like when your thread has dead for some reason, and is not recoverable.
There are however sometimes the need to catch the error when dealing with the framework itself as stated in the above URL.