Stream closed error - Storm - java

I am trying to read a line in a file, in the spout, and then send it to the bolts but i keep getting a stream closed error. Do I close it wrong or what is the problem here?
public class InputSpout extends BaseRichSpout {
private SpoutOutputCollector collector;
public void
declareOutputFields( OutputFieldsDeclarer declarer) {
declarer.declare( new Fields("logfile"));
}
private FileReader fileReader;
private boolean completed = false;
private TopologyContext context;
#Override
public void open( Map config, TopologyContext context, SpoutOutputCollector collector) {
try {
this.context = context;
this.fileReader = new FileReader(("logfile.txt").toString());
} catch (FileNotFoundException e) {
throw new RuntimeException("Error reading file "
+ ("logfile"));
}
this.collector = collector;
}
public void nextTuple() {
if (completed) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
String str;
BufferedReader reader = new BufferedReader(fileReader);
str = null;
try {
str = reader.readLine();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
while (str != null) {
this.collector.emit(new Values(str));
str = reader.readLine();
}
} catch (Exception e) {
throw new RuntimeException("Error reading typle", e);
} finally {
completed = true;
}
try {
reader.close();
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
This is the error I am getting:
java.io.IOException: Stream closed
at sun.nio.cs.StreamDecoder.ensureOpen(StreamDecoder.java:46)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:147)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
at java.io.BufferedReader.readLine(BufferedReader.java:382)
at myStorm.InputSpout.nextTuple(InputSpout.java:52)
at backtype.storm.daemon.executor$fn__4654$fn__4669$fn__4698.invoke(executor.clj:565)
at backtype.storm.util$async_loop$fn__458.invoke(util.clj:463)
at clojure.lang.AFn.run(AFn.java:24)
at java.lang.Thread.run(Thread.java:745)

You're closing the InputStream used by fileReader in nextTuple making it unavailable for subsequent calls. There's no need to close this Reader - just close a single BufferedReader when all data has been read.

Related

How could I deal with this custom Exception?

I have this bit of code which depends from a custom Exception thrown by a function inside findID() it throws a NoClientFound Exception that I made whenever this mentioned function returns a null (The client does not exist).
The IDE suggests that I shall apply that Exception into the code, but in this bit of code, where I need the ID to be null (unique IDs) I "can't catch that exception" since if I catch it, the function will not be executed as intended.
Question: How I can manage this?
Function with the Exception problem
public boolean add(Client c) {
StringBuilder sb = new StringBuilder();
boolean added = false;
try {
if (findID(c.getID()) == null) {
try (BufferedWriter bw = new BufferedWriter(
new FileWriter(fitxer, true));) {
//Add client to file
bw.write(sb.append(c.getID()).append(SEPARADOR).
append(c.getName()).toString());
bw.newLine();//New line
bw.flush(); //Push to file
added = true;
} catch (IOException e) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE,
null, "Error appeding data to file" + e);
}
}
} catch (IOException ex) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE, null,
"Error appeding data to file" + ex);
} finally {
}
return addded;
}
Exception Code
public class NoClientFound extends Exception {
private String msg;
public NoClientFound() {
super();
}
public NoClientFound(String msg) {
super(msg);
this.msg = msg;
}
#Override
public String toString() {
return msg;
}
You can catch that exception and handle it accordingly. When you catch NoClientFound exception that means findID(c.getID()) is null. So without handling that in the if block you can handle that within the catch block.
public boolean add(Client c) {
StringBuilder sb = new StringBuilder();
boolean added = false;
try {
// call the function
findID(c.getID());
} catch (NoClientFound ex) {
//handle the NoClientFound exception as you like here
BufferedWriter bw = new BufferedWriter(
new FileWriter(fitxer, true));
//Add client to file
bw.write(sb.append(c.getID()).append(SEPARADOR).
append(c.getName()).toString());
bw.newLine();//New line
bw.flush(); //Push to file
added = true;
}catch (IOException ex) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE, null,
"Error appeding data to file" + ex);
}finally {
}
return addded;
}
I assume you already have a null check on findID(...)
if( c == null || findID(c.getID()) == null){
throw new NoClientFound("Client not found!");
}else{
//add your file writing operation
}
and Also in NoClientFound class extend it from RuntimeException, not the Exception.
public class NoClientFound extends RuntimeException {
...
}
Caller method:
public void caller(){
Client client = new Client();
client.setId(1);
...
try{
add(client);
}catch(NoClientFound ex){
//client not found then create one for ex...
}
catch(Exception ex){
//somthing else happend
log.error(ex.getmessge());
}
}

Undefined behavior when working with the input stream

Why is this code contains undefined behavior (the program is completed in half the time). How do I make a clean shutdown of the reader when I need to complete the program?
public class Main implements Runnable {
private static BufferedReader reader;
public static void main(String[] args) {
reader = new BufferedReader(new InputStreamReader(System.in));
new Thread(new Main()).start();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
//System.in.close(); // <-- undefined behavior
reader.close(); // <-- undefined behavior
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
try {
reader.readLine();
} catch (IOException ignore) {
}
}
}

Client-Server, Object Input/Output, DeadLock

I am pretty new to writing client/server based apps. both server and client classes are kicked off in threads. New to using Object Output/input streams over tcp aswell. Have never had fun with serialization. In my application I am trying to use Object Input/Output Streaming but it looks like opening them is causing my application dies. The funny thing is that if I comment two lines:
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
Connection works nicely and app proceeds to the next panels etc. But I am still not capable of sending any objects throughout the socket. When I literally try to open those streams. It still connects but app get freezed. I 've got two questions:
first: is it better to use serialization
second: if I can use Object streaming, how should I open them? Can I do it inside the server/client thread?
Thanks for Your time
Here is the code of ClientApp:
public void run()
{
while (true)
{
try // odswiezanie co sekunde
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
try // polaczenie
{
if (connecting)
{
socket = new Socket(hostIP, port);
JOptionPane.showMessageDialog(null, "Connection established!");
connected = true;
connecting = false;
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
JOptionPane.showMessageDialog(frame, "Unknown server!");
connected = false;
}
catch (IOException e)
{
JOptionPane.showMessageDialog(frame,"An Error occured while trying to connect to the server!");
e.getMessage();
e.printStackTrace();
connected = false;
}
catch (IllegalThreadStateException e)
{
e.printStackTrace();
}
try // odbior obiektow
{
if(connected)
{
while(!opponentIsReady){
System.out.println("wszedlem do connected!(klient) ");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do klienta!");
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
Do you use Serializable interface for the Map object ?
If you still frozen at a step, its maybe because you try to read object (from server or client) and you didn't send it by the other side. While the object is not read it will wait for content.
I dont know how work your server, but you read response twice when oppenentReady is false.
if (inStream.readObject() != null) {
if (inStream.readObject() instanceof Boolean) {
//...
}
}
If this is not the expected behavior, you should store it in local variable.
Once again, this's smt I want to implement(in steps)
1. user choose to open connection(he becomes a server and waits for a client
to connect) - done.
2. second user choose to connect(becomes a client and connects to the
second player(server) - done.
3. Both get message that the connection is established and they are moved
to the next Panel where they do specific operations - done.
4.When anyone of them finishes, I want to tell it to the second guy
(it is represented by a boolean local varable) - here comes the problem.
5. When both have finished, they should be moved to the next Panel where
they play.(before they start playing, Maps that they have set in the previous Panel
should be sent to each other.
Next steps I can handle if Only I knew maybe not how to send those informations
but where to place sending code because it seems to be in the wrong place. Here is the full code of client/server classes:
connecting - is set to true in the other class after pushing the button.
iAmready - is set to true when player finishes setting up the map and should be sent to opponent,
because it triggers a specific operation by setting opponentIsReady to true when obtained.
public class ClientApp implements Runnable
{
public static String hostIP = "127.0.0.1";
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = false;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public final Frame frame;
public static Map mapToGet;
public static Map mapToSend;
public ClientApp(Frame parent)
{
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run()
{
while (true)
{
try // odswiezanie co sekunde
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
try // polaczenie
{
if (connecting)
{
socket = new Socket(hostIP, port);
JOptionPane.showMessageDialog(null, "Connection established!");
connected = true;
connecting = false;
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
JOptionPane.showMessageDialog(frame, "Unknown server!");
connected = false;
}
catch (IOException e)
{
JOptionPane.showMessageDialog(frame,"An Error occured while trying to connect to the server!");
e.getMessage();
e.printStackTrace();
connected = false;
}
catch (IllegalThreadStateException e)
{
e.printStackTrace();
}
try // odbior obiektow
{
if(connected)
{
FileOutputStream out = new FileOutputStream("/tmp/message.ser");
outStream = new ObjectOutputStream(out);
FileInputStream in = new FileInputStream("/tmp/message.ser");
inStream = new ObjectInputStream(in);
while(!opponentIsReady){
System.out.println("wszedlem do connected!(klient) ");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do klienta!");
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady && iAmReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}
inStream.close();
outStream.close();
in.close();
out.close();
}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
public static void connectionEstablished(Frame frame)
{
frame.remove(frame.connectPanel);
frame.getContentPane().add(frame.settingPanelForClient);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame)
{
frame.remove(frame.settingPanelForClient);
frame.getContentPane().add(frame.opponentsMove);
frame.validate();
frame.repaint();
}
public static Map getMap()
{
try
{
if (connected)
if (inStream.readObject() != null && inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static void sendMap()
{
if (connected)
if (mapToSend != null)
{
try
{
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
public class ServerApp implements Runnable
{
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = false;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ServerSocket hostServer = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public static Map mapToGet;
public static Map mapToSend;
final Frame frame;
public ServerApp(Frame parent)
{
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run()
{
while(true)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e) {}
try
{
if (connecting)
{
hostServer = new ServerSocket(port);
socket = hostServer.accept();
connected = true;
connecting = false;
JOptionPane.showMessageDialog(null, "Connection Established!");
frame.settingPanelForServer.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
}
}
catch (UnknownHostException e)
{
connected = connecting = false;
}
catch (IOException e)
{
connected = connecting = false;
}
try // odbior obiektow
{
if(connected)
{
while(!opponentIsReady){
System.out.println("wszedlem do connected(server)");
System.out.println(opponentIsReady);
if(!opponentIsReady)
{
inStream = new ObjectInputStream(socket.getInputStream());
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
}
if(iAmReady && !opponentIsReady)
{
System.out.println("wszedlem do iAmReady i wysylam wiadomosc o gotowosci do servera!");
outStream = new ObjectOutputStream(socket.getOutputStream());
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
outStream.writeObject(iAmReady);
outStream.flush();
}
if(opponentIsReady && iAmReady)
{
sendMap();
proceedToNextPanel(frame);
opponentIsReady = false;
}
}}
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
public static void connectionEstablished(Frame frame)
{
frame.remove(frame.waitPanel);
frame.getContentPane().add(frame.settingPanelForServer);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame)
{
frame.remove(frame.settingPanelForServer);
frame.getContentPane().add(frame.playPanelForServer);
frame.validate();
frame.repaint();
}
public static Map getMap()
{
try
{
if (connected)
if (inStream.readObject() != null && inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static void sendMap()
{
if (connected)
if (mapToSend != null)
{
try
{
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}
As i said before, you can not use readObject() more than once for the same object.
Example,
Use:
Object objectRead=inStream.readObject();
if (objectRead != null) {
if (objectRead instanceof Boolean) {
opponentIsReady = Boolean.valueOf(objectRead);
System.out.println(opponentIsReady);
} else if (objectRead instanceof Map) {
mapToGet = (Map) objectRead;
}
}
Instead of:
if(inStream.readObject() != null)
{
if(inStream.readObject() instanceof Boolean)
{
opponentIsReady = inStream.readBoolean();
System.out.println(opponentIsReady);
}
else if(inStream.readObject() instanceof Map)
{
mapToGet = (Map) inStream.readObject();
}
}
I think you didn't understand how it works:
When the client/server connection is etablished you can use Threads to read or write objects.
I give you code that you can test to understand how it works:
ServerApp:
public class ServerApp implements Runnable {
public static int port = 1000;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ServerSocket hostServer = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public static Map mapToGet;
public static Map mapToSend;
final Frame frame;
private boolean connected = false;
public ServerApp(Frame parent) {
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run() {
// Server initialization side
try {
hostServer = new ServerSocket(port);
JOptionPane.showMessageDialog(frame, "Waiting for opponent to finish");
// Accept will wait until a client try to connect
socket = hostServer.accept();
JOptionPane.showMessageDialog(null, "Connection Established!");
// Init streams when connection is etablished
inStream = new ObjectInputStream(socket.getInputStream());
outStream = new ObjectOutputStream(socket.getOutputStream());
frame.settingPanelForServer.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
connected = true;
} catch (IOException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
}
int x = 0;
// The loop is made to send/receive all messages
while (connected) {
try {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
}
Object o = String.format("I send you a message (%s)", x++);
outStream.writeObject(o);
Object response = inStream.readObject();
System.out.println("Response: " + response);
} catch (IOException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
connected = false;
} catch (ClassNotFoundException ex) {
Logger.getLogger(ServerApp.class.getName()).log(
Level.SEVERE, null, ex);
connected = false;
}
}
System.err.println("Connection closed");
}
public static void connectionEstablished(Frame frame) {
frame.remove(frame.waitPanel);
frame.getContentPane().add(frame.settingPanelForServer);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame) {
frame.remove(frame.settingPanelForServer);
frame.getContentPane().add(frame.playPanelForServer);
frame.validate();
frame.repaint();
}
public static Map getMap() {
try {
if (inStream.readObject() != null && inStream.readObject() instanceof Map) {
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void sendMap() {
if (mapToSend != null) {
try {
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ClientApp:
public class ClientApp implements Runnable {
public static String hostIP = "127.0.0.1";
public static int port = 1000;
public static boolean connected = false;
public static boolean connecting = true;
public static boolean iAmReady = false;
public static boolean opponentIsReady = false;
public static Socket socket = null;
public static ObjectInputStream inStream;
public static ObjectOutputStream outStream;
public final Frame frame;
public static Map mapToGet;
public static Map mapToSend;
public ClientApp(Frame parent) {
frame = parent;
mapToGet = new Map();
mapToSend = new Map();
}
#Override
public void run() {
try {
// Client initialization side
socket = new Socket(hostIP, port);
// If the socket connection succeed it pass, else execption is thrown
JOptionPane.showMessageDialog(null, "Connection Established!");
// Initialize streams
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());
frame.settingPanelForClient.bPlayerName.setText("Put the ships on your board!");
connectionEstablished(frame);
connected=true;
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
}
// The loop will receive server message and send response
while (connected) {
try {
Object serverMessage = inStream.readObject();
System.out.println("Server sent: " + serverMessage);
Object myResponse = String.format("I received %s", serverMessage);
outStream.writeObject(myResponse);
} catch (IOException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
connected=false;
} catch (ClassNotFoundException ex) {
Logger.getLogger(ClientApp.class.getName()).log(
Level.SEVERE, null, ex);
connected=false;
}
}
System.err.println("Connection closed");
}
public static void connectionEstablished(Frame frame) {
frame.remove(frame.connectPanel);
frame.getContentPane().add(frame.settingPanelForClient);
frame.validate();
frame.repaint();
}
public static void proceedToNextPanel(Frame frame) {
frame.remove(frame.settingPanelForClient);
frame.getContentPane().add(frame.opponentsMove);
frame.validate();
frame.repaint();
}
public static Map getMap() {
try {
if (connected) {
if (inStream.readObject() != null && inStream.readObject() instanceof Map) {
mapToGet = (Map) inStream.readObject();
return mapToGet;
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void sendMap() {
if (connected) {
if (mapToSend != null) {
try {
outStream.writeObject(mapToSend);
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

Java application and AMD processor issues

We have a windows application, which was tested on Windows XP, 7, 8, 8.1. Application consists of 2 parts: Bootstrap and main application. Bootstrap assures updates of the main app, and updates main app at a particular point. But users were able to force stop Boostrap process via the Task Manager (Ctrl+Shift+ESC->processes) by killing a process named javaw. In that case main app would not update and elder version would be launched. To avoid such issue we introduced interface of Bootstrap with main application via Socket. Here are the VM parameters of Bootstrap when it starts:
javaw.exe -Xms75M -Xmx90M -Xincgc -jar bootstrap.jar
There is a class SocketServer in the bootstrap:
public class Provider {
ServerSocket providerSocket;
Socket connection = null;
ObjectOutputStream out;
ObjectInputStream in;
String message;
public Provider() {
}
public void run() {
try{
providerSocket = new ServerSocket(54345);
connection = providerSocket.accept();
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
in = new ObjectInputStream(connection.getInputStream());
sendMessage("Connection successful");
do {
try {
message = (String)in.readObject();
if (message.equals("bye")) {
sendMessage("bye");
}
} catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
} while (!message.equals("bye"));
} catch(IOException ioe) {
ioe.printStackTrace();
} finally {
try {
in.close();
out.close();
providerSocket.close();
} catch(IOException ioef) {
ioef.printStackTrace();
}
}
}
public void sendMessage(String msg) {
try {
out.writeObject(msg);
out.flush();
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
public void stop() {
if (providerSocket != null && in != null && out != null && !providerSocket.isClosed()) {
try {
in.close();
out.close();
providerSocket.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
Main app is being started by Bootstrap via ProcessBuilder like so:
public static void communicate(Process process) {
final BufferedReader stdOut = new BufferedReader(new InputStreamReader(process.getInputStream(), Charset.forName("Windows-1251")));
final BufferedReader stdErr = new BufferedReader(new InputStreamReader(process.getErrorStream(), Charset.forName("Windows-1251")));
//InputStream
new Thread() {
#Override
public void run() {
String line;
try {
while ((line = stdOut.readLine()) != null) {
debugOut(line);
}
} catch (Exception e) {
e.printStackTrace();
}
try {
stdOut.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}.start();
//ErrorStream
new Thread() {
#Override
public void run() {
String line;
try {
while ((line = stdErr.readLine()) != null) {
debugOut(line);
}
} catch (Exception e) {
e.printStackTrace();
}
try {
stdErr.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}.start();
try {
final Provider provider = new Provider();
ExecutorService pEexec = Executors.newCachedThreadPool();
Future<Void> FPExec = pEexec.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
while (!Thread.currentThread().isInterrupted()) {
provider.run();
}
return null;
}
});
pEexec.shutdown();
process.waitFor();
debugOut("[MainApp] Exit");
provider.stop();
FPExec.cancel(true);
debug("Destroy process");
process.destroy();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void startApp() {
try {
ArrayList<String> params = new ArrayList<String>();
...
params.add("-Xms32M");
params.add("-Xmx48M");
params.add("-Xincgc");
params.add("-cp");
params.add(new File(pathToJar, "mainapp.jar").getPath());
params.add("net.craftwork.mainapp.AppStart");
params.add(licCode());
ProcessBuilder procBuild = new ProcessBuilder(params);
debugOut("[MainApp] Start");
Process proc = procBuild.start();
communicate(proc);
} catch (Exception e) {
e.printStackTrace();
}
}
There is a class SocketClient in the main app:
public class Requester {
Socket requestSocket;
ObjectOutputStream out;
ObjectInputStream in;
String message;
static Future<Void> oExec;
Requester() {
}
void run() {
try {
requestSocket = new Socket("localhost", 54345);
out = new ObjectOutputStream(requestSocket.getOutputStream());
out.flush();
in = new ObjectInputStream(requestSocket.getInputStream());
do {
try {
message = (String)in.readObject();
sendMessage("bye");
} catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
} while (!message.equals("bye"));
} catch(UnknownHostException uhe) {
uhe.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
oExec.cancel(true);
CommonUtils.debug("Bootstrap not found. Exit.");
System.exit(0);
} finally {
try {
in.close();
out.close();
requestSocket.close();
} catch(IOException ioef) {
ioef.printStackTrace();
}
}
}
void sendMessage(String msg) {
try {
out.writeObject(msg);
out.flush();
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
public static void main() {
final Requester client = new Requester();
ExecutorService exec = Executors.newCachedThreadPool();
oExec = exec.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
while (!Thread.currentThread().isInterrupted()) {
client.run();
Thread.sleep(1000);
}
return null;
}
});
exec.shutdown();
}
}
Socket Client is called when main application starts
public class AppStart {
public static void main(final String[] args) {
Requester.main();
EventQueue.invokeLater(new Runnable() {
public void run() {
...
}
});
}
}
This is all to it I do believe. Whole setup worked perfectly fine, even on slower computers. Problem is that after introduction of Socket interface we had major complaints from some users, reporting crashes. Took us some time to figure out the issue, but here is what we found: computers with Intel processors are perfectly fine, only ones with AMD processors crash. Crash normally happens within 3 to 15 minutes from the start of Bootstrap. When crash occurs resources of the computer are not fully used, processor workload is about 20-50% and RAM is quite free as well. When crash occurs user is only able to reset computer using hardware reset or power button, nothing else responds. All users have latest JAVA 1.7.0_51. Whether system is 32 or 64 bit does both crash (or not crash if it is Intel based). Please share your thoughts. May be someone had identical issues and could help me to figure this out.

Close a BufferedReader in a Iterator for returning file lines

I wrote the following class for an iterator that iterates along the lines of a file.
import java.io.*;
import java.util.Iterator;
public class FileIterator implements Iterator<String> {
private BufferedReader reader;
public FileIterator(String filename) {
this.reader = getBufferedReader(filename);
}
private static BufferedReader getBufferedReader(String filename) {
File file = new File(filename);
if(file.exists()) {
try {
return new BufferedReader(new InputStreamReader(
new FileInputStream(new File(filename)),"UTF-8"));
} catch (Exception e) {
e.printStackTrace();
return null;
}
} else {
System.out.println(filename + " is not there");
return null;
}
}
public boolean hasNext() {
try {
return reader.ready();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public String next() {
try {
return reader.readLine();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public void remove() {}
}
Now my question is a bit naive. Will be the reader closed once the iterator is no more used, when the GC will take care of it? Would the class improve if I close the reader manually? Maybe as a side effect in the hasNext() method:
public boolean hasNext() {
try {
if(reader.ready()) return true;
else {
reader.close();
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
Thanks!
If you really want to do this, I would have FileIterator implement Closeable and delegate the call to the underlying BufferedReader. You could even use it in a Java 7 try-with-resources block.

Categories

Resources