File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes Blocking FileWriters and Pipes Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Blocking FileWriters and Pipes" Watch "Blocking FileWriters and Pipes" New topic
Author

Blocking FileWriters and Pipes

aantal
Greenhorn

Joined: Apr 10, 2001
Posts: 3
Hi all -
Perhaps someone could help me with a little bit of a possible FileWriter problem...
I am using a FileWriter to write to a log file. This filewriter is used in a separate logging thread, and other threads (servlets) communicate with the logging thread via a Pipe.
Occasionally I get a bizarre case where everthing hangs, and I think it is a condition where the filewriter blocks for some reason, and the logger stops reading from the pipe, and the servlets eventually fill up the pipe, so they all become blocked...nasty!
So I would be greatly appreciative if someone could shed some light on when/how a filewriter might block, and also when reading from a pipe (which is wrapped as follows
new BufferedReader(new InputStreamReader(new DataInputStream(inPipe)));
The log is being written on a unix platform if it makes any difference.
I have been trying to track this down for a week now, so any help would be appreciated.
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
"aantal",
The Java Ranch has thousands of visitors every week, many with surprisingly similar names. To avoid confusion we have a naming convention, described at http://www.javaranch.com/name.jsp . We require names to have at least two words, separated by a space, and strongly recommend that you use your full real name. Please log in with a new name which meets the requirements.
Thanks.


Read about me at frankcarver.me ~ Raspberry Alpha Omega ~ Frank's Punchbarrel Blog
Scott Alan
Greenhorn

Joined: Jun 12, 2001
Posts: 4
Ok, name changed. If anyone has any ideas whatsoever they would be greatly appreciated...
Cindy Glass
"The Hood"
Sheriff

Joined: Sep 29, 2000
Posts: 8521
Without SOME code to look at this might be pretty hard to diagnose.


"JavaRanch, where the deer and the Certified play" - David O'Meara
Scott Alan
Greenhorn

Joined: Jun 12, 2001
Posts: 4
There is a lot of code in this system, but below are what I believe are the relavent parts. I know the indention is all hosed - for some reason pasting from JBuilder loses all my indentions...
<code>
protected LogManager()
{
// initialize the pipes
try
{
outPipe = new PipedOutputStream();
inPipe = new PipedInputStream(outPipe);
outBuffer = new BufferedWriter(new OutputStreamWriter(new DataOutputStream(outPipe))); // wrap the pipe with a writer
inBuffer = new BufferedReader(new InputStreamReader(new DataInputStream(inPipe))); // wrap the pipe with a reader
}
catch (Exception ex)
{
System.out.println("Failed to initialize pipes in LogManager constructor");
pipeInitSuccessful = false;
}
}
</code>
This is the method used by client threads to write to the log..
<code>
public static void log(int logLevel, String sourceClass, String sourceMethod, String msg)
{
try
{
if (!isInitialized()) { return; } // ensure the logger is ready for a message before sending one
try { sleep(3); } // force main thread to sleep in case it is hogging processor
catch (Exception ex) { } // the thread was interrupted while it was sleeping
// check if there are newlines, replace them with ~ if found, so they can be xferred via pipe
msg = cleanString(msg);
sourceClass = cleanString(sourceClass);
sourceMethod = cleanString(sourceMethod);
synchLog(logLevel, sourceClass, sourceMethod, msg); // all signs say go for logging to the pipe
}
catch (Exception ex)
{
// print an error and stop any further log messages
System.out.println("LogManager.log(): exception thrown trying to log message" + ex);
setInitialized(false);
}
}
public static synchronized void synchLog(int logLevel, String sourceClass, String sourceMethod, String msg)
{
try
{
outBuffer.write(String.valueOf(logLevel) + "\n"); // send the log level to the log manager
outBuffer.write(sourceClass + "\n"); // send the source class to the log manager
outBuffer.write(sourceMethod + "\n"); // send the source method to the log manager
outBuffer.write(msg + "\n"); // send the message to the log manager
outBuffer.flush(); // flush to make sure that the values are written to the pipe
}
catch (Exception ex)
{
// print an error and stop any further log messages
System.out.println("LogManager.synchLog(): exception thrown trying to write to pipe " + ex);
setInitialized(false);
}
}
</code>
The run method for the thread...
<code>
public void run()
{
if (!pipeInitSuccessful) { return; } // check to make sure that the inbuffer was initialized properly
if (!hasListeners()) { return; } // if there are not any listeners, then you won't be able to add them after the manager is running...
isMgrStarted = true;
isInitialized(true);
try
{
while (!interrupted())
{
// check the pipe...
if (inBuffer.ready())
{
pipeReadAndLog();
}
//sleep to allow other threads to run
sleep(5);
}
}
catch (InterruptedException ex)
{ // thread was interrupted during sleep or wait, this is a signal for the log to die
// if there is anything left in the pipe, log it, and then die.
try
{
System.out.println("LogManager: cleaning out residual log messages in pipe...");
int i = 0;
boolean readMoreFromPipe = true;
while ( (inBuffer.ready()) && (readMoreFromPipe) )
{
i++;
pipeReadAndLog();
if (i > maxResidualEntries) {readMoreFromPipe = false;} // do not sit here forever
}
}
catch (Exception innerEx)
{
System.out.println("LogManager.run(): Exception while trying to clean out residual log messages in pipe..." + innerEx);
}
}
catch (Exception ex)
{
// some other exception was thrown, meaning an error..., so print a message and then stop the log from continuing to run.
System.out.println("LogManager.run(): Exception thrown while reading and logging messages: " + ex);
setInitialized(false);
}
finally
{
// make sure that the other listeners are ended properly if the urn method bombs, or when the Log thread is told to close
// so that the logs are closed properly and not left in a junk state
end();
}
}
</code>
The method which writes the message to the file:
<code>
private boolean writeToFile(String msg)
// This method will just attempt to write a string to the file, and log a message if it fails.
{
boolean successful = true; // flag indicating the success of the write
try
{
fw.write(msg + "\r\n");
fw.flush();
}
catch (IOException ex)
{
System.out.println("FileLogWriter:writeToFile() - Unable to write message to log '" + filePath + fileName + "' Exception:" + ex.getMessage());
successful = false;
}
return successful;
} // end writeToFile method
</code>
The method which reads from the pipe
<code>
private void pipeReadAndLog() throws Exception
{
int pipedLevel; // the logging level, as read from the pipe
String pipedClass; // the logged class, as read from the pipe
String pipedMethod; // the logged method, as read from the pipe
String pipedMsg; // the logged message, as read from the pipe
pipedLevel = Integer.parseInt(inBuffer.readLine());
pipedClass = inBuffer.readLine();
pipedMethod = inBuffer.readLine();
pipedMsg = inBuffer.readLine();
//go ahead and log the message
localLog(pipedLevel, pipedClass, pipedMethod, pipedMsg);
}
</code>
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Blocking FileWriters and Pipes