Adding 'throws' on an extended class? - java

I'm making a simple application with the Socket API, but have run into a small issue that I haven't found the answer for.
The application is supposed to be multi-threaded, so that the main method starts both the server and client threads.
public class UDPClientServer1 extends Thread
However, since the the Socket classes need to throw some specific exceptions, I must also do this:
public void runClient() throws SocketException, UnknownHostException, IOException
and similarly for the runServer() method.
Not that there's anything wrong with that, but is there a more elegant solution? Something along the lines of :
public class UDPClientServer1 extends Thread, throws Exception

Ideally you may want to wrap the exception that your throw, either converting it to a RuntimeException if the error is unrecoverable, or at least a more appropriate / encapsulated exception.
E.g.
public void runClient throws ClientException
{
try
{
// do something
} catch (Exception e)
{
log.error("Exception encountered in client",e);
throw new ClientException("Unrecoverable client exception encountered",e);
// or: throw new RuntimeException("Unrecoverable client exception",e);
}
}
ClientException in the above is your own exception that you would need to create. Its purpose is to encapsulate the implementation details of corresponding exceptions from any calling code.
Using a RuntimeException, however, may be more appropriate if there is no reasonable way for the calling code to respond to the exception. When throwing a RuntimeException you do not have to declare it in the method signature and calling code does not need to explicitly handle it (although it should be handled at some point).

Related

Is it okay to declare a checked exception for an exception thrown by a called method?

Consider this:
public void Do() throws Exception {
if (blah) throw new Exception(...);
Thingy thingy = ...;
Foo(thingy);
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Throwable { ... }
In this case, is it okay to not handle EmptyThingyException inside Do and declare Do like so:
public void Do() throws Exception, EmptyThingyException {
or do I have to handle EmptyThingyException inside Do and throw it back again like so:
public void Do() throws Exception, EmptyThingyException {
try {
} catch (EmptyThingyException empty) {
throw empty;
}
...
}
The short answer to the question is:
Yes, it's correct to declare a checked exception thrown by a called method.
How a method achieves its purpose is an implementation detail and it shouldn't matter to the interface how much it does directly or how much it delegates to methods. The language rules about checked exceptions are carefully defined to make sure methods advertise all checked exceptions they may throw or methods they call throw (but are not handled by the method itself). Letting an unhandled exception get 'thrown through' a method is how things are supposed to work.
Indeed the answer is in the name of the construct "non-local exception handling" it was conceived to take effort out of endless error handling all the way up a call chain when the only real action is "that didn't work" at some point near the start.
To align to that method, you should only catch exceptions you're going to do something about.
Clean up code should be achieved with finally so the normal reasons to catch an exception are to log it and/or abandon a task at some point rather than letting the stack unwind further.
In this specific case the best answer would be to throw an IllegalArgumentException:
throw new IllegalArgumentException("thingy==null || thingy.isEmpty()");
That's unchecked and wisely so. Correct code shouldn't encounter illegal arguments and they should expect to be thrown rarely and be indicative of program flaw (either in the class, it's package or consumer code). External and user input should be validated directly and programs shouldn't rely on IllegalArgumentException.
In practice IllegalArgumentException and IllegalStateException should cover 'internal errors' meaning "You can't do this with that" or "You can't do that right now" respectively and should be commented to specify the fault.
The idea that you might sub-class those two because consumer code might respond differently to different illegal actions it might take is bodging pure and simple.
Program correctness includes that a program never makes an illegal call on some other part of the program or enters an invalid or corrupted state and exceptions only occur as a result of environmental failures that mean a program or sub-task in a program cannot be completed as intended.
if you want to do something after exception happen, then use try-catch, or you can just declare it on the method.
Beyond that, if EmptyThingyException is sub class of Exception, then it is no need to declare EmptyThingyException when you have declared Exception.
1- Declare the specific checked exceptions that your method can throw
public void foo() throws Exception { //Incorrect way
}
Always avoid doing this as in above code sample. It simply defeats the whole purpose of having checked exception. Declare the specific checked exceptions that your method can throw. If there are just too many such checked exceptions, you should probably wrap them in your own exception and add information to in exception message. You can also consider code refactoring also if possible.
2- Always catch only those exceptions that you can actually handle
catch (NoSuchMethodException e) {
throw e; //Avoid this as it doesn't help anything
}
Well this is most important concept. Don’t catch any exception just for the sake of catching it. Catch any exception only if you want to handle it or, you want to provide additional contextual information in that exception. If you can’t handle it in catch block, then best advice is just don’t catch it only to re-throw it.
3- Avoid using Throwable class
Throwable is the superclass of Exception and Error, as far as I know you need to use Throwable when you want to deal with both exceptions and errors, but it's definitely not your concern here, most of the java code deal with Exception and it's the way to go whenever you need to deal with checked exceptions http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html.
**
Well if I was you I would do something like :
public void Do() throws BlahIsFoundException{
try {
if (blah) throw new BlahIsFoundException(...);
Thingy thingy = ...;
Foo(thingy);
} catch(EmptyThingyException exception) {
//Handle the exception correctly, at least log it
} finally {
//Do some clean up if needed, for example close a database connection or free some resources.
}
}
public void Foo(Thingy thingy) throws EmptyThingyException {
if (thingy == null ||
thingy.isEmpty()) throw new EmptyThingyException();
...
}
public class EmptyThingyException extends Exception { ... }
public class BlahIsFoundException extends Exception { ... }
Hope that helps, here are some good documents to read :
http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
http://howtodoinjava.com/best-practices/java-exception-handling-best-practices

How am I supposed to let an Unchecked Exception bubble up and log?

So quoting from this page, which is titled: Exception-Handling Antipatterns Blog and seems to be written (or at least to be approved) by Oracle..
An unchecked exception probably shouldn't be retried, and the correct response is usually to do nothing, and let it bubble up out of your method and through the execution stack. This is why it doesn't need to be declared in a throws clause. Eventually, at a high level of execution, the exception should probably be logged.
I am not sure if I understand this. How can I log an unchecked exception? If I have something like:
public static void main(String args) {
foo();
// How do I know what to log here? The method I am calling
// is not throwing an Exception.
// Do I just blindly catch(Exception ex)?
}
static void foo() {
bar();
}
static void bar() {
baz();
}
static void baz() {
// I will do nothing as Oracle suggests and let this exception bubble up.. I wonder who is going to catch it and how this is going to be logged though!
throw new NullPointerException();
}
Can you help me understand what Oracle is suggesting here? I do not see any direct (or clear) way to catch runtime exceptions (I do not understand why it is not just called unchecked exceptions..) in higher levels and I am not sure how this suggested practice is useful. To me it would make more sense if it were talking about checked exceptions. Something like..
If a checked exception is thrown in a method that is not reasonable to be re-tried, the correct response is to let it bubble up and log..
You can also register a global ExceptionHandler that will handle the Exceptions that were not caught by your code:
Thread.setDefaultUncaughtExceptionHandler
This exception handle could then log whatever occured.
First of all, this is a general advice and it depends on the context. The idea behind it is that when a runtime exception occurs (ex. NullPointerException), the system is usually in an indeterministic state, meaning the rest of the code is not be guaranteed to execute as expected, so it's better to stop everything.
In most cases, your code will run in a separate thread and the exception will only stop the current thread, while the rest of the program keeps running.
This is not the case in your example, because everything is executed in a single thread, so the uncaught exception will effectively stop the whole program. In this scenario you might want to catch the exception and handle it.
public static void main(String args) {
try {
foo();
catch(Throwable t) {
t.printStackTrace(); // log exception
// handle the failure
}
}
You can also catch the exception earlier on, log and rethrow it further.
static void bar() {
try {
baz();
catch (Throwable t) { // catch
t.printStackTrace(); // log
throw t; // rethrow further
}
}
Edit: catch Throwable instead of Exception, will also catch Error
Note: Catching throwable is usually a bad idea, and should only be done with a specific purpose, not in general case. See #RC.'s comment.
As I understand it the documentation is suggesting that you have a generic handler at a high level of your code that logs such 'unexpected' (unrecoverable?) exceptions just as the comments in your main method suggest. So it might look something like this
public static void main(String args) {
try {
foo();
}
catch (ArithmeticException aex) { //if it's arithmetic log differently
log("arith issue! "+aex.getMessage());
}
catch (Exception ex) { //Otherwise do the best we can
log("unknown issue! "+ex.getMessage())
}
}
So there is still no path to recovery but at least before the process ends you get a chance to log the issue. You can also use the methods of Exception (or throwable) to get the stack trace and first causal exceptions in many case - so there is is a lot of extra useful information that might be logged.
There is a very straightforward way to catch unchecked exceptions, since they are all subclasses of RuntimeException or Error:
public static void main(String[] args) {
try {
// your code
} catch (RuntimeException | Error e) {
// handle uncaught exceptions, e.g.
e.printStackTrace();
}
}
How do I know what to log here? The method I am calling is not throwing an Exception.
As Joshua Bloch recommends in the Effective Java
Use the Javadoc #throws tag to document each unchecked exception that
a method can throw, but do not use the throws keyword to include
unchecked exceptions in the method declaration
And if you are using method wrapping in multilayered app i can recommend use exception translation:
Higher layers should catch lower-level exceptions and, in their place, throw exceptions that can be explained in terms of the higher-level abstraction
See Effective Java item 61
So i think for your example actually you should use something like:
try {
bar();
} catch(NullPointerException e) {
throw new HigherLevelException(...);
}
The most important guideline regarding exceptions is that a method that couldn't sucessfully complete its task should throw an exception.
Only if you can guarantee successful completion of your method's task, you should catch an exception inside your method (without re-throwing this or another exception). From my experience that's only true in very specific situations, e.g. if you have an alternative way to try if some first attempt fails, or if you really really understand all possible causes of this specific Exception class that you are about to catch.
Speaking about RuntimeExceptions, there are so many different types of RuntimeException that you can hardly justify an assertion like "When such an exception arises in my code or a method called from inside my code, that won't affect the outcome of my method - I can continue just as if nothing happened." So, you should signal to your caller that you failed to fulfill your task, and the clearest way to do that is to let the exception ripple through, without try/catch block or throws declaration, just relying on Java's default behaviour.
In my opinion, the same reasoning applies to nearly all kinds of exceptions, not only RuntimeExceptions.
The difference with checked exceptions is that you have to declare them in the throws clause of your method. Then you have two choices: list the exception in the throws clause of your method (and all parent methods as well!) or catch the exception, wrap it in a new RuntimeException(ex), and throw that from your method.
With e.g. a typical GUI application, your users will be grateful if a problem in one menu function won't crash the whole application - probably other menu items might still work as expected. So, top-level commands or menu items are typically the places where to catch exceptions, tell the user something like "Oops!", log the exception to some file for later inspection, and allow the user to continue with another action.
In your main/foo/bar/baz application, I don't see a place where continuing after an exception makes sense. So the whole program should be aborted (which happens automatically in your case). If you want some error logging to a file, then establish an uncaught exception handler or wrap the body of main() in a try / catch(Throwable t) block. You'll probably want every exception logged, whatever type it is, so catch them all, and that's why I'm suggesting Throwable.
public static void main(String[] args) {
try {
foo();
}
catch(NullPointerException e){
System.out.println("NullPointerException in main.");
}
}
static void foo() {
bar();
}
static void bar() {
baz();
}
static void baz() {
// I will do nothing as Oracle suggests and let this exception bubble up.. I wonder who is going to catch it and how this is going to be logged though!
throw new NullPointerException();
}
OUTPUT :
NullPointerException in main.
Basically the error is expected at a higher level, so there is no need to catch it on the baz() method level. If I understood correctly.
You can catch them just like any other exception with try-catch block. But the benefit is that you don't have to.
Use cases can vary. To my mind, the most popular is when it doesn't make sense to catch the exception right in that place or the appropriate handling should be implemented several levels (in terms of methods) higher than the method, calling the one throwing the exception (sorry, if that is not clear enough).
For example, the typical web application layout in java is as follows: you have a layer of controllers, a layer of services and a layer of dao. First one is responsible for dispatching requests, the second one is for managing business logic and the last one makes actual calls to db. So here for example it often doesn't make much sense to catch the exception in service layer if something goes wrong on the dao level. Here unchecked exceptions can be used. You log an exception and throw an unchecked exception so it could be handled some levels above for a user to get valuable feedback of work of the application.
If in this case you throw a checked exception you will have to rethrow it every level above just to bubble up it to the place of the actual handling. So here the unchecked exception is better to use in order not to copy and paste all that ugly try-catch block, rethrowing an exception and add the throws clause to the method.

exception handling in the api

I have a java interface that has a method as below -
List<TalkDO> process() throws DurationException;
DurationException is unchecked exception.
I am writing an implementation for this function where I read data from a file and process each line one by one. File read in requires to handle FileNotFoundException and IOException. I have to throw this exception to caller and to let it know that these 2 exception has occered but throwing this exception will make it like
List<TalkDO> process() throws IOException, FileNotFoundException
Which is not allowed in java. What could be my approach, I dont want to catch and handle IOException and FileNotFoundException in my process method
As you have multiple implementations of your interface and according to your comments some don't use File, I think that providing an interface that specifies exceptions of every implementations may be cumbersome for clients.
Why force a client to catch FileNotFoundException if he uses an implementation that cannot throw it?
A more flexible way would be to declare only throwing runtime exceptions in List<TalkDO> process().
In your implementation, you should catch checked exceptions and re-throw
a RuntimeException version of them.
In this way, each client will catch the exception he needs to.
Interface
public MyInterface {
public List<TalkDO> process() throws DurationException, IORuntimeException, FileNotFoundRuntimeException
}
Implementation using File
public MyFileImpl implements MyInterface{
public List<TalkDO> process() throws DurationException, IORuntimeException, FileNotFoundRuntimeException{
...
try{
}
catch (IOException e){
throw new IORuntimeException("your msg", e);
}
catch (FileNotFoundException e){
throw new FileNotFoundRuntimeException("your msg", e);
}
}
Implementation without using File
public MyInMemoryImpl implements MyInterface{
public List<TalkDO> process() throws DurationException {
...
}
}
throws DurationException, IOException, FileNotFoundException is not
allowed in Java
This is not correct, you can specify multiple exceptions in the method signature using the throws clause, you can look here on this.
Also, one important point is that it is not good practice to specify the unchecked exceptions (like your DurationException) in the method signature, it will make the method signature to clutter, look here for more details.
What could be my approach, I don't want to catch and handle IOException
and FileNotFoundException in my process method
You either have to catch or throw the checked exceptions and say if you don't want to propagate these exceptions as checked exceptions to the caller, you can wrap these checked exceptions into unchecked (runtime exceptions).
It is saying process()' in 'FileInputProcessor' clashes with
'process()' in 'InputProcessor'; overridden method does not throw
'java.io.FileNotFoundException
The important point about Java exceptions is that you can't throw new checked exceptions from the overriding methods, so you need to convert them into unchecked/RuntimeException objects. So, the solution is in your implementation class, you need to wrap the checked exception and throw a new RuntimeExcetion (just create your own custom BusinessException i.e., project specific).

Throw IOException instead of Exception

I have method1() which is called from lots of other methods throughout the code. This is the signature of the method:
public void method1(final Properties properties) throws IOException {}
All methods calling this method also throw IOException.
The actual code in method1() changed, so now instead of IOException it throws some other exceptions that extend Exception and not IOException anymore.
I don’t want to change the signature of all methods calling method1().
Is it ok to create IOException and still throw IOException from method1() and hence the methods calling method1()?
Something like below:
Try {
// code
} catch (Exception e) {
throw new IOException(e.getCause());
}
No, you should not do this, because you will confuse every other developer reading your code or reading stacktraces.
From the software-design point of view, the error happened a lot earlier.
If your code is like an API and used by others, you may better have used Custom-Exceptions and wrapped the IOException as root-cause.
If you have the complete source, you should refactor the source and add another exception signature.
You need to save the original exception as the cause, so you're not losing the original message or stacktrace. Calling e.getCause() in your code example is skipping over the exception that you caught and getting its cause, which is suspicious-looking.
Also it would be better to specify the particular exceptions that the method catches, rather than using a catch-all Exception type. Catching Exception would result in things like NullPointerExceptions getting caught that were not trapped before.
The best thing to do here is change the exceptions thrown by your method to a custom type that doesn't let the implementation details bleed through to the callers. Your method signature should change to
public void method1(final Properties properties) throws SomeCustomException {
try {
.... // do whatever
} catch (AException | BException | CException e) {
throw new SomeCustomException(e);
}
}
This will work technically.
However, catching Exception or Throwable is almost everytime a bad idea (as is throwing them), because you will also catch all other Exceptions, besides RuntimeExceptions.
If you can change the code of all calling classes (i.e. you are not developing a framework/library), you should do so. Because I assume you meant method1() throws a more specific type now.
You may also think about throwing a Subtype of RuntimeException which does not need to be catched, and is a good idea for errors that can't be corrected (e.g. a bad configuration).
(see Clean Code by Robert Martin)

Where is this exception caught and handled?

In some code I've been reading, I've come across this :
class Someclass
{
public static void main(String[] args) throws IOException
{
//all other code here......
}
}
If main() throws an exception, in this case its an IOException, where is it caught and handled?
EDIT:
Is this considered bad practice? Or is this really common in real world code?
The detailed flowchart of full uncaught exception handling is given here: How uncaught exceptions are handled in Java.
When an uncaught exception occurs, the JVM does the following:
it calls a special private method, dispatchUncaughtException(), on the Thread class in which the exception occurs;
[...which] calls the thread's getUncaughtExceptionHandler() method to find out the appropriate uncaught exception handler to use. Normally, this will actually be the thread's parent ThreadGroup, whose handleException() method by default will print the stack trace.
it then terminates the thread in which the exception occurred.
Therefore you can, if you wish to, create your own custom uncaught exception handler.
It should also be noted that while main is commonly used as a Java application entry point, the method is just like any other methods in that it can also be called from other contexts (e.g. other main methods, or even itself recursively!). In that case, the caller can catch exceptions thrown.
public class SelfCatch {
public static void main(String args[]) throws Exception {
if (args == null) throw new Exception("Hi there!");
try {
main(null);
} catch (Exception e) {
System.out.println("Caught: " + e);
}
System.out.println("Exiting...");
}
}
Output:
Caught: java.lang.Exception: Hi there!
Exiting...
EDIT: Is this considered bad practice?
Or is this really common in real world
code?
It would be in production code, but when rapid prototyping or knocking up test code its often used as its quicker than typing the try {...} catch block. (unless you use a good IDE like Eclipse 3.5 which has an 'Auto wrap in try/catch' feature [auto-detecting any and all exceptions to!] ;-) )
Or your pretty sure it wont be thrown by methods invoked by main().
But even wrapping in a try/catch block will usually result in the same output as if you leave the Exception uncaught, if you simply use e.printStackTrace() ...
At the command line.
EDIT: The entry point is Main. Hence, there is no other method/caller to handle the exception.

Categories

Resources