java Stream closed exception occurs during File Writer write method - java

The code which I currently have as below used to write the response and recently i am getting java.io.IOException: Stream closed error frequently even though I closed the File Writer properly not sure why any body please help me on this.
Exception:
Caused by: java.io.IOException: Stream closed
at sun.nio.cs.StreamEncoder.ensureOpen(StreamEncoder.java:26)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:99)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
at com.test.resp.RespWriter.write(RespWriter.java:150)
at com.ctc.wstx.sw.BufferingXmlWriter.flushBuffer(BufferingXmlWriter.java:1103)
at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:213)
at com.ctc.wstx.sw.BufferingXmlWriter.close(BufferingXmlWriter.java:194)
at com.ctc.wstx.sw.BaseStreamWriter.finishDocument(BaseStreamWriter.java:1690)
The place I am getting the exception at below place
fileWriter.write(buff, off, len); Here is the place I am getting Exception
public void write(char[] buff, int off, int len) throws IOException {
printWriter.write(buff, off, len);
if(count < FILE_SIZE) {
fileWriter.write(buff, off, len); Here is the place I am getting Exception
count+=len;
}
}
Code:
public RespWriter(RequestHeader header, PrintWriter printWriter)
throws InitializationException {
isClosed = false;
if(StringUtil.isEmpty(FILE_PATH) || printWriter == null) {
throw new InitializationException(
InitializationException.ERR_CODE);
} else {
this.header = header;
File responseFolder = new File(FILE_PATH.concat(
"/".concat(header.getUserId())));
boolean dirCreated = responseFolder.mkdir();
if(responseFolder.exists() && responseFolder.isDirectory()) {
responseFile = new File(responseFolder,
"R"+header.getId()+FILE_EXTENSION);
} else {
throw new InitializationException(
InitializationException.ERR_CODE,
"response folder does not exist");
}
this.printWriter = printWriter;
try {
fileWriter = new FileWriter(responseFile);
} catch (IOException e) {
log.error("FileWriter could not be created", e);
}
writeHeaderToFile();
}
}
private void writeHeaderToFile() {
String headerStr = "\nRequest Header:\nnull\n";
try {
if(header!=null) {
headerStr="\n"+Thread.currentThread().getName()
+" Request Header:\n" + header.toString() + "\n";
}
fileWriter.write(headerStr, 0, headerStr.length());
fileWriter.write("Date:");
fileWriter.write(new Date().toString()+"\n");
fileWriter.write("Response:\n"+Thread.currentThread().getName()+": ");
fileWriter.flush();
} catch (IOException e) {
log.error("IOException occurred writing header to file", e);
}
}
#Override
public void close() throws IOException {
if(!isClosed) {
try {
if(fileWriter!=null) {
try {
fileWriter.close();
} catch(IOException e) {
log.error("IOException", e);
}
}
if(printWriter!=null) {
try {
printWriter.close();
} catch(IOException e) {
log.error("IOException", e);
}
}
} finally {
isClosed = true;
}
}
}
public void flush() throws IOException {
if(printWriter!=null) {
try {
printWriter.flush();
} catch(IOException e) {
log.error("IOException", e);
}
}
if(fileWriter!=null) {
try {
fileWriter.flush();
} catch(IOException e) {
log.error("IOException", e);
}
}
}
Any thing i missed in the code or do I want to create new FileWriter instance in the Write method. Please help on this. Thanks in Advance

The stream is already closed when enters the write() method. I would suggest you println 3 different debug statements to spot the issue. 1 when you open/create the streamer, 2 when close it and 3 when you attempt to write to it, so you can see the order of operations. Also, have a look here: java IO Exception: Stream Closed

Related

How to kill negated conditional survived mutant

I have this code which I want to test and get the max pit coverage but I am not able to kill the mutant for the negated condition if (close). I am also using mockito to throw some exception.
public static void copyBytes(InputStream in, OutputStream out, int buffSize, boolean close) throws IOException {
try {
copyBytes(in, out, buffSize);
if (close) {
out.close();
out = null;
in.close();
in = null;
}
} finally {
if (close) {
closeStream(out);
closeStream(in);
}
}
}
This is my case tests:
#Test
public void mockOutputCopyBytes1False(){
try{
OutputStream outputStream = Mockito.mock(OutputStream.class);
doThrow(new IOException()).when(outputStream).close();
copyBytes(createInputStream(), outputStream, 50, false);
outputStream.write(10);
}catch (Exception e){
e.printStackTrace();
Assert.assertEquals(IOException.class, e.getClass());
}
}
#Test
public void mockOutputCopyBytes1True(){
try{
OutputStream outputStream = Mockito.mock(OutputStream.class);
doThrow(new IOException()).when(outputStream).close();
copyBytes(createInputStream(), outputStream, 50, true);
outputStream.write(10);
}catch (Exception e){
e.printStackTrace();
Assert.assertEquals(IOException.class, e.getClass());
}
}
The finally clause is executed whether the code works or throws an exception, there is no need to code for both cases:
public static void copyBytes(InputStream in, OutputStream out, int buffSize, boolean close) throws IOException {
try {
copyBytes(in, out, buffSize);
// TODO - remove the following
//if (close) {
// out.close();
// out = null;
// in.close();
// in = null;
//}
} finally {
if (close) {
closeStream(out);
closeStream(in);
}
}
}

ObjectInputStream is not able to recognize my Object Data format

I am getting EOFException from the following code:
if (!(in.read() == -1))
{
CANDataInfo canData = (CANDataInfo) in.readObject();
System.out.println(canData.toString());
bw.write(canData.toString());
}
else
{
System.out.println("in.read() == -1 "+in.readObject());
jLab0x28.setText("No more bytes to read ");
}
I am doing an Socket programming where server is sending continuos data to client at some interval. The Data whichis passed from server to client in via socket is of type CANDataInfo object which i have developed. At client side while i am printing the data i am getting exception. Since object's read is always -1 i am not able to log the data on some file.
Server Side Code:
private ServerSocket server = null;
private Socket client = null;
private ObjectOutputStream out;
public static final String TAG = "APP1";
private void structureData(CANDataInfo canDataInfo)
{
try
{
if(server == null)
{
server = new ServerSocket(38301);
server.setSoTimeout(0);
}
client = server.accept();
Log.e("Server ", ""+client.isConnected());
Log.e("Data ", ""+canDataInfo.toString());
if(!client.isConnected())
{
Log.e("Server ", "client.isConnected() "+client.isConnected());
server.close();
}
out = new ObjectOutputStream(client.getOutputStream());
out.writeObject(canDataInfo);
out.close();
}
catch (Exception ex)
{
Log.e(CANManagerSetUp.TAG, "" + ex);
}
}
Client Side Code {Not a clean solution, Refer Answer from EJP}
package com.cnh.socket.client;
import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import javax.swing.JLabel;
import cantest.setup.CANDataInfo;
public class ThreadListener
{
Socket client = null;
ObjectInputStream in = null;
ListenFor0X28 runnableListenFor0X28 = null;
boolean continueMe;
public class ListenFor0X28 implements Runnable
{
JLabel jLab0x28;
public ListenFor0X28(){}
public ListenFor0X28(boolean stop, JLabel jLab0x28)
{
continueMe = stop;
this.jLab0x28 = jLab0x28;
}
public void run()
{
while(continueMe)
{
try
{
client = new Socket("localhost", 38301);
in = new ObjectInputStream(client.getInputStream());
if(client.isConnected())
{
jLab0x28.setText("Connected to Server");
appendFile(continueMe, jLab0x28, client);
}
else
{
System.out.println("Client is trying to connect");
jLab0x28.setText("Client is trying to connect");
}
}
catch(Exception ex)
{
ex.printStackTrace();
System.err.println("Before Append "+ex.toString());
}
}
}
}
BufferedWriter file = getFile("C:\\ISSUE124_Resolved.txt");
private void appendFile(boolean continueMe, JLabel jLab0x28, Socket client)
{
try
{
if(!client.isClosed())
{
try
{
CANDataInfo canData = (CANDataInfo) in.readObject();
System.out.println(canData.toString());
file.write(canData.toString());
file.flush();
}
catch (EOFException exp)
{
continueMe = true;
System.out.println("A Stream has finished "+exp.toString()+"\n");
}
catch (ClassNotFoundException exp)
{
exp.printStackTrace();
System.err.println(exp.toString());
continueMe = false;
}
}
if(!continueMe)
{
file.close();
client.close();
in.close();
jLab0x28.setText("Socket is closed "+client.isClosed());
}
}
catch(IOException exp)
{
exp.printStackTrace();
System.err.println("Exception "+exp.toString());
jLab0x28.setText(exp.getMessage());
continueMe = false;
}
}
public BufferedWriter getFile(String path)
{
try
{
File file = new File(path);
if (!file.exists())
{
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
return new BufferedWriter(fw);
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
}
Exception Stack: {Before Resolving}
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at com.cnh.socket.client.ThreadListener.appendFile(ThreadListener.java:73)
at com.cnh.socket.client.ThreadListener.access$0(ThreadListener.java:65)
at com.cnh.socket.client.ThreadListener$ListenFor0X28.run(ThreadListener.java:48)
at java.lang.Thread.run(Unknown Source)
Data received in unknown format java.io.EOFException
In the client
if (!(in.read() == -1))
{
CANDataInfo canData = (CANDataInfo) in.readObject();
System.out.println(canData.toString());
bw.write(canData.toString());
}
The first line reads one byte from the input stream. This is actually the first byte of the object that was written by the server. Thus the stream is no longer aligned correctly so the following readObject() fails.
You should remove the pointless and erroneous read() call, which is getting your object streams out of sync.
While you're at it, you can also remove all the redundant calls to isConnected(). They aren't doing anything. You seem to have a mania for calling extra methods which mostly don't do anything, or which try to predict the future. Try to taper off.
EDIT As requested I am critiquing not only your client but your server code.
Server:
private void structureData(CANDataInfo canDataInfo)
{
try
{
if(server == null)
The ServerSocket should have been created and configured in the constructor.
{
server = new ServerSocket(38301);
server.setSoTimeout(0);
Zero is the default. Don't assert defaults. Remove.
}
client = server.accept();
Log.e("Server ", ""+client.isConnected());
Logging isConnected() is redundant. Remove. This will always print true. The socket is connected. You just accepted it. If you want to log something useful, log the client socket's remote address.
Log.e("Data ", ""+canDataInfo.toString());
How can there be any data when you haven't read any yet? If this is invariant server-side data, why log it on every accept?
if(!client.isConnected())
{
Log.e("Server ", "client.isConnected() "+client.isConnected());
server.close();
}
This test can never pass, and the code block can never be entered, and if by some miracle it was entered, closing the server socket is a ridiculous response. Remove all this.
out = new ObjectOutputStream(client.getOutputStream());
out.writeObject(canDataInfo);
out.close();
}
catch (Exception ex)
Don't catch Exception. Catch IOException.
{
Log.e(CANManagerSetUp.TAG, "" + ex);
You should log the exception class, its message, and the stack trace. ""+ex does not accomplish that.
}
}
Client:
public class ThreadListener
{
Socket client = null;
ObjectInputStream in = null;
ListenFor0X28 runnableListenFor0X28 = null;
boolean continueMe;
public class ListenFor0X28 implements Runnable
{
JLabel jLab0x28;
public ListenFor0X28(){}
public ListenFor0X28(boolean stop, JLabel jLab0x28)
{
continueMe = stop;
this.jLab0x28 = jLab0x28;
}
public void run()
{
while(continueMe)
{
try
{
client = new Socket("localhost", 38301);
in = new ObjectInputStream(client.getInputStream());
if(client.isConnected())
The client is connected. You just connected it, when you constructed the Socket. And if by some miracle it wasn't connected, calling getInputStream() would already have failed with a SocketException. Remove this test. In general there is far too much testing of things that can't be true or can't be false in your code.
{
jLab0x28.setText("Connected to Server");
appendFile(continueMe, jLab0x28, client);
}
else
{
System.out.println("Client is trying to connect");
jLab0x28.setText("Client is trying to connect");
}
}
The else block is unreachable, and the log message 'Client is trying to connect' is incorrect. Remove the entire block and the else.
catch(Exception ex)
See above. Don't catch Exception. Catch the exceptions the compiler tells you to catch: in this case IOException and the DNS-related ones.
{
ex.printStackTrace();
System.err.println("Before Append "+ex.toString());
See above about how to log exceptions.
}
}
}
}
BufferedWriter file = getFile("C:\\ISSUE124_Resolved.txt");
private void appendFile(boolean continueMe, JLabel jLab0x28, Socket client)
{
try
{
if(!client.isClosed())
{
try
{
CANDataInfo canData = (CANDataInfo) in.readObject();
System.out.println(canData.toString());
file.write(canData.toString());
file.flush();
}
catch (EOFException exp)
{
continueMe = true;
System.out.println("A Stream has finished "+exp.toString()+"\n");
}
catch (ClassNotFoundException exp)
{
exp.printStackTrace();
System.err.println(exp.toString());
continueMe = false;
}
}
if(!continueMe)
{
file.close();
client.close();
in.close();
You don't need to close both the input stream and the socket. Either will do. General practice is to close the outermost writer/output stream if there is one, otherwise the input stream.
jLab0x28.setText("Socket is closed "+client.isClosed());
}
}
catch(IOException exp)
{
exp.printStackTrace();
System.err.println("Exception "+exp.toString());
jLab0x28.setText(exp.getMessage());
continueMe = false;
}
}
public BufferedWriter getFile(String path)
{
try
{
File file = new File(path);
if (!file.exists())
{
file.createNewFile();
}
Here you are (1) testing for file existence and (2) creating a new file.
FileWriter fw = new FileWriter(file.getAbsoluteFile());
Here the operating system will create a new file regardless of what you did above. The exists()/createNewFile() part is therefore a complete waste of time: two system calls that accomplish precisely nothing. Remove them.
return new BufferedWriter(fw);
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
Poor practice. You should let this method throw IOException and not catch it internally, or return null. At present, if this method fails, you will get an instrutable NullPointerException when you go to use its return value.
}
}

Using FileInputStream compile error says variable is uninitialized

Can somebody tell me what am I doing wrong in the below java code ? It doesn't compile and gives me compilation error.
import java.io.*;
public class ShowFile {
public static void main(String[] args) {
int i;
FileInputStream Fin;
try {
Fin = new FileInputStream("C:\\Users\\cbr\\Desktop\\test.txt");
} catch (FileNotFoundException exp) {
System.out.println("exception caught" + exp);
}
try {
do {
i = Fin.read();
System.out.print((char) i);
} while (i != -1);
} catch (IOException exp) {
System.out.println("Exception caught" + exp);
}
finally {
try {
Fin.close();
} catch (IOException exp) {
System.out.println("Exception caught" + exp);
}
}
}
}
while the below code compiles. You can see both initialization are within try block.
import java.io.*;
class ShowFile2 {
public static void main(String args[]) {
int i;
FileInputStream fin;
// First make sure that a file has been specified.
try {
fin = new FileInputStream("C:\\Users\\cbr\\Desktop\\test.txt");
} catch (FileNotFoundException exc) {
System.out.println("File Not Found");
return;
}
try {
// read bytes until EOF is encountered
do {
i = fin.read();
if (i != -1) {
System.out.print((char) i);
}
} while (i != -1);
} catch (IOException exc) {
System.out.println("Error reading file.");
}
try {
fin.close();
} catch (IOException exc) {
System.out.println("Error closing file.");
}
}
}
The problem is, that if new FileInputStream("C:\\Users\\cbr\\Desktop\\test.txt"); throws an exception, your variable will not be initialized in the second part of your method. This is not allowed. Object members will be initialized to null when the object is created, but this is not the case for local variables: they must be initialized explicitly.
A quick fix (but read on for a better fix) would be to initialize your variable (to null) when you are defining it:
FileInputStream fin = null;
This will solve your compilation error, however, you will get NullPointerExceptions when an exception is thrown in the first catch block.
A better solution is to put your error handling logic in the same place: if creating the FileInputStream fails, you don't want to read bytes from it anyway. So you can use a single try-catch block:
try {
fin = new FileInputStream("C:\\Users\\cbr\\Desktop\\test.txt");
// Read bytes from fin.
...
} catch (IOException e) {
// handle exception
...
}
Final advice: to make sure that your input stream is closed in all circumstances, you can use a try-with-resources block:
try (fin = new FileInputStream("C:\\Users\\cbr\\Desktop\\test.txt")) {
// Read bytes from fin.
...
} catch (IOException e) {
// handle exception
...
}
It does compile because the ShowFile2 class contains return in the catch block: this will ensure that the variable fin will be always initialized.
In the first class you caught the exception and you continue the execution of your program.

How to close a RandomAccessFile

I'm trying to close a RandomAccessFile but resource remain busy.
Code:
public boolean isOpen(RandomAccessFile f) {
try {
f.length() ;
return true ;
}
catch (IOException e) {
return false ;
}
}
this.rfmFile = new File(filePath);
try {
this.rfmRandomAccessFile = new RandomAccessFile(rfmFile, "rws");
} catch(Exception e){
}finally{
this.rfmRandomAccessFile.close();
}
while(!isOpen(this.rfmRandomAccessFile));
log.debug("I Finally Closed this RAF");
Log is not showed and thread goes in loop.
When I try to access to my resource from shell it gives me "Device or Resource busy".
The only way to access is kill java process.
When you are trying to access the RandomAccessFile length(), method, it is already closed and thus you cannot access it anymore.
You probably want to use the length() method of File. Your loop cannot work as the RandomAccessFile was already closed.
But I must admit I am clueless on the low level reason why rfmRandomAccessFile would not really be closed. It could be a side effect of your strange loop trying to get the size of a closed file.
[edit:]Could not reproduce your issue with the following piece of code:
package com.company;
import java.io.*;
public class Main {
public static void main(String[] args) {
File file = new File("foobar.txt");
RandomAccessFile randomAccessFile = null;
try {
randomAccessFile = new RandomAccessFile(file, "rws");
randomAccessFile.write(new byte[]{'f'});
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(randomAccessFile !=null){
try {
randomAccessFile.close();
} catch (IOException e) {
//doh!
}
}
}
FileReader reader = null;
try {
reader = new FileReader(file);
char read = (char) reader.read();
System.out.println("what was written: "+read);
System.out.println("file size: "+file.length());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(reader !=null){
try {
reader.close();
} catch (IOException e) {
//doh!
}
}
}
}
}

Java - passing input into external C/C++ application

I'm trying to enter some value in external application using Java.
Java application looks like this:
Runtime runtime = Runtime.getRuntime();
// ... str build ...
proc = runtime.exec(str);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
bw.write(value);
bw.flush();
bw.close();
if (proc.waitFor() != 0)
// error msg
// the end
Application hangs at waitFor method.
External application looks like this:
welcome banner
please enter 8 character input:
Welcome banner is printed using printf and input is taken with SetConsoleMode/ReadConsoleInput. ReadConsoleInput reads one char and they are masked with * character.
Help
you can use:
proc.getOutputStream().write("some date".getBytes())
keep in mind that you HAVE to read everything the app send to stdout and stderr, else it might get stuck writing there.
I use a generic class to read it in a different thread.
usage is like:
InputStreamSucker inSucker = new InputStreamSucker(proc.getInputStream());
InputStreamSucker errSucker = new InputStreamSucker(proc.getErrorStream());
proc.waitFor();
int exit = process.exitValue();
inSucker.join();
errSucker.join();
InputStreamSucker code is here:
public class InputStreamSucker extends Thread
{
static Logger logger = Logger.getLogger(InputStreamSucker.class);
private final BufferedInputStream m_in;
private final ByteArrayOutputStream m_out;
private final File m_outFile;
public InputStreamSucker(InputStream in) throws FileNotFoundException
{
this(in, null);
}
public InputStreamSucker(InputStream in, File outFile) throws FileNotFoundException
{
m_in = new BufferedInputStream(in, 4096);
m_outFile = outFile;
m_out = new ByteArrayOutputStream();
start();
}
#Override
public void run()
{
try
{
int c;
while ((c = m_in.read()) != -1)
{
m_out.write(c);
}
}
catch (IOException e)
{
logger.error("Error pumping stream", e);
}
finally
{
if (m_in != null)
{
try
{
m_in.close();
}
catch (IOException e)
{
}
}
try
{
m_out.close();
}
catch (IOException e)
{
logger.error("Error closing out stream", e);
}
if (m_outFile != null)
{
byte data[] = m_out.toByteArray();
if (data.length > 0)
{
FileOutputStream fo = null;
try
{
fo = new FileOutputStream(m_outFile);
fo.write(data);
}
catch (IOException e)
{
logger.error("Error writing " + m_outFile);
}
finally
{
try
{
if (fo != null) fo.close();
}
catch (IOException e)
{
logger.error("Error closing " + m_outFile);
}
}
}
}
}
}
public String getOutput()
{
return new String(m_out.toByteArray());
}
}
Got the answer! The trick is to use WriteConsoleInput() API because program expects keyboard event, not text ... That's why the waitFor() waited forever! :)

Categories