try-with-resources initialize to null - java

I'm refactoring some old code that looks like this:
OutputStreamWriter osw1 = null;
OutputStreamWriter osw2 = null;
try {
// Some statements...
if (condition1)
osw1 = createAnOutputStreamWriter(params1...);
// Some more statements...
if (condition2)
osw2 = createAnOutputStreamWriter(params2...);
// Some more statements...
} finally {
try {
if (osw1 != null)
osw1.close();
if (osw2 != null)
osw2.close();
} catch (Exception e) {
// Ignore
}
}
I would like to clean up the code, but can't directly replace the outermost try use try-with-resources when the variables osw1 and osw2 change to refer to different objects inside the block. Can you offer any suggestions?

Related

Java InputStream with different Object Classes

my code has to read in two different Object Types (Bestellung, AKunde) through a ObjectOutputStream and save it in a csv file, which works.
But when i try to read them from the file it doesn't work.
Here is the code:
OutputStream:
LinkedList<Bestellung> bestellListe = verwaltungBestell.getBestellListe();
try {
fileOutputStream = new FileOutputStream(file);
outputStream = new ObjectOutputStream(fileOutputStream);
for (AKunde kunde : kundenliste) {
outputStream.writeObject(kunde);
}
for (Bestellung bestellung : bestellListe) {
outputStream.writeObject(bestellung);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileOutputStream != null) {
fileOutputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
InputStream:
ArrayList<AKunde> kundenImport = new ArrayList<AKunde>();
ArrayList<Bestellung> bestellungenImport = new ArrayList<Bestellung>();
boolean cont = true;
try {
ObjectInputStream objectStream = new ObjectInputStream(new FileInputStream(directorie));
while (cont) {
AKunde kunde = null;
try {
kunde = (AKunde) objectStream.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (kunde != null) {
kundenImport.add(kunde);
} else {
cont = false;
}
}
while (cont) {
Bestellung bestellung = null;
try {
bestellung = (Bestellung) objectStream.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (bestellung != null) {
bestellungenImport.add(bestellung);
} else {
cont = false;
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
}
But it won't read the "Bestellungen" and won't save them into "bestellungenImport".
Anyone has a solution???
Your code never reaches the Bestellung reader part.
You have a false assumption that kunde =(AKunde)objectStream.readObject(); returns null.
Instead, it throws exception.
Oneway you can do is cast it like #luk2302.
Another way is to add a object count when writing your object stream:
outputStream.writeInt(kundenliste.size());
for (AKunde kunde : kundenliste) {
outputStream.writeObject(kunde);
}
outputStream.writeInt(bestellListe.size());
for (Bestellung bestellung : bestellListe) {
outputStream.writeObject(bestellung);
}
Then replace your while(cont) loop with a for each loop:
int kundeCount = objectStream.readInt();
for (int i = 0; i < kundeCount; i++) {
// Read and import kunde
}
You need to change your logic for reading objects. There are two main issues:
you never reset cont so the second while loop will never do anything
even if you did that you would always skip the first Bestellung since it was already read when the second loop is reached
I would propose something along the lines of:
Object object = objectStream.readObject();
if (object instanceof AKunde) {
kundenImport.add((AKunde) object);
} else if (object instanceof Bestellung) {
bestellungenImport.add((Bestellung) object);
} else {
// something else was read
}
You simply need to loop over this code and add proper error handling where needed.
I would suggest, you change the way you write your objects to ObjectOutputStream in the first place:
Directly write the kundenListe and bestellListe objects, so you dont't have to worry about types or number of elements when reading the objects again. Your stream of object then always contains two objects, the two lists.
// use try-with-resources if you're on Java 7 or newer
try (ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file))) {
// write the complete list of objects
outputStream.writeObject(kundenliste);
outputStream.writeObject(bestellListe);
} catch (IOException e) {
e.printStackTrace(); //TODO proper exception handling
}
Then you could read it just like that:
ArrayList<AKunde> kundenImport = new ArrayList<>();
ArrayList<Bestellung> bestellungenImport = new ArrayList<>();
//again try-with-resources
try (ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(file))) {
kundenImport.addAll((List) inputStream.readObject());
bestellungenImport.addAll((List) inputStream.readObject());
} catch (IOException | ClassNotFoundException e) { //multi-catch, if Java 7 or newer
e.printStackTrace(); //TODO proper exception handling
}
Further reads:
The try-with-resources Statement
Catching Multiple Exception Types (...)

Jumping from a try block to a finally block

I'm trying to do the following :
String txt = "begin\n";
try{
// some stuff
if(some condition)
JUMP TO FINALLY CODE
// some other stuff
} finally {
String txt += "end\n";
return txt;
}
Is there a way to implement JUMP TO FINALLY CODE without raising an exception (raising an exception wouldn't look clean in my opinion)
yes one way is to just return from the method like this
String txt = "begin\n";
try{
// some stuff
if(some condition)
return;
// some other stuff
} finally {
String txt += "end\n";
}
No need of having any method to jump to finally since here always finally block execute. Whether or not there is an Exception.
You can just use a return if you don't want to execute the line of codes bellow something
try {
if(isThisShouldReturn()){
return; // when if satisfied will return from try
} else {
// do the stuff
}
}finally {
System.out.println("come to finally");
}
My approach would be to negate the condition:
String txt = "begin\n";
try{
// some stuff
if(!someCondition) {
// some other stuff
}
} finally {
String txt += "end\n";
}
This would have the intended behaviour for your example.
//Throw an exception from try block or..
//use return call:
try
{
if(true condition)
{
return;
}
else
{
//false condition do work....
}
}
finally
{
//always executed.
}
I guess return and by throwing exception are the only two ways you can reach out to a finally block from the try block.
You need to use a block label combined with a break; something like:
end_try: try {
...
break end_try;
...
} finally {
...
}
or:
try {
...
end_try: {
break end_try;
}
} finally {
...
}

modify method argument or return in java

I have seen this method in android source code.
protected LocaleConfiguration doInBackground(Void... unused) {
LocaleConfiguration localeConfiguration = new LocaleConfiguration();
readConfiguration(Launcher.this, localeConfiguration);
return localeConfiguration;
}
private static void readConfiguration(Context context, LocaleConfiguration configuration) {
DataInputStream in = null;
try {
in = new DataInputStream(context.openFileInput(PREFERENCES));
configuration.locale = in.readUTF();
configuration.mcc = in.readInt();
configuration.mnc = in.readInt();
} catch (FileNotFoundException e) {
// Ignore
} catch (IOException e) {
// Ignore
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// Ignore
}
}
}
}
why not something like this
private static LocaleConfiguration readConfiguration(Context context) {
LocaleConfiguration configuration = new LocaleConfiguration();
DataInputStream in = null;
try {
in = new DataInputStream(context.openFileInput(PREFERENCES));
configuration.locale = in.readUTF();
configuration.mcc = in.readInt();
configuration.mnc = in.readInt();
} catch (FileNotFoundException e) {
// Ignore
} catch (IOException e) {
// Ignore
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// Ignore
}
}
}
return configuration;
}
what is the advantage of modifying argument instead of returning new value
The advantage of modifying an argument instead of returning a new instance is that you put control of instantiation in the hands of the calling code - i.e. you allow it to re-use an existing instance.
The 'modifying argument' approach allows you to initialise an object using several such methods. e.g.
LocaleConfiguration localeConfiguration = new LocaleConfiguration();
readConfiguration(Launcher.this, localeConfiguration);
readSomeOtherConfiguration(Launcher.this, localeConfiguration);
return localeConfiguration;
Arguably you could do the same thing by returning the same instance as was passed in as a parameter, but I personally think that's asking for trouble.
Another possible reason might be if the cost of instantiation was high, you might want to recycle an old object. This doesn't appear to be the case with the code you present though, and it's an optimisation so only think about doing this if absolutely necessary!
Personally I would tend to take the 'return a new instance' approach unless there's a specific reason not to. I think it's simpler and decreases the likelihood of subtle errors in the calling code.

java try finally block to close stream

I want to close my stream in the finally block, but it throws an IOException so it seems like I have to nest another try block in my finally block in order to close the stream. Is that the right way to do it? It seems a bit clunky.
Here's the code:
public void read() {
try {
r = new BufferedReader(new InputStreamReader(address.openStream()));
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch (IOException readException) {
readException.printStackTrace();
} finally {
try {
if (r!=null) r.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
Also if you're using Java 7, you can use a try-with-resources statement:
try(BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()))) {
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch(IOException readException) {
readException.printStackTrace();
}
It seems a bit clunky.
It is. At least java7's try with resources fixes that.
Pre java7 you can make a closeStream function that swallows it:
public void closeStream(Closeable s){
try{
if(s!=null)s.close();
}catch(IOException e){
//Log or rethrow as unchecked (like RuntimException) ;)
}
}
Or put the try...finally inside the try catch:
try{
BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()));
try{
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
}finally{
r.close();
}
}catch(IOException e){
e.printStackTrace();
}
It's more verbose and an exception in the finally will hide one in the try but it's semantically closer to the try-with-resources introduced in Java 7.
In Java 7 you can do this...
try (BufferedReader r = new BufferedReader(...)){
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch(IOException e) {
//handle exception
}
Declaring a variable in the try block requires that it implements AutoCloseable.
Declaring a variable in the try block also limits its scope to the
try block.
Any variable declared in the try block will automatically have close() called when the try block exits.
It's called a Try with resources statement.
Yes it is clunky, ugly and confusing. One possible solution is to use Commons IO which offers a closeQuietly method.
There's a number of questions in the "Related" column on the right hand of this page that are actually duplicates, I advise to look through these for some other ways of dealing with this issue.
Like the answer mentioning the Commons IO library, the Google Guava Libraries has a similar helper method for things which are java.io.Closeable. The class is com.google.common.io.Closeables. The function you are looking for is similarly named as Commons IO: closeQuietly().
Or you could roll your own to close a bunch like this: Closeables.close(closeable1, closeable2, closeable3, ...) :
import java.io.Closeable;
import java.util.HashMap;
import java.util.Map;
public class Closeables {
public Map<Closeable, Exception> close(Closeable... closeables) {
HashMap<Closeable, Exception> exceptions = null;
for (Closeable closeable : closeables) {
try {
if(closeable != null) closeable.close();
} catch (Exception e) {
if (exceptions == null) {
exceptions = new HashMap<Closeable, Exception>();
}
exceptions.put(closeable, e);
}
}
return exceptions;
}
}
And that even returns a map of any exceptions that were thrown or null if none were.
Your approach within finally is correct. If the code that you call in a finally block can possibly throw an exception, make sure that you either handle it, or log it. Never let it bubble out of the finally block.
Within the catch block you are swallowing the exception - which is not correct.
Thanks...
public void enumerateBar() throws SQLException {
Statement statement = null;
ResultSet resultSet = null;
Connection connection = getConnection();
try {
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT * FROM Bar");
// Use resultSet
}
finally {
try {
if (resultSet != null)
resultSet.close();
}
finally {
try {
if (statement != null)
statement.close();
}
finally {
connection.close();
}
}
}
}
private Connection getConnection() {
return null;
}
source.
This sample was useful for me.
First thing I noticed in your code is curly bracket { } missing from your code if you look at it. also you need to initialize value of r to null so you need to pass null value to object at first so that if condition you have written can do not null condition check and lets you close the stream.

Can I avoid such cumbersome try...catch block

Usually, when dealing with Java IO code, here is what I wrote
FileOutputStream out = null;
try
{
out = new FileOutputStream("myfile.txt");
// More and more code goes here...
}
catch (Exception e)
{
}
finally
{
// I put the close code in finally block, to enture the opened
// file stream is always closed even there is exception happened.
if (out != null) {
// Another try catch block, troublesome.
try {
out.close();
} catch (IOException ex) {
}
}
}
As you can see, while I try to close the file stream, I need to deal with another try...catch block.
Look troublesome :(
Is there any way I can avoid? I don't feel comfortable in putting the close code in non-finally block, as exception caused by other codes will make no chance for "close" being called.
It is very important that you close streams in a finally. You can simplify this process with a utility method such as:
public static void closeStream(Closeable closeable) {
if(null != closeable) {
try {
closeable.close();
} catch(IOException ex) {
LOG.warning("Failed to properly close closeable.", ex);
}
}
}
I make it a point of at least logging a stream close failure. The usage then becomes:
FileOutputStream out = null;
try
{
out = new FileOutputStream("myfile.txt");
// More and more code goes here...
}
catch (Exception e)
{
}
finally
{
closeStream(out);
}
In Java 7 I believe that streams will be closed automatically and the need for such blocks should be mostly redundant.
Automatic Resource Management is coming in Java 7 which will automatically provide handling of this. Until then, objects such as OutputStream, InputStream and others implement the Closeable interface since Java 5. I suggest you provide a utility method to safe close these. These methods generally eat exceptions so make sure that you only use them when you want to ignore exceptions (e.g. in finally method). For example:
public class IOUtils {
public static void safeClose(Closeable c) {
try {
if (c != null)
c.close();
} catch (IOException e) {
}
}
}
Note that the close() method can be called multiple times, if it is already closed subsequent calls will have no effect, so also provide a call to close during the normal operation of the try block where an exception will not be ignored. From the Closeable.close documentation:
If the stream is already closed then invoking this method has no effect
So close the output stream in the regular flow of the code and the safeClose method will only perform close if something failed in the try block:
FileOutputStream out = null;
try {
out = new FileOutputStream("myfile.txt");
//...
out.close();
out = null;
} finally {
IOUtils.safeClose(out);
}
Discussion at
Try-catch-finally and then again a try catch
and
Is there a preference for nested try/catch blocks?
basically, the question is whether a close() exception is worth catching.
Project Lombok provides a #Cleanup annotation that removes the need for try catch blocks all together. Here's an example.
I tend to use utility functions for this:
public static void safeClose(OutputStream out) {
try {
out.close();
} catch (Exception e) {
// do nothing
}
}
which changes the code to the slightly more palatable:
FileOutputStream out = null;
try {
out = new FileOutputStream("myfile.txt");
// do stuff
} catch (Exception e) {
// do something
} finally {
safeClose(out);
}
You can't really do much better in Java at least until Java 7 when (hopefully) ARM ("Automatic Resource Management") blocks will help somewhat.
Write a method that looks something like below; call from your finally block...
static void wrappedClose(OutputStream os) {
if (os != null) {
try {
os.close();
}
catch (IOException ex) {
// perhaps log something here?
}
}
Separate your try/catch and try/finally blocks.
try
{
FileOutputStream out = new FileOutputStream("myfile.txt");
try
{
// More and more code goes here...
}
finally
{
out.close();
}
}
catch (Exception e)
{
//handle all exceptions
}
The outer catch will also catch anything thrown by the close.

Categories

Resources