How to write an Exception to a text file - java

import java.io.*;
class FileWrite
{
public static void main(String args[])
{
try{
// Create file
FileWriter fstream = new FileWriter("out.txt");
BufferedWriter out = new BufferedWriter(fstream);
out.write("Hello Java");
//Close the output stream
out.close();
}catch (Exception e){//Catch exception if any
// CAN I WRITE THE EXCEPTION TO THE TEXT FILE
}
}
}
I am writing text to a file. Can i write the exception thrown in the catch block to the out.txt file ?

You should not and probably could not write the exception to the file, whose writer may have caused the error.
But you can try using a logger, like log4j, as already suggested and in your catch block. You could simply add something as:
private static final Category log = Category.getInstance(MyClass.class.getName());
...
catch (Exception e) {
logger.log(e.getMessage());
}
Learn more about logging here or in this post.
Also check out the log4j docs.

Yes, you can write the exception to a text file. But if the exception happened in the line where you are creating the FileWriter or BufferedWriter, then you wont be able to use this object based on the state of these objects. Also you need to declare the instance of these objects outside the try block to enable visibility.

You cannot use the same out variable from the try block to write to out.txt, since the exception could have been thrown anywhere in the try block. This means that in the catch block out might not be initialized, or attempting to write using it will cause the same exception you are current catching.
You could attempt to open the file again in the catch block to write the exception, but since opening and writing to the same file has just failed it is unlikely that this will work.

Call the following method in catch block and pass the object. That will do your work:
public static void writeException(Exception e) {
try {
FileWriter fs = new FileWriter("out.txt", true);
BufferedWriter out = new BufferedWriter(fs);
PrintWriter pw = new PrintWriter(out, true);
e.printStackTrace(pw);
}
catch (Exception ie) {
throw new RuntimeException("Could not write Exception to file", ie);
}
}
As Ex.
try{
new NullPointerException();
}
catch(Exception e){
writeException(e);
}

//breaking code
} catch (Exception e) {
File f = new File("/tmp/someFileYouCanActuallyWriteOn.txt");
if (!f.exists())
f.createNewFile();
e.printStackTrace(new PrintStream(f));
}
But consider the comment from zachary-yates. Also, catching 'Exception' and not the specific type is discouraged - but if you really want to catch everything, catch Throwabble

Related

Gson stream closing

Does the stream close when you use something like:
gson.toJson(obj, new FileWriter("C:\\fileName.json"));
or is it better to to this:
try (Reader reader = new FileReader("c:\\test\\staff.json")) {
// Convert JSON File to Java Object
Staff staff = gson.fromJson(reader, Staff.class);
// print staff
System.out.println(staff);
} catch (IOException e) {
e.printStackTrace();
}
I know the try block closes the stream, but does ths first example also close the stream?
Code taken from
Mkyong
Does the stream close when you use something like:
gson.toJson(obj, new FileWriter("C:\\fileName.json"));
It does not. You should close it using try-with-resources, or a try-catch-finally block.
Since JDK 7, the preferred way to close an AutoClosable is to use try-with-resources (like in your second snippet):
try (FileWriter writer = new FileWriter("C:\\fileName.json")) {
gson.toJson(obj, writer);
} catch (IOException e) {
e.printStackTrace();
}
Or you could call close() using a try-catch-finally block:
FileWriter writer = null;
try {
writer = new FileWriter("C:\\fileName.json");
gson.toJson(obj, writer);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileWriter implements AutoClosable so it needs to be closed. Not naming the variable will not close it automatically.

Proper way to handle filenotfoundexception Java

I'm trying to find the proper method to handle a fileNotFoundException in the event it occurs in my code. I currently catch and rethrow the exception but am not sure if this is the most optimal way. I would like my function to stop running in the event the file cannot be found, which currently does not happen. What is the typical way of achieving this?
Any tips/insights would be great, thanks in advance.
BufferedReader br = null;
List<String> names = null;
try {
br = new BufferedReader(new FileReader("src/files/names.csv"));
} catch (FileNotFoundException e) {
try {
throw e;
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
}
try catch is usually used to avoid throwing the exception. In your case
void foo() throws FileNotFoundException {
BufferedReader br = null;
List<String> names = null;
br = new BufferedReader(new FileReader("src/files/names.csv"));
}
does the exact same thing as your example code.
If you want to avoid throwing the exception to the caller use try catch and to exit the application call System.exit(0)
try {
br = new BufferedReader(new FileReader("src/files/names.csv"));
} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(0);
}
There are several ways of handing such errors. Here are a few:
Throw a non-checked exception. It will have to be caught by someone else, and since it's unchecked, he might not know about it. Not always the best idea, but useful for some cases:
try {
br = new BufferedReader(new FileReader("src/files/names.csv"));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
Delcare your method with throws FileNotFoundException so callers will have to handle this case.
Simply return after catching the exception, or even use System.exit() if appropriate.
All three approaches will stop the execution of the current function.

Java Sockets passing between methods

I am just starting out with Java Socket Programming, and I have been reading literature on sockets here. The below code is a sample from a textbook I've taken which asks me to find the bug. Comparing with the literature though I am not seeing any bugs. The creation of the socket, bufferedreader, and printwriter seem correct, and they are surrounded in a try-catch block as well. The are properly "close()"ed in a try-catch block as well. Is there an error when passing these to process()? Any help would be appreciated.
import java.net.*;
import java.io.*;
class main{
public void process(PrintWriter out, BufferedReader in, Socket echoSocket){
//....
}
public void processData() {
Socket echoSocket;
PrintWriter out;
BufferedReader in;
try{
echoSocket = new Socket("server.company.com", 8081);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
}
catch (Exception e) {
System.err.println("Exception has occured");
return;
}
process(out, in, echoSocket);
try {
out.close();
in.close();
echoSocket.close();
}
catch(IOException e) {
System.err.println("IOException has occurred.");
}
}
}
Although, typos notwithstanding, one can only guess what the actual "bug" is, this code has an issue with error handling. Specifically, in the disposal of resources.
Discussion about resources
What are resources ?
Basically : any Java Object that relies on underlying OS level resources. Mostly : IO resources (input and output streams, channels), Sockets. But more importantly : if the "thing" you're using has a close, dispsose, shutdown or any of the like, it surely holds on to resources internally.
There are some exceptions (notably ByteArrayInputStream holds no resource but memory), but these are implementation details : if you stick to their interface (and you should, this is a "contract"), every stream should be closed.
Since Java 7, most of these objects in the Java API implement the AutoCloseable interface, but many 3rd parties have not necessarily ported this to their code (and maybe some can't for other reasons).
As one of the code reviewers at my company : I stop reading and I reject any code as soon as I do not see a secure call to the close method of a resource. By secure I mean inside a finally clause, that is guaranteed to be executed.
Rule of thumb about resources
Any resource obtained by your program should be freed in a finally clause (some even add : of its own).
What is the typical lifecycle of a resource
Well:
You obtain it
You use it
You release it
In your code, that is
ResourceObject myObject = null;
try {
myObject = getResource();
processResource(myObject);
} finally {
if(myObject != null) {
try {
myObject.close();
} catch (Exception e) {
// Usually there is nothing one can do but log
}
}
}
Since Java 7, if the resource object implements AutoCloseableyou have a new way of writing that, it's called the "try with resources".
try(ResourceObject myObject = getResource()) {
process(myObject);
}
You do not see the finally, but it's there, the compiler writes the finally clause for you in that case.
What about multiple resources ?
Well : multiple resources, multiple finallys. The idea is to separate the causes of failures in different finally clauses.
Say you want to copy a file...
public void myCopy() throws IOException {
InputStream source = null;
try {
source = new FileInputStream("yourInputFile");
// If anything bad happens, I have a finally clause that protects this now
OutputStream destination = null;
try {
destination = new FileOutputStream("yourOurputFile"); // If fails, my Input will be closed thanks to its own finally
performCopy(source, destination); // If this fail, my destination will also be closed thanks to its own finally
} finally {
if(destination!=null) { try { destination.close(); } catch (Exception e) {/* log*/ }}
}
} finally {
if(source!=null) { try { source.close(); } catch (Exception e) {/* log*/ }}
}
}
Or, with Java 7 syntax, we have the shorter (disclaimer : I have no Java7 right now, so can't really check if this compiles) :
try(
InputStream input = new FileInputStream("in");
OutputStream output = new FileOutputStream("out")) {
performCopy(input, output);
} catch(IOException e) {
// You still have to deal with it of course.
}
This is SO MUCH BOILERPLATE !
Yes it is. That's why we have libraries. One could argue you should not write such code. Use standard, well behaved libraries like commons IO, or use one of their utility methods. Or newer JDK methods like the Files API, and see how this works.
Commons IO has a handy IOUtils.closeQuietly() suite of methods for closing streams.
Try with resources Gotchas
There are ramifications in the "try with resources" call that go a bit deeper than that. These include: What if I want to do something with the exceptions that occur in the finally clause ? How do I differentiate that from an exception that would have occured during performCopy?
Another case is : what happens here :
try(Reader reader = new InputStreamReader(new FileInputStream("in"), "an encoding that is not supported")) {
// Whatever
}
It happens that an UnsupportedEncodingException is thrown but after the FileInputStream is instanciated. But as the FileInputStream is not the subject of the try clause, it will NOT be closed. An you have a File descriptor leak. Try that a thousand times, and your JVM will not be able to open files anymore, you OS will tell you "max number of open files exceeded" (ulimit generally does that in UNIX)
Back to your sockets
So what are your resources ?
Well, first, we can notice that you have only ONE true resource, your Socket instance, because the Socket javadoc says (javadoc):
* <p> Closing this socket will also close the socket's
* {#link java.io.InputStream InputStream} and
* {#link java.io.OutputStream OutputStream}.
So your Input and Output streams are tied to your Socket, and this is enough.
What's wrong with your code
Adding comments one your original code:
try{
echoSocket = new Socket("server.company.com", 8081);
out = new PrintWriter(echoSocket.getOutputStream(), true); // This can throw IOException
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream())); // Ditto
}
catch (Exception e) {
// If an exception was thrown getting any of the streams, we get there
System.err.println("Exception has occured");
// And you return without closing the socket. It's bad !
return;
}
// Let's assume everything worked, no exception.
process(out, in, echoSocket); // This may throw an exception (timeout, socket closed by peer, ...)
// that is uncaught (no catch clause). Your socket will be left unclosed as a result.
try {
out.close(); // This can fail
in.close(); // This too
echoSocket.close(); // And this too - although nothing you can do about it
}
catch(IOException e) {
// if out.close fails, we get here, and in.close and socket.close
// never got a chance to be called. You may be leaking resources
System.err.println("IOException has occurred.");
}
A safe implementation
Socket echoSocket = null;
try {
// open socket,
echoSocket = new Socket("server.company.com", 8081); // protected by finally
out = new PrintWriter(echoSocket.getOutputStream(), true); // protected
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream())); // protected
process(out, in, echoSocket); // Still protected
} catch (Exception e) {
// Your current error handling
} finally {
// Anyway, this close will be called if needs be.
if(echoSocket != null) {
try { echoSocket.close(); } catch (Exception e) { /* log */}
// See javadoc, this has closed the in & out streams too.
}
}
public void process(){PrintWriter out, BufferedReader in, Socket echoSocket){
should be
public void process(PrintWriter out, BufferedReader in, Socket echoSocket){
otherwise everything seems fine to me
Try this I think you missed one semicolon
public void processData() {
Socket echoSocket;
PrintWriter out;
BufferedReader in;
try{
echoSocket = new Socket("localhost", 8080);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
}
catch (IOException e) {
System.err.println("Exception has occured");
return;
}
process(out, in, echoSocket);
try {
out.close();
in.close();
echoSocket.close();
}
catch(IOException e) {
System.err.println("IOException has occurred.");
}
}
public void process (PrintWriter out, BufferedReader in, Socket echoSocket)
{
}

exception handling for closing reader and writer

I was just looking back over some code we wrote in a java class that I'm taking. I noticed that in the finally block there is a try/catch for closing the reader, but not the writer. I'll copy the code below. Can anyone explain why that would be? I'd like to understand better.
public class UsingFiles {
public static void main(String[] args) {
// open the input stream (from the file of this program)
BufferedReader reader = null;
PrintWriter writer = null;
try {
reader = new BufferedReader(new FileReader("./src/UsingFiles.java"));
writer = new PrintWriter("reverseFile.txt");
// String line;
// while ((line = reader.readLine()) != null) {
// System.out.println(line);
// }
// print the file in reverse order
// use recursion
reverseFile(reader, writer);
} catch (FileNotFoundException e) {
System.out.println("Couldn't open the file!");
} catch (IOException e) {
System.out.println("Problem reading the file");
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
System.out.println("Couldn't close the reader");
}
}
if (writer != null) {
writer.close();
}
}
}
private static void reverseFile(BufferedReader reader, PrintWriter writer)
throws IOException {
String line = reader.readLine();
if (line != null) {
reverseFile(reader, writer);
writer.println(line);
}
}
There are two possibilities that I can think of:
It's an oversight
Both calls to close() can throw an exception. If the first one throws an exception, the second one would be skipped - unless of course the first one was wrapped in its own try/catch block. The second one doesn't need a try/catch block since if it fails, there is no subsequent code that will be skipped
In the "real world", I would say that the answer is #1. The reason I would think #2 to be unlikely is that there is usually some other code that you will want to execute, even if you can't close some stream. This would be especially true had the catch blocks not caught an exception (or re-threw a different exception) since a fresh exception in the finally block would replace the original exception and you would never know that it had happened.
Update
As another answer has pointed out, PrintWriter.close() does not in fact throw an IOException, even though the parent interface Writer does declare that close() can throw an IOException. So that may be a better explanation.
I believe the intent was to attempt to close the writer even if the reader failed to close. If closing the reader throws an IOException, you will never execute the rest of the finally block.
This is because PrintWriter never throws exception during close(). See API. This
try {
writer.close();
} catch(IOException e) {
System.out.println("Couldn't close the writer");
}
will result in compiler error: Unreachable catch block for IOException. This exception is never thrown from the try statement body
It actually SHOULD be closed.
http://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html
Anytime you use a resource on the system, it's great practice to close a the objects that have access to it.
There is no need to close reader in try block of finally block if you are using try with resource
try(reader = new BufferedReader(new FileReader("./src/UsingFiles.java"))
{
}
catch(Exception e)
{
}

A problem with java Object Streams while writing to file

I am trying to write an Object of kind "HashMap" to a file & recover it when my program run again. But I faced with an EOFException when I try to read that object and the Object is not read from the file. I use the flush() & close() methods when I wrote the object for the FileOutputStream & ObjectOutputStream. Also I create OutputStream & InputStream together for my file.
here is my code:
DataOutputStream outToFile;
DataInputStream inFromFile;
ObjectOutputStream writeTableToFile;
ObjectInputStream readTableFromFile;
File tableFile;
public DNS(){
try {
tableFile = new File("table.txt");
outToFile = new DataOutputStream(new FileOutputStream(tableFile) );
writeTableToFile = new ObjectOutputStream(outToFile);
inFromFile = new DataInputStream(new FileInputStream(tableFile));
readTableFromFile = new ObjectInputStream(inFromFile);
HashMap table2 = (HashMap) readTableFromFile.readObject();
if (table2 == null)
table=new HashMap(100);
else
table = table2;
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(EOFException e){
table=new HashMap(100);
}
catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
and here is code for writing object:
table.put(NameField.getText(), IPField.getText());
try {
//writeTableToFile.reset();
writeTableToFile.writeObject(table);
writeTableToFile.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
Regards,
sajad
The file seems to be incomplete. When I look at your code, you're creating the file table.txt and try to read it immediately afterwards.
This ctor:
new FileOutputStream(tableFile)
will overwrite the file. If your read it afterwards, it will be empty (except the header information from the OOS)
EOFException means that the file is incomplete. So it's either not flush()ed or not close()ed or an exception is swallowed somewhere.

Categories

Resources