I'm developing a library and in some method I want to throw a ClassNotFoundException but eclipse force me to either 'Add a throws declaration' or 'Surround with try/catch'. I do not want to implement any of them, what I want is to throw this excepcion to the client of the class. I've seen that all classes that extend ReflectiveOperationException force me to add or surround the exception. In the other hand I've seen that classes that extend RuntimeException does not require to add or surround the exception.
As an abstraction of my problem, imagine a code like this:
public Class getClassForCellType(int cellTypeRequested) {
Class cellClassRequired = null;
if (cellTypeRequested == 0) {
cellClassRequired = CellA.class;
} else if (cellTypeRequested == 1) {
cellClassRequired = CellB.class;
} else {
throw new ClassNotFoundException("cellType Not Available");
}
return cellClassRequired;
}
I want to throw ClassNotFoundException because is what is happening and I would not like to use another more generic class. Someone could please explain me why those ReflectiveOperationException classes require handling them directly.
I think your problem arises because you are not using ClassNotFoundException for the purpose it is intended. This exception is very specifically intended to be thrown when the implementation of a requested Java class is not available on the classpath.
Here you are trying to translate a parameter into a Class, but that is not the same as the system level error of a missing Class definition.
I would create your own CellTypeClassNotResolvedException which extends RuntimeException and throw that instead:
public CellTypeClassNotResolvedException extends RuntimeException {
public CellTypeClassNotResolvedException(String s) {
super(s);
}
}
Eclipse is telling you (as any Java compiler must do) that if you want a ClassNotFoundException to be able to escape your method, the method must declare that that is a possibility, like so:
public Class getClassForCellType(int cellTypeRequested) throws ClassNotFoundException {
// ...
throw new ClassNotFoundException("cellType Not Available");
// ...
return cellClassRequired;
}
This is the rule for any Exception other than java.lang.RuntimeException and its subclasses.
You need to add a throws declaration due to ClassNotFoundException being a checked exception. TO fix your code, it would look like this:
public Class getClassForCellType(int cellTypeRequested) throws ClassNotFoundException {
Class cellClassRequired = null;
if (cellTypeRequested == 0) {
cellClassRequired = CellA.class;
} else if (cellTypeRequested == 1) {
cellClassRequired = CellB.class;
} else {
throw new ClassNotFoundException("cellType Not Available");
}
return cellClassRequired;
}
In Java, we have two core types of exceptions:
Checked, and unchecked exceptions.
Checked exceptions: If this type of exception is thrown, it has to be explicitly handled by either the client of the method or the method itself. ReflectiveOperationException is an example of this. These types of exceptions are usually used to reflect API problems, usage problems, legitimate/business application failures.
Java's way of fulfilling this requirement is to say you either have to handle (i.e. catch the exception) in your method, or you have to explicitly inform the client that they may get this exception (i.e. throws clause).
Unchecked exceptions: If this type of exception is thrown, it does not have to be handled explicitly. These are usually reflective of programming errors - for instance, ArrayIndexOutOfBoundsExceptions is a good example - you wouldn't anticipate running into this problem, and if you did, you can be relatively confident it's a bug and don't expect the client to cater for it in their code!
In your example, you are trying to tell the client that they passed you a bad parameter by throwing the ClassNotFoundException. They need to know this might be thrown in order to handle the scenario in their code, hence you need to add the throws declaration to the method signature.
public Class getClassForCellType(int cellTypeRequested) throws ClassNotFoundException {
}
See Oracle Docs on more exception tutorials: http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
Related
Let say I have 2 projects A (API), and B (implementation).
My sonar-lint tells me I should never throw Exception because it is too generic. So, what should be the proper way to handle any kinds of exceptions in the API, including both runtime and "checked" exceptions ?
Project A
public interface IBuilder {
public void create() throws Exception;
}
Project B
public abstract class ABuilder implements IBuilder {
public void create() throws Exception {
throw myImplException();
}
}
public class ARealBuilder extends ABuilder {
public void create() throws Exception {
//Some Exceptions and RunTimeExceptions can occurs
}
}
If I create my own exception type like this:
public class myException extends Exception {
}
Does this handle RuntimeExceptions ?
Just my two cents, but as I started typing it in a comment it became too long:
Throwing Exception doesn't provide any useful information, what do you do in the catch part of your API method? You always have to handle all exceptions and/or re-throw them.
The proper way of handling exceptions has to be done in the implementation part (Project B):
Is the information not useful or can/should be handled Project B? Handle it (via a retry mechanism or providing a meaningful default value, e.g. user not found in session => return an UnknownUser object or null).
Is the information useful for Project A? Define a project specific exception, e.g. UserNotFoundException and throw that one. Then Project A can handle that specific case.
You don't need to define the RuntimeExceptions as they are bubbling up the call stack until Project A anyway (if not handled/catched before in Project B), but yes they are also children of Exception.
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
I was reading an article about checked and unchecked Exceptions in Java and found this article/link:
https://projectlombok.org/disableCheckedExceptions.html
According to the article it's just a hack developed for javac.
Consider the code snippet below:
import java.io.*;
class Example
{
public static void main(String args[]) throws IOException
{
FileInputStream fis = null;
fis = new FileInputStream("myfile.txt");
int k;
while(( k = fis.read() ) != -1)
{
System.out.print((char)k);
}
fis.close();
}
}
Here I have to write public static void main(String args[]) throws IOException
because I am trying to open a file. Here "throws" clause is a must. Without it I will get an error. What if I am sure about the Existance of the file I am opening. i.e.myfile.txt in the mentioned location. At some point one can feel that few Checked Exceptions are not required for the code.
Is there any facility provided by Java to disable checked Exceptions according to the need?
Even after doing so much research I could not find a proper answer for it.
Is there any facility provided by Java to disable checked Exceptions according to the need?
No official facilities, but there are workarounds one can use when needed:
First, since there are both checked and unchecked exceptions in java, using unchecked exceptions might be an option. All exceptions which derive from RuntimeException are unchecked:
RuntimeException is the superclass of those
exceptions that can be thrown during the normal operation of the
Java Virtual Machine.
A method is not required to declare in its throws
clause any subclasses of RuntimeException that might
be thrown during the execution of the method but not caught.
Interesting read here, here.
Then there is type erasure which allows to throw a checked exception without declaring it.
This is what project lombok uses for #SneakyThrows
import lombok.SneakyThrows;
public class SneakyThrowsExample implements Runnable {
#SneakyThrows(UnsupportedEncodingException.class)
public String utf8ToString(byte[] bytes) {
return new String(bytes, "UTF-8");
}
#SneakyThrows
public void run() {
throw new Throwable();
}
}
Use with caution:
Be aware that it is impossible to catch sneakily thrown checked types directly, as javac will not let you write a catch block for an exception type that no method call in the try body declares as thrown.
And lastly it's only the compiler which cares about checked exceptions, it's not part of the jvm at all. Once you're past the compiler stage anything is possible. So writing bytecode directly or using a version of javac with checked exceptions disabled completely bypasses them.
Other than hacking the compiler there is no option to disable checked exceptions I know of. Best you can do is catch the checked exception and rethrow it within a runtime exception if you don't want to force the client code to handle the checked exception.
It is designed in Java that I get a Throwable object if I invoke getCause() on an Exception.
I understand that getCause() is simply inherited from Throwable and I know that Throwable can be either an Error or an Exception, but a programmer generally should work only on the Exception level without dealing with Throwable/Error classes.
What was the reason in the Java exception hierarchy design to, for example, not include getCause() in the Exception class that would return an Exception object?
Here is an illustration of the inconvenience taken from Java Concurrency In Practice (Brian Goetz):
public class Preloader {
private final FutureTask<ProductInfo> future =
new FutureTask<ProductInfo>(new Callable<ProductInfo>() {
public ProductInfo call() throws DataLoadException {
return loadProductInfo();
}
});
private final Thread thread = new Thread(future);
public void start() { thread.start(); }
public ProductInfo get()
throws DataLoadException, InterruptedException {
try {
return future.get();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof DataLoadException)
throw (DataLoadException) cause;
else
throw launderThrowable(cause);
}
}
}
It is said in the book:
...but also because the cause of the ExecutionException is returned as a Throwable, which is inconvenient to deal with...
And in launderThrowable() it is dealt with rethrowing Error right away (because we don't want to deal with it) and returning RuntimeException:
public static RuntimeException launderThrowable(Throwable t) {
if (t instanceof RuntimeException)
return (RuntimeException) t;
else if (t instanceof Error)
throw (Error) t;
else
throw new IllegalStateException("Not unchecked", t);
}
getCause is a method defined in Throwable, and simply inherited in Exception. The cause of a Throwable is simply a Throwable (it could be an Exception or an Error).
IMO, having a method, say getCauseAsException, that just returns an Exception if any as the cause exception is not really useful. You could simply invoke getCause() and check if it's an instance of Exception if you're just concerned with Exception and not Errors.
First, if you have a type that has a few subtypes, and their behavior is really the same, it makes sense to define the methods at the parent class. Basically, what the designers are saying is: "Throwable can have a cause, which is also a throwable, and you can get that cause". And you can do that in both Exception and Error because they both happen to be throwables.
Now, the Throwable hierarchy exists since Java 1.0, and generics didn't exist there. Nowadays you might be able to have defined the behavior like this:
class ModernThrowable<T extends ModernThrowable<T>> {
T getCause() {...}
}
And you could define ModernException as extends ModernThrowable<ModernException> and then you could get the sort of behavior that you expect.
But this design didn't exist back then, so you get a Throwable back, and you have to cast it. That's how things used to work and you have to keep backward compatibility.
But actually... as plausible as this may sound, this is not true. At least, it's not the whole truth.
It is perfectly OK to get an Error as the cause of an Exception. Take a look at javax.management.RuntimeErrorException. When you are working with an agent, you might get an Error, which in these special circumstances, should not cause you to abort the system immediately. So you put it as the cause of this special Exception. And thus, your getCause() will actually return an Error from an Exception.
So if it wasn't designed like this, you would have to go through hoops - have a specialty method just for the cause of this particular exception.
Programmers generally work at the Exception level when they are implementing applications. But remember that the JVM, for instance, is also implemented in Java and, in this context, programmers should work at the Throwable/Error level too.
So the question of at which level in the exception hierarchy tree you should work its more of an issue of the domain of the system you're implementing, than an issue of the language design itself. So it makes perfect sense from a language design perspective to provide the getCause method in the Throwable class, which is the root of the hierarchy tree. Since the Exception class inherits this method from its superclass, it's not necessary to provide the same method with a different return type just because in some specific domains you don't/shouldn't work with Throwable instances.
In my unit test, I test a method for an expected RuntimeException and I want to distinct those thrown by my component from ones thrown by the code called in the method.
Creating a custom exception type is unnecessary and does not solve the problem if the method throws the same exception type but for different reasons, e.g. InvalidArgumentException.
Looks like the only way to tell them is the message or the error code. Because the message can be changed during development, the error code seems the only reliable option.
What is the best practice for creating of system of error codes so they don't conflict with ones of external packages, eg. third party libraries?
Creating a custom exception type is unnecessary and does not solve the
problem if the method throws the same exception type but for different
reasons, e.g. InvalidArgumentException.
Why do you think it's unnecessary? This is what you should do. Derive your own custom exception classes, throw their instances from your code and catch them outside (in your unit tests). The catch statement can be repeated in anticipation of multiple different exception classes:
try {
// something
} catch (MySpecificException e) {
// you know that your code threw this
} catch (Exception e) {
// this is coming from somewhere else
}
--Edit--
Sorry, I didn't see the java tag. Even though the following example uses PHP constructs, the principles should still apply.
--Original--
I use custom exception codes in only a few, very specific cases, and I store these codes in a custom exception class which extends the default exception class. They are stored in the class as constants, as the value doesn't really matter, but the context does.
Consider:
class CoreLib_Api_Exception extends Exception
{
const EXCEPTION_FORMAT = '%s (%s): %s';
const CODE_FILE_DNE = 100;
const CODE_DIR_BASE_EQUALS_REMOVE = 101;
const CODE_XML_READER_UNABLE_TO_OPEN = 200;
const CODE_XML_READER_UNABLE_TO_READ = 201;
}
// Example usage
class CoreLib_Api_Reader
{
protected function getReader()
{
$reader = new CoreLib_Api_Xml_Reader();
if (!#$reader->open($this->getFileUri())) {
$e = new CoreLib_Api_Exception(sprintf('Could not open %s for parsing', $this->getFileUri()), CoreLib_Api_Exception::CODE_XML_READER_UNABLE_TO_OPEN);
throw $e;
}
}
}
// Calling code
try {
$reader = CoreLib_Api_Reader();
$reader->setFileUri($fileUri);
$reader->getReader();
} catch (Exception $e) {
// If code is anything other than open, throw it
if ($e->getCode() !== CoreLib_Api_Exception::CODE_XML_READER_UNABLE_TO_OPEN) {
throw $e;
}
$e = null;
$reader = null;
}
By using the exception code, I can check to determine if the reader is unable to open the file, if so ignore the exception and move on, otherwise throw the exception and break the flow.
And if one of my exception codes collides with a third party exception code, it doesn't matter, as I mentioned before, using constants, the context will dictate which code I want to match on.
I test a method for an expected RuntimeException
I think this is a mistake. A RuntimeException should be used only for indicating bugs in the code that the code itself can detect. Testing should test only for specified (defined) behaviour. But when there is a bug in some code, its behaviour is undefined (who knows where the bug could be or what it might do). So there is no point in trying to specify what RuntimeExceptions some code should throw; that is like specifying how the code should behave "in the presence of a bug". Throwing particular RuntimeExceptions with particular messages should be seen as a courtesy to the maintenance programmer (who is likely to be you).