jbaird123
asked on
Java issue - how to force my code to exit when it hangs
I have a Java method that I use for decrypting files by executing the GPG binary and passing in some parameters (see code sample below).
Sometimes for reasons beyond my control, the file that the program is attempting to decrypt is corrupted and cannot be decrypted. In those cases, I want the program to abort and raise an error. The problem I am having is that the the program often just hangs and never completes - it is as if it were stuck in an infinite loop. So rather than trapping the problem and exiting, the program just sits there and never completes.
Is there any way I can force this program so that it will ALWAYS complete - either successfully or by raising an error?
Thanks.
Sometimes for reasons beyond my control, the file that the program is attempting to decrypt is corrupted and cannot be decrypted. In those cases, I want the program to abort and raise an error. The problem I am having is that the the program often just hangs and never completes - it is as if it were stuck in an infinite loop. So rather than trapping the problem and exiting, the program just sits there and never completes.
Is there any way I can force this program so that it will ALWAYS complete - either successfully or by raising an error?
Thanks.
public static String decryptFile(String gpgBinaryPath, String passphrase,
String decryptedFilePath, String encryptedFilePath) {
//System.out.println("encryptedFilePath: " + encryptedFilePath);
//System.out.println("decryptedFilePath: " + decryptedFilePath);
//System.out.println("gpgBinaryPath: " + gpgBinaryPath);
//System.out.println("passphrase: " + passphrase);
String strExecReturn = "";
String[] cmdArray = new String[] {
gpgBinaryPath,
"--no-tty",
"--yes",
"-q",
"-d",
"--passphrase",
passphrase,
"-o",
decryptedFilePath,
encryptedFilePath };
java.lang.Runtime runtime = java.lang.Runtime.getRuntime();
java.lang.Process ps = null;
try
{
ps = runtime.exec(cmdArray);
} //end try
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}//end catch - IOException
try
{
int exitStatus = ps.waitFor();
//System.out.println ("exit Status = "+exitStatus);
if(exitStatus!=0)
{
InputStream e = ps.getErrorStream();
String error = "";
BufferedInputStream bre = new BufferedInputStream(e);
try
{
int readInt = bre.read();
System.out.println ("readInt = "+readInt);
while (readInt != -1)
{
char c = (char) readInt;
error = error + c;
readInt = bre.read();
}//end while
}//end try
catch (IOException e1)
{
e1.printStackTrace();
}//end catch
System.out.println("ERROR_COMMAND "+ error);
strExecReturn = "ERROR:"+error;
throw new Exception("Some problem while copying - "+error);
}//end if
else if(exitStatus==0)
{
strExecReturn = "SUCCESS";
}//end else if
}//end try
catch (java.lang.InterruptedException e)
{
System.out.println("EXCEPTION_TRACE "+ e);
e.printStackTrace();
}//end catch - InterruptedException
catch(Throwable t)
{
t.printStackTrace();
}//end catch - Throwable
//System.out.println("Hello " + message + " !"); //$NON-NLS-1$ //$NON-NLS-2$
return strExecReturn;
}//end method - decryptFile
http://technojeeves.com/joomla/index.php/free/52-runtimeexec
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you, Doug. This was exactly what I needed.
The place where you are potentially waiting forever is here:That's not going to help you really. It's far more likely that your app is what is hanging - for the reason given at my link and sublinks. If it's really the process that's hung then it will be down to a bug in GPG
int exitStatus = ps.waitFor();
I would suggest replacing that with a timeout. Let's say you're willing to wait for at most 5 minutes before deciding the process has hung and aborting.
ASKER
CEHJ,
I looked over the information you gave me, but I'm afraid I am still too new to Java to be able to make sense of it all.
Is it possible to simplify all of that information into a simple call that I can add to my code?
Thanks.
I looked over the information you gave me, but I'm afraid I am still too new to Java to be able to make sense of it all.
Is it possible to simplify all of that information into a simple call that I can add to my code?
Thanks.
CEHJ,
I'm not convinced that it's hanging due to his reading of the error stream. I think the only place that could happen (if it was an issue with reading the streams) is here:
int readInt = bre.read();
But that shouldn't block when reading an error stream after the process has terminated. If it did that would be a pretty nasty bug in the JDK wouldn't it?
I think the links you posted are more to solve the problem of how to read the output stream and the error stream while a process is running (a thorny problem). But that doesn't seem to apply here?
Doug
I'm not convinced that it's hanging due to his reading of the error stream. I think the only place that could happen (if it was an issue with reading the streams) is here:
int readInt = bre.read();
But that shouldn't block when reading an error stream after the process has terminated. If it did that would be a pretty nasty bug in the JDK wouldn't it?
I think the links you posted are more to solve the problem of how to read the output stream and the error stream while a process is running (a thorny problem). But that doesn't seem to apply here?
Doug
I don't know what the sequence of events is here. In almost all cases, hanging with Runtime.exec is caused by not consuming process streams in separate threads.
Of course, if the gpg code is problematic when run outside java, then it could be that the process itself is a problem. I didn't get that impression, If that's the case, i missed it
Of course, if the gpg code is problematic when run outside java, then it could be that the process itself is a problem. I didn't get that impression, If that's the case, i missed it