Serialization:java.io.StreamCorruptedException: invalid stream header: 0AACED00 - java

I'm a student practicing my File IO skills and I am coming up against a problem with reading Objects from a file using ObjectInputStream. The code is consistently throwing an InvalidClassException and I can't find how the code is throwing it online or by trial and error. Here's my code:
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class ReadFromFile {
String filename;
List<Object> os;
public ReadFromFile(String filename) {
this.filename = filename;
os = new ArrayList<>();
}
public Object[] readObject() {
try {
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
System.out.print("reading\n");
while (true) {
os.add(ois.readObject());
System.out.print("read one\n");
}
} catch (EOFException e) {
return os.toArray();
} catch (FileNotFoundException e) {
System.out.print("File not found\n");
return os.toArray();
} catch (ClassNotFoundException e) {
System.out.print("Class not found\n");
return os.toArray();
} catch (StreamCorruptedException e) {
System.out.print("SC Exception\n");
e.printStackTrace();
return os.toArray();
} catch (InvalidClassException e) {
e.printStackTrace();
System.out.print("IC Exception\n");
return os.toArray();
} catch (OptionalDataException e) {
System.out.print("OD Exception\n");
return os.toArray();
} catch (IOException e) {
System.out.print("IO Exception\n");
return os.toArray();
}
}
}
I wrote all of the separate catch blocks to figure out what Exception was being thrown and it always throws the InvalidClassException.
Here also is my Tree Class:
import java.io.Serializable;
public class Tree implements Serializable {
private static final long serialVersionUID = -310842754445106856L;
String species;
int age;
double radius;
public Tree() {
this.species = null;
this.age = 0;
this.radius = 0;
}
public Tree(String species, int age, double radius) {
this.species = species;
this.age = age;
this.radius = radius;
}
public String toString() {
return species + ", age: " + age + ", radius: " + radius;
}
}
And here is my write to file function:
public boolean write(Object object) {
try {
File f = new File(filename);
FileOutputStream fos = new FileOutputStream(f,true);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(object + "\n");
oos.close();
} catch (FileNotFoundException e) {
System.out.print("File Not Found\n");
return false;
} catch (IOException e) {
System.out.print("IOException\n");
return false;
}
return true;
}
Your knowledge is appreciated...
Stack trace:
SC Exception
java.io.StreamCorruptedException: invalid stream header: 0AACED00
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:806)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at ReadFromFile.readObject(ReadFromFile.java:17)
at WriteAndRecord.main(WriteAndRecord.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Process finished with exit code 0

java.io.StreamCorruptedException: invalid stream header: 0AACED00
This is caused by appending to the FileOutputStream. As I mentioned in a comment above, you can't append to a stream written by ObjectOutputStream, at least not without special measures. Keep the file and the ObjectOutputStream open until you've written all the objects you want to write, then close it, then deserialize from it.
NB As I also mentioned,
while ((object = in.readObect()) != null)
is not a valid object-reading loop. readObject() doesn't return null at end of stream: it throws EOFException. null can occur anywhere in the stream, any time you write one. The correct form of the loop is:
try
{
for (;;)
{
Object object = in.readObject();
// ...
}
}
catch (EOFException exc)
{
// end of stream
}
// other catch blocks ...
NB 2 This:
oos.writeObject(object + "\n");
should be just
oos.writeObject(object);
Otherwise you're implicity calling toString() and pointlessly appending a line terminator, so the result of readObject() will be a String, not the original object.

I think this was caused by the lack of a serialVersionUID.
Whenever you serialize an object, the ClassLoader needs something to verify the new loaded object against to verify it and ensure its compatibility. In order to do this, you just need to define a field in your class like this:
private static final long serialVersionUID = 12358903454875L;
Your IDE may have also given you a warning stating the lack of it (Eclipse does this).
This should solve your problem.
You can learn more in this excellent answer by Jon Skeet here: What is a serialVersionUID and why should I use it?.

Related

ObjectOutputStream Resulting in EOF Error

I'm trying to implement object serialization in java. I'm not sure why my code is currently leading to an EOFException, as my code is writing to the file it's supposed to:
Currently, my code is:
import java.io.*;
public class main {
public static void main(String[] args) {
product p1 = new product("product", 0, "this is a product.");
ObjectOutputStream out = null;
try {
out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("info.dat")));
out.writeObject(p1);
out.writeObject(p1);
System.out.println("Wrote to file");
} catch (FileNotFoundException e) {
System.out.println("");
} catch (IOException e) {
System.out.println("");
}
ObjectInputStream in = null;
try {
in = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream("info.dat")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
while product class is extremely simple, being only:
import java.io.Serializable;
public class product implements Serializable {
String name;
double cost;
String description;
public product(String a,double b,String c) {
name = a;
cost = b;
description = c;
}
}
Currently, the output is
Meaning that my code did run and did write to file. I also added an extra write object just in case, so I really don't understand how an EOF error is occurring. Can somebody please explain why?

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.
}
}

Cannot read multiple externalizable objects from InputStream [duplicate]

This question already has an answer here:
StreamCorruptedException: invalid type code: AC
(1 answer)
Closed 8 years ago.
I have a trouble with reading multiple objects from InputStream(i.e. from file). I receive the exception:
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1379)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at com.socket.Client.readFromFile(Client.java:63)
at com.socket.Client.main(Client.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
I have managed to read/write only one object, it's OK. I can write many objects, it's OK too. But I cannot read more than one object from file. Why does it happen so?
EDIT:
NB! It seems I have faced with the problem of implementing of List in Externalazible class. How to implement it correcly?
My 'Main' code:
public class Client {
public static void main(String[] args) {
if (args[0] == null || args[1] == null) {
System.out.println("No arguments entered!");
System.exit(0);
}
try (Socket clientSocket = new Socket("localhost", 3000);
OutputStream outbound = clientSocket.getOutputStream();
BufferedReader inbound = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));) {
outbound.write((args[0] + "\n").getBytes());
outbound.write("End\n".getBytes());
List<StockQuote> stockQuotes = new ArrayList<>();
String quote;
while (true) {
quote = inbound.readLine();
if (quote != null && quote.equals("End"))
break;
stockQuotes.add(new StockQuote(args[0], new Double(quote)));
}
writeInFile(args[1], stockQuotes);
stockQuotes.clear();
stockQuotes = readFromFile(args[1]);
if (stockQuotes != null)
for (StockQuote stockQuote : stockQuotes)
System.out.println("The " + stockQuote.getSymbol() + " price is " + stockQuote.getPrice());
} catch (UnknownHostException e) {
System.out.println("No such host available!");
} catch (IOException e) {
System.out.println("Server not reachable or down!!");
}
}
private static List<StockQuote> readFromFile(String filename) {
File file = new File(filename);
try (ObjectInputStream readFromFile = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));) {
return (List<StockQuote>) readFromFile.readObject();
} catch (FileNotFoundException e) {
System.out.println("'" + filename + "' is not found in " + file.getPath());
} catch (IOException e) {
e.printStackTrace();
System.out.println("Something gone wrong in the process of reading from '" + file + "'");
} catch (ClassNotFoundException e) {
System.out.println("Cast to class is wrong!");
}
return null;
}
private static void writeInFile(String filename, List<StockQuote> stockQuotes) {
File file = new File(filename);
try (ObjectOutputStream writeInFile = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file, true)));) {
writeInFile.writeObject(stockQuotes);
} catch (FileNotFoundException e) {
System.out.println("'" + filename + "' is not found in " + file.getPath());
} catch (IOException e) {
System.out.println("Something gone wrong in the process of writing to '" + file + "'");
}
}
}
Externalizable 'StockQuote' class:
public class StockQuote implements Externalizable {
private String symbol;
private double price;
private List<StockQuote> stockQuoteList;
public StockQuote() {
}
public StockQuote(String symbol, double price) {
this.symbol = symbol;
this.price = price;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
#Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(stockQuoteList);
}
#Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
stockQuoteList = (List<StockQuote>) in.readObject();
}
}
Result:
As the result, I receive something like "The null price is 0.0". It says that I serialize my List but my Objects inside it are not serialized, why?
NB!
And could you take me one more tip, how is better to write strings, list and so on in Externalizable classes as out.writeObject or there is beter way to do it?
Your reads and writes are not symmetric.
To write two stock quotes, you
open a new ObjectOutputStream
write a StockQuote
close the ObjectOutputStream
open a new ObjectOutputStream
write a StockQuote
close the ObjectOutputStream
To read these two StockQuotes, you
open an ObjectInputStream
read a StockQuote
read a StockQuote
close the ObjectInputStream
Each time you open a new ObjectOutputStream, a serialization header is written to the underlying stream.
My advice: store all the StockQuotes to a list, and write this list to the ObjectOutputStream when you're done. On the receiver end, read the list.

Can't serialize an ArrayList

This is a followup to Serializing a vector
I'm trying to implement loading and saving for a game I'm working on.
I want to save a Maze which contains, among other attributes, an ArrayList of Entity.
Entity is a super class for Dragon, Hero and Item. All three of these types can be contained at once in the vector.
Using the "automatic" serialization mechanism (adding implements Serializable to Maze) saves all attributes but the ArrayList.
Why does this happen?
My code is below, for completeness' sake.
package logic;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public final class LoadAndSave {
public static final transient boolean available = false;
public static final boolean serialize(Object obj) {
// Write to disk with FileOutputStream
FileOutputStream saveFile;
try {
saveFile = new FileOutputStream("game.sav");
} catch (FileNotFoundException e) {
return false;
}
// Write object with ObjectOutputStream
ObjectOutputStream objOut;
try {
objOut = new ObjectOutputStream(saveFile);
} catch (IOException e) {
//
return false;
}
// Write object out to disk
try {
objOut.writeObject(obj);
} catch (IOException e) {
return false;
}
return true;
}
public static final Object load() {
FileInputStream fileIn;
try {
fileIn = new FileInputStream("game.sav");
} catch (FileNotFoundException e1) {
return null;
}
// Read object using ObjectInputStream
ObjectInputStream objIn;
try {
objIn = new ObjectInputStream(fileIn);
} catch (IOException e) {
return null;
}
// Read an object
Object obj;
try {
obj = objIn.readObject();
} catch (IOException e) {
return null;
} catch (ClassNotFoundException e) {
return null;
}
return obj;
}
}
Is Entity serializable too? (you mentioned that just Maze is serializable).
And be sure that the list is not defined as transient or static, otherwise it will be skipped by the serialization mechanism.
I checked Your code with the following assumptions:
class Entity implements Serializable {}
and:
private char[][] mazeWalls = new char[0][0];
private Vector<Entity> entities = new Vector<Entity>();
...and it works perfectly, serializing and deserializing empty Entity objects...
You need to make sure that you close your streams. Your code for load() can be simplified to look something like this:
ObjectInputStream objIn = null;
try {
objIn = new ObjectInputStream(new FileInputStream("game.sav"));
return objIn.readObject();
} catch (Exception exception) {
// Deal with errors
return null;
} finally {
if (objIn != null) {
try {
objIn.close();
} catch (Exception exception) {}
}
}
serialise() can be altered in a similar way.

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