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.
Related
New Java programmers frequently encounter errors phrased like this:
"error: unreported exception <XXX>; must be caught or declared to be thrown"
where XXX is the name of some exception class.
Please explain:
What the compilation error message is saying,
the Java concepts behind this error, and
how to fix it.
First things first. This a compilation error not a exception. You should see it at compile time.
If you see it in a runtime exception message, that's probably because you are running some code with compilation errors in it. Go back and fix the compilation errors. Then find and set the setting in your IDE that prevents it generating ".class" files for source code with compilation errors. (Save yourself future pain.)
The short answer to the question is:
The error message is saying that the statement with this error is throwing (or propagating) a checked exception, and the exception (the XXX) is not being dealt with properly.
The solution is to deal with the exception by either:
catching and handling it with a try ... catch statement, or
declaring that the enclosing method or constructor throws it1.
1 - There are some edge-cases where you can't do that. Read the rest of the answer!
Checked versus unchecked exceptions
In Java, exceptions are represented by classes that descend from the java.lang.Throwable class. Exceptions are divided into two categories:
Checked exceptions are Throwable, and Exception and its subclasses, apart from RuntimeException and its subclasses.
Unchecked exceptions are all other exceptions; i.e. Error and its subclasses, and RuntimeException and its subclasses.
(In the above, "subclasses" includes by direct and indirect subclasses.)
The distinction between checked and unchecked exceptions is that checked exceptions must be "dealt with" within the enclosing method or constructor that they occur, but unchecked exceptions need not be dealt with.
(Q: How do you know if an exception is checked or not? A: Find the javadoc for the exception's class, and look at its parent classes.)
How do you deal with a (checked) exception
From the Java language perspective, there are two ways to deal with an exception that will "satisfy" the compiler:
You can catch the exception in a try ... catch statement. For example:
public void doThings() {
try {
// do some things
if (someFlag) {
throw new IOException("cannot read something");
}
// do more things
} catch (IOException ex) {
// deal with it <<<=== HERE
}
}
In the above, we put the statement that throws the (checked) IOException in the body of the try. Then we wrote a catch clause to catch the exception. (We could catch a superclass of IOException ... but in this case that would be Exception and catching Exception is a bad idea.)
You can declare that the enclosing method or constructor throws the exception
public void doThings() throws IOException {
// do some things
if (someFlag) {
throw new IOException("cannot read something");
}
// do more things
}
In the above we have declared that doThings() throws IOException. That means that any code that calls the doThings() method has to deal with the exception. In short, we are passing the problem of dealing with the exception to the caller.
Which of these things is the correct thing to do?
It depends on the context. However, a general principle is that you should deal with exceptions at a level in the code where you are able to deal with them appropriately. And that in turn depends on what the exception handling code is going to do (at HERE). Can it recover? Can it abandon the current request? Should it halt the application?
Solving the problem
To recap. The compilation error means that:
your code has thrown a checked exception, or called some method or constructor that throws the checked exception, and
it has not dealt with the exception by catching it or by declaring it as required by the Java language.
Your solution process should be:
Understand what the exception means, and why it could be thrown.
Based on 1, decide on the correct way to deal with it.
Based on 2, make the relevant changes to your code.
Example: throwing and catching in the same method
Consider the following example from this Q&A
public class Main {
static void t() throws IllegalAccessException {
try {
throw new IllegalAccessException("demo");
} catch (IllegalAccessException e){
System.out.println(e);
}
}
public static void main(String[] args){
t();
System.out.println("hello");
}
}
If you have been following what we have said so far, you will realise that the t() will give the "unreported exception" compilation error. In this case, the mistake is that t has been declared as throws IllegalAccessException. In fact the exception does not propagate, because it has been caught within the method that threw it.
The fix in this example will be to remove the throws IllegalAccessException.
The mini-lesson here is that throws IllegalAccessException is the method saying that the caller should expect the exception to propagate. It doesn't actually mean that it will propagate. And the flip-side is that if you don't expect the exception to propagate (e.g. because it wasn't thrown, or because it was caught and not rethrown) then the method's signature shouldn't say it is thrown!
Bad practice with exceptions
There are a couple of things that you should avoid doing:
Don't catch Exception (or Throwable) as a short cut for catching a list of exceptions. If you do that, you are liable catch things that you don't expect (like an unchecked NullPointerException) and then attempt to recover when you shouldn't.
Don't declare a method as throws Exception. That forces the called to deal with (potentially) any checked exception ... which is a nightmare.
Don't squash exceptions. For example
try {
...
} catch (NullPointerException ex) {
// It never happens ... ignoring this
}
If you squash exceptions, you are liable to make the runtime errors that triggered them much harder to diagnose. You are destroying the evidence.
Note: just believing that the exception never happens (per the comment) doesn't necessarily make it a fact.
Edge case: static initializers
There some situations where dealing with checked exceptions is a problem. One particular case is checked exceptions in static initializers. For example:
private static final FileInputStream input = new FileInputStream("foo.txt");
The FileInputStream is declared as throws FileNotFoundException ... which is a checked exception. But since the above is a field declaration, the syntax of the Java language, won't let us put the declaration inside a try ... catch. And there is no appropriate (enclosing) method or constructor ... because this code is run when the class is initialized.
One solution is to use a static block; for example:
private static final FileInputStream input;
static {
FileInputStream temp = null;
try {
temp = new FileInputStream("foo.txt");
} catch (FileNotFoundException ex) {
// log the error rather than squashing it
}
input = temp; // Note that we need a single point of assignment to 'input'
}
(There are better ways to handle the above scenario in practical code, but that's not the point of this example.)
Edge case: static blocks
As noted above, you can catch exceptions in static blocks. But what we didn't mention is that you must catch checked exceptions within the block. There is no enclosing context for a static block where checked exceptions could be caught.
Edge case: lambdas
A lambda expression (typically) should not throw an unchecked exception. This is not a restriction on lambdas per se. Rather it is a consequence of the function interface that is used for the argument where you are supplying the argument. Unless the function declares a checked exception, the lambda cannot throw one. For example:
List<Path> paths = ...
try {
paths.forEach(p -> Files.delete(p));
} catch (IOException ex) {
// log it ...
}
Even though we appear to have caught IOException, the compiler will complain that:
there is an uncaught exception in the lambda, AND
the catch is catching an exception that is never thrown!
In fact, the exception needs to be caught in the lambda itself:
List<Path> paths = ...
paths.forEach(p -> {
try {
Files.delete(p);
} catch (IOException ex) {
// log it ...
}
}
);
(The astute reader will notice that the two versions behave differently in the case that a delete throws an exception ...)
More Information
The Oracle Java Tutorial:
The catch or specify requirement
... also covers checked vs unchecked exceptions.
Catching and handling exceptions
Specifying the exceptions thrown by a method
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
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)
I use java.lang.ExceptionInInitializerError to rethrow caught exceptions in static initialisation blocks. I noticed it is not possible to construct with both a message and a cause; only one or the other.
Is there a good reason why?
What alternatives can you suggest for rethrowing checked exceptions as unchecked exceptions from a static init block? Ex: Rethrow as java.lang.RuntimeException which allows both message and cause.
UPDATE: Clarified #2 and added sample code.
public class Sample {
private static final String _FILE_PATH = "blah/blah/blah";
static {
try {
FileReader in = new FileReader(new File(_FILE_PATH));
}
catch (FileNotFoundException e) {
// Option A: Without context message
throw new ExceptionInInitializerError(e);
// Option B: With context message
String msg = String.format("Failed to open file for reading: '%s'", _FILE_PATH);
throw new RuntimeException(msg, e);
}
}
}
Ref: Why doesn't Java allow to throw a checked exception from static initialization block?
As documented here, there is a constructor ExceptionInInitializerError(Throwable thrown), which you probably should be using instead: it conforms to standard exception chaining, which preserves the stack trace and does other useful stuff (see a sample chained-exception output).
Edit
As noted in this answer to the question you linked to: it is forbidden to allow a checked exception to fall out of a static block; unchecked exceptions are fine, but cannot be caught anywhere, unless one is doing manual dynamic class-loading with Class.forName (very uncommon).
This translates to "good luck catching anything you throw in a static initializer". Basically, whatever exception you construct and throw, it won't be much use.
You want to throw an exception with both a message (that you write) and the exception itself. I like to do the same, providing context for the error and the exception. I would throw an Exception (or an instance of an Exception class that extends Exception or a sub class), not RuntimeException since you probably want the exception to be checked. Right?
Generally speaking you should throw checked excpetions in cases where your system could potentially recover (at a higher level) from an exception and runtime exceptions (unchecked) when the system cannot. (James Gosling's view)
It's an Error. Generally errors are what an application shouldn't even try to catch and recover from.
As for why it doesn't have a constructor with both the message and cause, it's probably because the developers of that class didn't deem it necessary since the main purpose of that class is to let you know "oops shit happened bro, can't recover..."
Personally I think that one of those is enough to identify the error.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Throws or try-catch
I'm writing an API and I wish to write code such that I can raise an exception in a particular scenario. I've created an exception class as follows :-
public class InvalidSeverityException extends Exception {
private static final long serialVersionUID = 1L;
public InvalidSeverityException() {
// TODO Auto-generated constructor stub
}
}
In the codebase im having the following to call the code :-
throw new InvalidSeverityException();
However Eclipse suggests that I either use throws or enclose it within a try ... catch block. I feel that I shouldn't be catching this error and that the developers who use my API should enclose the code within try...catch.
Does that make sense? Am I doing something wrong?
When handling with exceptions in Java you must understand the concept of checked exceptions and unchecked exceptions.
In your case currently you are defining a checked exception, maybe you want an unchecked one.
Here's a brief description about each one of the types:
Checked Exceptions
This exceptions must be part of the method's signature that raises them (or that invokes one method that does) or you must catch them with a try catch block and deal with the problem. Usually checked exceptions are used when there is something that can be done about the error and also when you want the developer to be aware that such error may occur and that has to be handled.
In java java.lang.Exception is a checked exception and all its subclasses will also be checked.
Unchecked Exceptions
This exceptions on the other hand don't need to make part of the method signature, nor you have to wrap methods that throw new in a try catch block. It's just expected that somewhere in the call stack there will be a try catch to handle it, otherwise if it reaches the JVM it will nicely dump you a stacktrace.
In java java.lang.RuntimeException is an unchecked exception and so are all its subclasses.
My opinion
If you are defining an API my suggestion is to use checked exceptions, this is mostly because you explicitly inform the developers using your API that such an exception might occur (so they can handle it anyway they want).
You are correct, you should not catch it. As suggested by eclipse, you should use throws so that the developers will know that your method potentially throws that exception and can then catch it.
.... method() throws YourException{
The method where you have throw new InvalidSeverityException(); should define throws InvalidSeverityException
Example:
void yourMethod() throws InvalidSeverityException
{
........//Some code
throw new InvalidSeverityException();
}
Well then surely you follow the first suggestion by Eclipse and set your method to throw the exception.
public void myMethod() throws InvalidSeverityException {
//throw it somewhere in here so that other
//developer can catch it while calling your method
}