import java.io.*;
class West1 extends Exception {
private String msg;
public West1() {
}
public West1(String msg) {
super(msg);
this.msg=msg;
}
public West1(Throwable cause) {
super(cause);
}
public West1(String msg,Throwable cause) {
super(msg,cause);
this.msg=msg;
}
public String toString() {
return msg;
}
public String getMessage() {
return msg;
}
}
public class West {
public static void main(String[] args) {
try {
throw new West1("Custom Exception.....");
}catch(West1 ce) {
System.out.println(ce.getMessage());
//throw new NumberFormatException();
throw new FileNotFoundException();
}catch(FileNotFoundException fne) {
fne.printStackTrace();
}/*catch(NumberFormatException nfe) {
nfe.printStackTrace();
}*/
}
}
In the above code, NumberFormatException is thrown from catch block it compile and run successfully but when FileNotFoundException is thrown from catch block it will not compile. Following Errors are thrown:
West.java:40: error: exception FileNotFoundException is never thrown in body of
corresponding try statement
}catch(FileNotFoundException fne){
West.java:39: error: unreported exception FileNotFoundException; must be caught
or declared to be thrown
throw new FileNotFoundException();
So my question is what is reason behind this behaviour?
NumberFormatException is a RuntimeException, meaning that it's not required to be declared in all methods it may be thrown. This means that, unlike FileNotFoundException, the compiler can not know if it can get thrown in a block or not.
The title implies you are trying to catch multiple exceptions at once, and your code implies you understand that you can have multiple catch blocks for a single try block to catch different types of exceptions. Everything is good so far, but you seem to misunderstand exactly where the try-catch catches errors.
Here is you code. I removed the comments to make it more concise.
public class West {
public static void main(String[] args) {
try {
throw new West1("Custom Exception.....");
} catch(West1 ce) {
System.out.println(ce.getMessage());
throw new FileNotFoundException(); // <-- Must be caught
} catch(FileNotFoundException fne) { // <-- Never thrown
fne.printStackTrace();
}
}
}
The first compiler error is because the catch block that is for catching FileNotFoundException's try block never throws FileNotFoundException. The second compiler error is because FileNotFoundException is a checked exception. Because it is a checked exception your code must either
handle it (by catching it with try-catch)
let everyone know it could throw it (public static void main(String[] args) throws FileNotFoundException { ...).
From the context of your code, you seem to be going with the first option, handling it with try-catch, but you have the catch in the wrong place.
catch blocks don't catch exceptions, try blocks do. catch blocks specify what to do with the actual caught exception.
public class West {
public static void main(String[] args) {
try {
throw new West1("Custom Exception.....");
} catch(West1 ce) {
System.out.println(ce.getMessage());
try {
throw new FileNotFoundException();
} catch(FileNotFoundException fne) {
fne.printStackTrace();
}
}
}
}
Try that instead. Notice how you can have a try instead of a catch. This wouldn't matter if FileNotFoundException wasn't a checked exception.
Related
Here's the code.
public class TestTest {
public static void main (String[] args) throws Exception {
try {
run();
} catch(Exception e) {
printSuppressedExceptions(e);
}
}
public static void printSuppressedExceptions(Throwable t) {
System.out.println(t);
System.out.println("suppressed exceptions: " + t.getSuppressed().length);
}
public static void run() throws Exception {
try(MyResource r = new MyResource("resource");) {
System.out.println("try");
System.getProperty("").length(); // throws illegalArgumentException
} catch(Exception e) {
printSuppressedExceptions(e);
throw e;
} finally {
new MyResource("finally").close();
}
}
}
class MyResource implements AutoCloseable {
private final String name;
public MyResource(String name) {
this.name = name;
}
#Override
public void close() throws Exception {
throw new Exception("exception" + " from " + this.name);
}
}
Since exception thrown from try block suppressed the exception from resource, I got "suppressed exceptions: 1" at first which was understandable. But when an exception was thrown from finally, it seemed like all suppressed exceptions disappeared because I got "java.lang.Exception: exception from finally" followed by "suppressed exceptions: 0" which I think it should be 1.
I browsed the Java tutorials and it definitely says
However, in this example, if the methods readLine and close both throw exceptions, then the method readFirstLineFromFileWithFinallyBlock throws the exception thrown from the finally block; the exception thrown from the try block is suppressed.
From The try-with-resources Statement
How could it happen?
Here is code that does what you would expect:
public class TestTest {
public static void main (String[] args) throws Exception {
try {
run();
} catch(Exception e) {
printSuppressedExceptions(e);
}
}
public static void printSuppressedExceptions(Throwable t) {
System.out.println(t);
System.out.println("suppressed exceptions (" + t.getSuppressed().length + "):");
for (Throwable suppressed : t.getSuppressed()) {
System.out.println(" - " + suppressed);
}
}
public static void run() throws Exception {
Exception exceptionFromCatch = null;
try(MyResource r = new MyResource("resource");) {
System.out.println("try");
System.getProperty("").length(); // throws illegalArgumentException
} catch(Exception e) {
exceptionFromCatch = e;
printSuppressedExceptions(e);
throw e;
} finally {
try {
new MyResource("finally").close();
} catch (Exception e) {
if (exceptionFromCatch!=null) {
e.addSuppressed(exceptionFromCatch);
}
throw e;
}
}
}
}
class MyResource implements AutoCloseable {
private final String name;
public MyResource(String name) {
this.name = name;
}
#Override
public void close() throws Exception {
throw new Exception("exception" + " from " + this.name);
}
}
So lets go trough the try-with-resource part of your code (as introduced in JDK 1.7.0) and see what happens (see What is the Java 7 try-with-resources bytecode equivalent using try-catch-finally? for more details):
the try-with-resource block MyResource r = new MyResource("resource") is executed
the try block is executed and throws an IllegalArgumentException
the try-with-resource block calls close() for all resources (in your example only one)
close() throws an exception, but since the exception from the try block has priority the exception from thrown by close() is suppressed and added via addSuppressed(..)
So that part works like you expected from reading the tutorial.
And now the try-catch-finally part of your code (as in JDK 1.6 and earlier):
the try block is executed and throws an IllegalArgumentException
(the catch block behaves the same way as if there was no catch block)
the finally block is executed and throws an Exception
the exception from the finally block has priority and the one from the try block is suppressed
But this time the word suppressed used in the java tutorial does not stand for "suppressed and added to the actually thrown exception" but "suppressed and lost to nirvana". So it still behaves as in JDK 1.6 and earlier and does not make use of the newly introduced addSuppressed(..) getSuppressed() functionality. That's the reason it doesn't behave like you expected.
I would argue the behaviour you expected wouldn't be logical either. I would like it to behave like this:
...
} finally {
try {
new MyResource("finally").close();
} catch (Exception e) {
if (exceptionFromCatch!=null) {
exceptionFromCatch.addSuppressed(e);
} else {
throw e;
}
}
}
...
That would always give priority to the exception from the try block (as implemented with the new try-with-resource feature) and add the exception from the catch block as suppressed to the list. But that would break compatibility with JDK 1.6, so I guess that's the reason why it doesn't behave like that.
This is the code sample and I am getting an error "must be caught or declare to
be thrown" but I have
already handled the IOException. So can you please tell why the error is populating. The code also
follows the handle and declare rule.
public void rethrow() throws SQLException, IOException {
try {
couldThrowAnException();
}
catch(Exception e) {
e = new IOException();
throw e; //Error: must be caught or declare to be thrown
}
}
The problem you are running into is that the compiler deals with the variable declaration type, not the type you assign to the variable.
The variable is of type Exception, which is not part of the throws clause.
If you change the catch() clause to match IOException, it will compile.
I'd suggest you read the Exceptions Trail of the Java Language Tutorial.
You handled IOException but you are throwing Exception(not IOException ) from catch block.
So you have to add Exception in throws clause
or
catch IOException instead of Exception in the catch block
public void rethrow() throws SQLException, IOException {
try {
couldThrowAnException();
}
catch(IOException e) {
e = new IOException();
throw e; //Error: must be caught or declare to be thrown
}
}
Although, it makes no sens to cathc it and throw it...
A far better way would be:
public void rethrow() {
try {
couldThrowAnException();
}
catch(IOException e) {
//do something when you encounter the io-error
}
catch(SQLException e) {
//do something when you encounter the sql-error
}
}
I am experimenting with exceptions and i want to ask when it is possible to handle multiple exceptions in one handler and when it is not?
For example i wrote the following code which combines two exceptions (FileNotFoundException OutOfMemoryError) and the program runs properly without any error. Al thought the handling is not so relevant with the functionality of the code i chose them just to see when i can combine multiple exceptions in on handler :
import java.io.FileNotFoundException;
import java.lang.OutOfMemoryError;
public class exceptionTest {
public static void main(String[] args) throws Exception {
int help = 5;
try {
foo(help);
} catch (FileNotFoundException | OutOfMemoryError e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static boolean foo(int var) throws Exception {
if (var > 6)
throw new Exception("You variable bigger than 6");
else
return true;
}
}
But when i choose different type of exceptions the compiler gives me error . For example when i choose IOException and Exception i have the error the exception is already handled " :
import java.io.IOException;
import java.lang.Exception;
public class exceptionTest {
public static void main(String[] args) throws Exception {
int help = 5;
try {
foo(help);
} catch (IOException | Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static boolean foo(int var) throws Exception {
if (var > 6)
throw new Exception("You variable bigger than 6");
else
return true;
}
}
So why is this happening ? Why in one occasion i can use multiple exception in handler and in the other not ? Thank you in advance.
You are getting the message because IOException is a subclass of Exception. Therefore, if an IOException were thrown, it would be caught by a catch (Exception e) statement, so catching it as an IOException is redundant.
The first example works because neither FileNotFoundException nor OutOfMemoryError is a subclass the other.
However, you can catch sub-classed exceptions using the separate catch statement:
try{
// code that might throw IOException or another Exception
} catch (IOException e) {
// code here will execute if an IOException is thrown
} catch (Exception e) {
// code here will execute with an Exception that is not an IOException
}
If you do this, please note that the subclass must come first.
The method processExceptions() should call the method BEAN.methodThrowExceptions and handle exceptions:
1.1. if an exception FileSystemException occurs, then log it by calling the method BEAN.log and throw forward
1.2. if an exception CharConversionException or any other IOException occurs, just log it by calling the method BEAN.log
Add the class/type of the exception you are forwarding in 2.1. to the processExceptions() method signature.
Handle the remaining exception in the method main() and log it. Use try..catch
I tried different solutions. It works but not as it should. What is the correct placement of throws in methods. Or maybe i shouldnt use them at all? And if I don't place them I can't make use of throw. Please help, I would really appreciate your time.
public class Solution {
public static StatelessBean BEAN = new StatelessBean();
public static void main(String[] args) {
try{
processExceptions();
}
catch (CharConversionException e){
BEAN.log(e);
}
}
public static void processExceptions()throws CharConversionException {
try{
BEAN.methodThrowExceptions();
}
catch (CharConversionException e){
BEAN.log(e);
throw e;
}
catch (FileSystemException e){
BEAN.log(e);
}
catch (IOException e){
BEAN.log(e);
}
}
public static class StatelessBean {
public void log(Exception exception) {
System.out.println(exception.getMessage() + ", " + exception.getClass().getSimpleName());
}
public void methodThrowExceptions() throws CharConversionException, FileSystemException, IOException {
int i = (int) (Math.random() * 3);
if (i == 0)
throw new CharConversionException();
if (i == 1)
throw new FileSystemException("");
if (i == 2)
throw new IOException();
}
}
}
If a method is capable of throwing an exception which IS NOT RuntimeException (either directly throwing or invoking a method which can throw an exception), it should either handle the exception or declare that it throws the exception, so that any other method which calls this method would know that it can encounter an exception and can either handle it or declare it that it throws (and so on).
Since you are dealing with checked exception, there is no clean way to avoid declaring throws, but there is a (messy) workaround. You can wrap the exception in a RuntimeException and can throw it and when you want to handle it, you can get the actual exception from the re.getCause();
public class Solution {
public static StatelessBean BEAN = new StatelessBean();
public static void main(String[] args) {
try{
processExceptions();
}
catch (RuntimeException re){
if (!(re.getCause() instanceof CharConversationException)) {
//handle the case in which the exception was not CCE and not FSE not IOException
}
}
}
public static void processExceptions() {
try{
BEAN.methodThrowExceptions();
} catch (CharConversionException cce){
BEAN.log(e);
throw new RuntimeException(cce);
} catch (FileSystemException fse){
BEAN.log(e);
} catch (IOException e){
BEAN.log(e);
}
}
public static class StatelessBean {
public void log(Exception exception) {
System.out.println(exception.getMessage() + ", " + exception.getClass().getSimpleName());
}
public void methodThrowExceptions() throws CharConversionException, FileSystemException, IOException {
int i = (int) (Math.random() * 3);
if (i == 0)
throw new CharConversionException();
if (i == 1)
throw new FileSystemException("");
if (i == 2)
throw new IOException();
}
}
}
I am not sure whether I understood your question correctly and this is what you wanted :)
I think that the order:
Handle the remaining exception in the method main()
means that you should catch not only CharConversionException, but all other Exceptions by:
catch (Exception e)
Besides, you should ask it on help.javarush.net I think :>
This question already has answers here:
Close resource quietly using try-with-resources
(4 answers)
Closed 1 year ago.
I was reading about the try-with-resource in JDK7 and while I was thinking of upgrading my application to run with JDK7 I faced this problem..
When using a BufferedReader for example the write throws IOException and the close throws IOException.. in the catch block I am concerned in the IOException thrown by the write.. but I wouldn't care much about the one thrown by the close..
Same problem with database connections.. and any other resource..
As an example I've created an auto closeable resource:
public class AutoCloseableExample implements AutoCloseable {
public AutoCloseableExample() throws IOException{
throw new IOException();
}
#Override
public void close() throws IOException {
throw new IOException("An Exception During Close");
}
}
Now when using it:
public class AutoCloseTest {
public static void main(String[] args) throws Exception {
try (AutoCloseableExample example = new AutoCloseableExample()) {
System.out.println(example);
throw new IOException("An Exception During Read");
} catch (Exception x) {
System.out.println(x.getMessage());
}
}
}
how can I distinguish between such exceptions without having to create wrappers for classes such as BufferedReader?
Most of cases I put the resource close in a try/catch inside the finally block without caring much about handling it.
Lets consider the class:
public class Resource implements AutoCloseable {
public Resource() throws Exception {
throw new Exception("Exception from constructor");
}
public void doSomething() throws Exception {
throw new Exception("Exception from method");
}
#Override
public void close() throws Exception {
throw new Exception("Exception from closeable");
}
}
and the try-with-resource block:
try(Resource r = new Resource()) {
r.doSomething();
} catch (Exception ex) {
ex.printStackTrace();
}
1. All 3 throw statements enabled.
Message "Exception from constructor" will printed and the exception thrown by constructor will be suppressed, that means you can't catch it.
2. The throw in constructor is removed.
Now the stack trace will print "Exception from method" and "Suppressed: Exception from closeable" below. Here you also can't catch the suppressed exception thrown by close method, but you will be nofitied about the suppressed exception.
3. Throws from constructor and method are removed.
As you have probably already guessed the "Exception from closeable" will be printed.
Important tip: In all of above situations you are actually catching all exceptions, no matter where they were throwed. So if you use try-with-resource block you don't need to wrap the block with another try-catch, the extra block is simply useless.
Hope it helps :)
I would suggest using a flag as in the following example:
static String getData() throws IOException {
boolean isTryCompleted = false;
String theData = null;
try (MyResource br = new MyResource();) {
theData = br.getData();
isTryCompleted = true;
} catch(IOException e) {
if (!isTryCompleted )
throw e;
// else it's a close exception and it can be ignored
}
return theData;
}
source:Close resource quietly using try-with-resources