I have try and catch block in JAVA code
import java.io.FileOutputStream;
import java.util.zip.ZipOutputStream;
public class TryTest {
public static void main(String[] args) {
String zipPath ="D:/test";
try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipPath))){
String Hello ="Hello";
System.out.println("==============>"+Hello);
}catch (Exception e) {
e.printStackTrace();
}
}
}
And my compiled class look like
/*
* Decompiled with CFR 0.145.
*/
....
try {
try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(string));){
String string2 = "Hello";
System.out.println("==============>" + string2);
}
....
I wounder why another try block added in compile time.
Full Source code in
https://github.com/vikram06/java_try_catch_bug
This is explained in the JLS 14.20.3.2 Extended try-with-resources :
The meaning of an extended try-with-resources statement:
try ResourceSpecification
Block
Catchesopt
Finallyopt
is given by the following translation to a basic try-with-resources
statement (ยง14.20.3.1) nested inside a try-catch or try-finally or
try-catch-finally statement:
try {
try ResourceSpecification
Block
}
Catchesopt
Finallyopt
The effect of the translation is to put the ResourceSpecification
"inside" the try statement. This allows a catch clause of an extended
try-with-resources statement to catch an exception due to the
automatic initialization or closing of any resource.
Furthermore, all resources will have been closed (or attempted to be
closed) by the time the finally block is executed, in keeping with the
intent of the finally keyword.
When you're using try with resources (I mean try (...) {... ) then Java compiler generates additional code section to display the stacktrace from local variable of type Throwable. That's because Java compiler is decomposing try with resources statement into separate tries - one for closing the resource and another for statements inside your try.
How is it displayed after decompilation - it depends on the decompiler you use.
Author of CFR here - short answer - CFR's 'resugaring' isn't perfect ;) (though the decompiled code is entirely correct, and valid.)
If you find something like this, feel free to submit a bug/improvement.
For what it's worth - the ACTUAL bytecode bears much less of a resemblance to the input - try using cfr with the arguments
--tryresources false --decodefinally false
And you get the unsugared code, which is much closer to the actual bytecode.
public static void main(String[] args) {
String zipPath = "D:/test";
try {
ZipOutputStream zipOut;
block11 : {
zipOut = new ZipOutputStream(new FileOutputStream(zipPath));
Throwable throwable = null;
try {
String Hello2332 = "Hello";
System.out.println("==============>" + Hello2332);
if (zipOut == null) return;
if (throwable == null) break block11;
}
catch (Throwable Hello2332) {
try {
throwable = Hello2332;
throw Hello2332;
}
catch (Throwable throwable2) {
if (zipOut == null) throw throwable2;
if (throwable == null) {
zipOut.close();
throw throwable2;
}
try {
zipOut.close();
throw throwable2;
}
catch (Throwable throwable3) {
throwable.addSuppressed(throwable3);
throw throwable2;
}
}
}
try {
zipOut.close();
return;
}
catch (Throwable Hello2332) {
throwable.addSuppressed(Hello2332);
return;
}
}
zipOut.close();
return;
}
catch (Exception e) {
e.printStackTrace();
}
}
Related
Code Snippet :
InputStream inputStream = null;
try{
ExternalServiceObject object = externalService.getObject();
inputStream = object.getInputStream();
// further uses of inputStream
} catch(Exception e){
throw e;
} finally {
if(inputStream != null)
inputStream.close();
}
Here, externalService.getObject() can also throw an exception.
Wish to refactor this code using try-with-resources, hence avoiding the finally block.
Or is the current behavior the most appropriate behavior.
All the comments and answers are appreciated.
If you don't need the external service object for anything else:
try (InputStream inputStream = externalService.getObject().getInputStream()) {
// further uses of inputStream
} catch (Exception e) {
// ... logging etc
throw e;
}
I believe that execution order in the try-with-resources is top-down
(like all other java variable definitions)
try
(
ExternalServiceObject externalServiceObject = externalService.getObject(),
InputStream inputStream = externalServiceObject.getInputStream();
)
{
// further uses of inputStream
}
catch (Exception e)
{
// do stuff.
}
Caveat: ExternalServiceObject must implement AutoCloseable
So, use try-with-resources if that's what you want to use:
try {
ExternalServiceObject object = externalService.getObject();
try (InputStream inputStream = object.getInputStream()) {
// ...
}
} catch (Exception e) {
throw e; // But why catch it only to rethrow?
}
The closing of the InputStream can be done using a try-with-resources block. It is more readable and less clunky. InputStream implements AutoCloseable and thus upon exiting a try-with-resources block the class's close method will automatically be called. If you are only using the InputStream for the scope of the try-catch-finally block then you should move it to the try block.
Also, you should avoid (where possible) catching Exception. Any resulting exceptions that are thrown in your try block could result in unwanted behavior.
In the following code example I expect to have 1 as a return value of method testM(). But due to the exception in TestAutoCloseable.close() method I get unexpected behaviour.
My question is: "Is it a normal behaviour of JVM?"
public static void main(String[] args) {
ProgrammerTwo programmerTwo = new ProgrammerTwo();
System.out.println(programmerTwo.testM());
}
int testM() {
try (TestAutoCloseable closable = new TestAutoCloseable()) {
System.out.println("Do first return");
return 1;
} catch (IOException e) {
System.out.println("handled");
}
System.out.println("Do something, that shouldn't do if first return have happened");
return 2;
}
static class TestAutoCloseable implements AutoCloseable {
#Override
public void close() throws IOException {
throw new IOException();
}
}
Because if it is normal behaviour, we shouldn't use return or break statements in try with resources statement. It should be anti-pattern.
The details of how the try-with-resources statement works are in this section from the JLS. In your case, it is an extended try-with-resources since it has a catch clause as defined in the below quote (note the highlighted statement at the end).
A try-with-resources statement with at least one catch clause and/or a finally clause is called an extended try-with-resources statement.
The meaning of an extended try-with-resources statement:
try ResourceSpecification
Block
[Catches]
[Finally]
is given by the following translation to a basic try-with-resources statement nested inside a try-catch or try-finally or try-catch-finally statement:
try {
try ResourceSpecification <--- exception thrown in this basic try-with-resources
Block
}
[Catches]
[Finally]
The effect of the translation is to put the resource specification "inside" the try statement. This allows a catch clause of an extended try-with-resources statement to catch an exception due to the automatic initialization or closing of any resource.
This means that closing the resource occurs within the body of the outer try block, causing an exception to be thrown and handled in the catch block, and control resumes to the statements after the extended try-with-resources statement.
In effect, the whole method testM is equivalent to:
int testM() {
try {
final TestAutoCloseable closable = new TestAutoCloseable();
Throwable #primaryExc = null;
try {
System.out.println("Do first return");
return 1;
} catch (Throwable #t) {
#primaryExc = #t;
throw #t;
} finally {
if (closable != null) {
if (#primaryExc != null) {
try {
closable.close();
} catch (Throwable #suppressedExc) {
#primaryExc.addSuppressed(#suppressedExc);
}
} else {
closable.close();
}
}
}
} catch (IOException e) {
System.out.println("handled");
}
System.out.println("Do something, that shouldn't do if first return have happened");
return 2;
}
In simple words,When your try-with-resource block is exiting,an IOException is thrown (since you are throwing it from close(),so value 1 has never been returned from the method,instead JVM moves to catch block because as per the rule,as soon as any exception happens then all the remaing code in try block does not get executed instead JVM moves to catch block.so now your catch block runs and then your remaining codes get executed
I'm a beginner still, and currently learning about handling exceptions. The exercise in my book I'm trying to figure out tells me to add a Finally block to close out the file I opened, and I don't understand what I'm doing wrong. Keep in mind the file name and path are fake but here is what I have:
public static String readLineWithFinally()
{
System.out.println("Starting readLineWithFinally method.");
RandomAccessFile in = new RandomAccessFile("products.ran", "r");
try
{
String s = in.readLine();
return s;
}
catch (IOException e)
{
System.out.println(e.toString());
return null;
}
finally
{
try
{
in.close();
}
catch (Exception e)
{
System.out.println("Generic Error Message");
}
}
}
To add on to Taylor Hx's answer, you can take advantage of Java 7's try-with-resources construct to avoid having to use finally altogether in your case.
public static String readLineWithFinally() {
System.out.println("Starting readLineWithFinally method.");
try (RandomAccessFile in = new RandomAccessFile("products.ran", "r")) {
return in.readLine();
} catch (IOException e) {
System.out.println(e.toString());
return null;
}
}
You'll also want to be certain that your usage is consistent with what the API mandates for RandomAccessFile.
The code that you posted shouldn't compile, as RandomFile(String, String) can possibly throw FileNotFoundException. As such, we must include it in the try block.
System.out.println("Starting readLineWithFinally method.");
RandomAccessFile in = null;
try {
in = new RandomAccessFile("products.ran", "r");
String s = in.readLine();
return s;
} catch (IOException e) {
System.out.println(e.toString());
return null;
} finally {
try {
if(in != null) {
in.close();
}
} catch (Exception e) {
System.out.println("Generic Error Message");
}
}
Keep in mind the file name and path are fake but here is what I have:
That is why you will have a FileNotFoundException while creating RandomAccessFile("products.ran", "r") with read access mode "r".
From the documentation: RandomAccessFile(String name, String mode)
This constructor throws a FileNotFoundException if the mode is
"r" but the given string does not denote an existing regular file,
or if the mode begins with "rw" but the given string does not denote
an existing, writable regular file and a new regular file of that name
cannot be created, or if some other error occurs while opening or
creating the file
Due to my company's policy of using Eclipse and using Eclipse's code-autofix, the following code pattern appears excessively in the codebase:
InputStream is = null;
try {
is = url.openConnection().getInputStream();
// .....
} catch (IOException e) {
// handle error
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// handle error
}
}
}
IMO it's extremely fugly and hard to read, especially the portion within the finally block (is there really a need to catch 2 instances of IOException?). Is there anyway to streamline the code such that it looks cleaner?
Why do anything? It's working code. It's correct.
Leave it be.
First, about using IOUtils - may worth a shot telling your supervisors that the very application-server / Java runtime environment they might use, uses IOUtils and similar libraries itself. so in essence you're not introducing new components to your architecture.
Second, no, not really. There isn't really any way around it other than writing your own utility that will immitate IOUtils' closeQuietly method.
public class Util {
public static void closeStream(inputStream is) {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// log something
}
}
}
Now your code is
InputStream is = null;
try {
is = url.openConnection().getInputStream();
// .....
} catch (IOException e) {
// handle error
} finally {
Util.closeStream(is);
}
Not a lot else to do as the IOException in the catch might have some specific processing.
See this question, use the closeQuietly() solution.
InputStream is = null;
try {
is = url.openConnection().getInputStream();
// .....
} catch (IOException e) {
// handle error
} finally {
IoUtils.closeQuietly(is);
}
// stolen from the cited question above
public class IoUtils {
public static closeQuietly (Closeable closeable) {
try {
closeable.close();
} catch (IOException logAndContinue) {
...
}
}
}
Or wait for JDK7's ARM blocks.
You could define something like this somewhere:
private static interface InputStreamCallback {
public void doIt(InputStream is) throws IOException;
}
private void with(InputStreamCallback cb) {
InputStream is = null;
// Creational code. Possibly adding an argument
try {
cb.doIt(is);
} catch (IOException e) {
// handle error or rethrow.
// If rethrow add throws to method spec.
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// handle error or rethrow.
}
}
}
}
And invoke your code like this:
with(new InputStreamCallback() {
#Override
public void doIt(InputStream is) throws IOException {
is = url.openConnection().getInputStream();
// .....
}
});
If you declare with method static in a helper class, then you could even do an import static of it.
There's a drawback. You need to declare url final.
EDIT: creational code is not the point. You can arrange it in several ways. The callback is the point. You could isolate what you need to do there.
Is there an elegant way to handle exceptions that are thrown in finally block?
For example:
try {
// Use the resource.
}
catch( Exception ex ) {
// Problem with the resource.
}
finally {
try{
resource.close();
}
catch( Exception ex ) {
// Could not close the resource?
}
}
How do you avoid the try/catch in the finally block?
I usually do it like this:
try {
// Use the resource.
} catch( Exception ex ) {
// Problem with the resource.
} finally {
// Put away the resource.
closeQuietly( resource );
}
Elsewhere:
protected void closeQuietly( Resource resource ) {
try {
if (resource != null) {
resource.close();
}
} catch( Exception ex ) {
log( "Exception during Resource.close()", ex );
}
}
I typically use one of the closeQuietly methods in org.apache.commons.io.IOUtils:
public static void closeQuietly(OutputStream output) {
try {
if (output != null) {
output.close();
}
} catch (IOException ioe) {
// ignore
}
}
If you're using Java 7, and resource implements AutoClosable, you can do this (using InputStream as an example):
try (InputStream resource = getInputStream()) {
// Use the resource.
}
catch( Exception ex ) {
// Problem with the resource.
}
Arguably a bit over the top, but maybe useful if you're letting exceptions bubble up and you can't log anything from within your method (e.g. because it's a library and you'd rather let the calling code handle exceptions and logging):
Resource resource = null;
boolean isSuccess = false;
try {
resource = Resource.create();
resource.use();
// Following line will only run if nothing above threw an exception.
isSuccess = true;
} finally {
if (resource != null) {
if (isSuccess) {
// let close throw the exception so it isn't swallowed.
resource.close();
} else {
try {
resource.close();
} catch (ResourceException ignore) {
// Just swallow this one because you don't want it
// to replace the one that came first (thrown above).
}
}
}
}
UPDATE: I looked into this a bit more and found a great blog post from someone who has clearly thought about this more than me: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html He goes one step further and combines the two exceptions into one, which I could see being useful in some cases.
As of Java 7 you no longer need to explicitly close resources in a finally block instead you can use try-with-resources syntax. The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
Assume the following code:
try( Connection con = null;
Statement stmt = con.createStatement();
Result rs= stmt.executeQuery(QUERY);)
{
count = rs.getInt(1);
}
If any exception happens the close method will be called on each of these three resources in opposite order in which they were created. It means the close method would be called first for ResultSetm then the Statement and at the end for the Connection object.
It's also important to know that any exceptions that occur when the close methods is automatically called are suppressed. These suppressed exceptions can be retrieved by getsuppressed() method defined in the Throwable class.
Source: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Ignoring exceptions which occur in a 'finally' block is generally a bad idea unless one knows what those exceptions will be and what conditions they will represent. In the normal try/finally usage pattern, the try block places things into a state the outside code won't be expecting, and the finally block restores those things' state to what the outside code expects. Outside code which catches an exception will generally expect that, despite the exception, everything has been restored to a normal state. For example, suppose some code starts a transaction and then tries to add two records; the "finally" block performs a "rollback if not committed" operation. A caller might be prepared for an exception to occur during the execution of the second "add" operation, and may expect that if it catches such an exception, the database will be in the state it was before either operation was attempted. If, however, a second exception occurs during the rollback, bad things could happen if the caller makes any assumptions about the database state. The rollback failure represents a major crisis--one which should not be caught by code expecting a mere "Failed to add record" exception.
My personal inclination would be to have a finally method catch exceptions that occur and wrap them in a "CleanupFailedException", recognizing that such failure represents a major problem and such an exception should not be caught lightly.
One solution, if the two Exceptions are two different classes
try {
...
}
catch(package1.Exception err)
{
...
}
catch(package2.Exception err)
{
...
}
finally
{
}
But sometimes you cannot avoid this second try-catch. e.g. for closing a stream
InputStream in=null;
try
{
in= new FileInputStream("File.txt");
(..)// do something that might throw an exception during the analysis of the file, e.g. a SQL error
}
catch(SQLException err)
{
//handle exception
}
finally
{
//at the end, we close the file
if(in!=null) try { in.close();} catch(IOException err) { /* ignore */ }
}
Why do you want to avoid the additional block? Since the finally block contains "normal" operations which may throw an exception AND you want the finally block to run completely you HAVE to catch exceptions.
If you don't expect the finally block to throw an exception and you don't know how to handle the exception anyway (you would just dump stack trace) let the exception bubble up the call stack (remove the try-catch from the finally block).
If you want to reduce typing you could implement a "global" outer try-catch block, which will catch all exceptions thrown in finally blocks:
try {
try {
...
} catch (Exception ex) {
...
} finally {
...
}
try {
...
} catch (Exception ex) {
...
} finally {
...
}
try {
...
} catch (Exception ex) {
...
} finally {
...
}
} catch (Exception ex) {
...
}
After lots of consideration, I find the following code best:
MyResource resource = null;
try {
resource = new MyResource();
resource.doSomethingFancy();
resource.close();
resource = null;
} finally {
closeQuietly(resource)
}
void closeQuietly(MyResource a) {
if (a!=null)
try {
a.close();
} catch (Exception e) {
//ignore
}
}
That code guarantees following:
The resource is freed when the code finished
Exceptions thrown when closing the resource are not consumed without processing them.
The code does not try to close the resource twice, no unnecessary exception will be created.
If you can you should test to avoid the error condition to begin with.
try{...}
catch(NullArgumentException nae){...}
finally
{
//or if resource had some useful function that tells you its open use that
if (resource != null)
{
resource.Close();
resource = null;//just to be explicit about it was closed
}
}
Also you should probably only be catching exceptions that you can recover from, if you can't recover then let it propagate to the top level of your program. If you can't test for an error condition that you will have to surround your code with a try catch block like you already have done (although I would recommend still catching specific, expected errors).
You could refactor this into another method ...
public void RealDoSuff()
{
try
{ DoStuff(); }
catch
{ // resource.close failed or something really weird is going on
// like an OutOfMemoryException
}
}
private void DoStuff()
{
try
{}
catch
{
}
finally
{
if (resource != null)
{
resource.close();
}
}
}
I usually do this:
MyResource r = null;
try {
// use resource
} finally {
if( r != null ) try {
r.close();
} catch( ThatSpecificExceptionOnClose teoc ){}
}
Rationale: If I'm done with the resource and the only problem I have is closing it, there is not much I can do about it. It doesn't make sense either to kill the whole thread if I'm done with the resource anyway.
This is one of the cases when at least for me, it is safe to ignore that checked exception.
To this day I haven't had any problem using this idiom.
try {
final Resource resource = acquire();
try {
use(resource);
} finally {
resource.release();
}
} catch (ResourceException exx) {
... sensible code ...
}
Job done. No null tests. Single catch, include acquire and release exceptions. Of course you can use the Execute Around idiom and only have to write it once for each resource type.
Changing Resource from best answer to Closeable
Streams implements Closeable Thus you can reuse the method for all streams
protected void closeQuietly(Closeable resource) {
if (resource == null)
return;
try {
resource.close();
} catch (IOException e) {
//log the exception
}
}
I encountered a situation similar where I couldn't use try with resources but I also wanted to handle the exception coming from the close, not just log and ignore it like closeQuietly mechanism do. in my case I'm not actually dealing with an output stream, so the failure on close is of more interest than a simple stream.
IOException ioException = null;
try {
outputStream.write("Something");
outputStream.flush();
} catch (IOException e) {
throw new ExportException("Unable to write to response stream", e);
}
finally {
try {
outputStream.close();
} catch (IOException e) {
ioException = e;
}
}
if (ioException != null) {
throw new ExportException("Unable to close outputstream", ioException);
}