I am trying to use Process.waitFor() to wait until mysqldump finishes its backup process. Here is my code.
///i use this mysql command, its working fine
String dump = "bkprefs/mysqldump "
+ "--host=localhost "
+ "--port=3306 "
+ "--user=root "
+ "--password= "
+ "--add-drop-table "
+ "--add-drop-database "
+ "--complete-insert "
+ "--extended-insert "
+ "test";
//execute the command
Process run = null;
try {
run = Runtime.getRuntime().exec(dump);
int stat = run.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
The problem is that, run.waitfor() hangs. It seems like it keeps on waiting for something that will not happen.
When I replace the line int stat = run.waitFor() with Thread.sleep(5) the backup is working fine. But I can't stick to this because backing up time will vary depending on the size of the database so using Thread.sleep to wait for backup process to finish is not safe.
Please help me. Replies are greatly appreciated.
Edit :
I consume its inputstream using the following code.
InputStream in = run.getInputStream();
FileWriter fstream = null;
try {
fstream = new FileWriter("haha.sql");
} catch (IOException ex) {
ex.printStackTrace();
}
BufferedWriter out = new BufferedWriter(fstream);
int nextChar;
StringBuffer sb = new StringBuffer();
try {
while ((nextChar = in.read()) != -1) {
out.write((char) nextChar);
//sb.append((char) nextChar);
}
out.flush();
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
you need to consume the output streams from the sub process. This article details everything you need to do to use Process successfully. (also, this has probably been answered many times on stackoverflow already).
mysqldump dumps to stdout. You might want read it the stream, or use option -r redirecting the output.
Related
I am trying to figure out why my inputFile.delete() will not delete the file. After looking at numerous topics it looks like something is still using the file and hence it won't delete. But I can't figure it out. What am I missing??
File inputFile = new File("data/Accounts.txt");
File tempFile = new File("data/tmp.txt");
try {
tempFile.createNewFile();
BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
String line;
int i = 0;
for (User u : data) {
String toRemove = getIDByUsername(username);
while ((line = reader.readLine()) != null) {
if (line.contains(toRemove + " ")) {
line = (i + " " + username + " " + getStatusByUsername(username) + " " + password);
}
writer.write(line + "\n");
i++;
}
}
reader.close();
writer.close();
} catch (FileNotFoundException e) {
ex.FileNotFound();
} catch (IOException ee) {
ex.IOException();
} finally {
inputFile.delete();
tempFile.renameTo(inputFile);
}
You can have that much shorter and easier by using java.nio:
public static void main(String[] args) {
// provide the path to your file, (might have to be an absolute path!)
Path filePath = Paths.get("data/Accounts.txt");
// lines go here, initialize it as empty list
List<String> lines = new ArrayList<>();
try {
// read all lines (alternatively, you can stream them by Files.lines(...)
lines = Files.readAllLines(filePath);
// do your logic here, this is just a very simple output of the content
System.out.println(String.join(" ", lines));
// delete the file
Files.delete(filePath);
} catch (FileNotFoundException fnfe) {
// handle the situation of a non existing file (wrong path or similar)
System.err.println("The file at " + filePath.toAbsolutePath().toString()
+ " could not be found." + System.lineSeparator()
+ fnfe.toString());
} catch (FileSystemException fse) {
// handle the situation of an inaccessible file
System.err.println("The file at " + filePath.toAbsolutePath().toString()
+ " could not be accessed:" + System.lineSeparator()
+ fse.toString());
} catch (IOException ioe) {
// catch unexpected IOExceptions that might be thrown
System.err.println("An unexpected IOException was thrown:" + System.lineSeparator()
+ ioe.toString());
}
}
This prints the content of the file and deletes it afterwards.
You will want to do something different instead of just printing the content, but that will be possible, too ;-) Try it...
I am trying to figure out why my inputFile.delete() will not delete the file.
That's because the old file API is crappy specifically in this way: It has no ability to tell you why something is not succeeding. All it can do, is return 'false', which it will.
See the other answer, by #deHaar which shows how to do this with the newer API. Aside from being cleaner code and the newer API giving you more options, the newer API also fixes this problem where various methods, such as File.delete(), cannot tell you the reason for why it cannot do what you ask.
There are many, many issues with your code, which is why I strongly suggest you go with deHaar's attempt. To wit:
You aren't properly closing your resources; if an exception happens, your file handlers will remain open.
Both reading and writing here is done with 'platform default encoding', whatever that might be. Basically, never use those FileReader and FileWriter constructors. Fortunately, the new API defaults to UTF_8 if you fail to specify an encoding, which is more sensible.
your exception handling is not great (you're throwing away any useful messages, whatever ex.FileNotFound() might be doing here) - and you still try to delete-and-replace even if exceptions occur, which then fail, as your file handles are still open.
The method should be called getIdByUsername
Your toRemove string is the same every time, or at least, the username variable does not appear to be updated as you loop through. If indeed it never updates, move that line out of your loop.
I'm having a problem calling some simple command line functions with r.exec - for some reason, given a file X the command
'echo full/path/to/X' works fine (both in the display and with 'p.exitValue()==0', but 'cat full/path/to/X' does not (and has 'p.exitValue()==1') - both 'cat' and 'echo' live in /bin/ on my OSX - am I missing something? Code is below (as it happens, any suggestions to improve the code generally are welcome...)
private String takeCommand(Runtime r, String command) throws IOException {
String returnValue;
System.out.println("We are given the command" + command);
Process p = r.exec(command.split(" "));
InputStream in = p.getInputStream();
BufferedInputStream buf = new BufferedInputStream(in);
InputStreamReader inread = new InputStreamReader(buf);
BufferedReader bufferedreader = new BufferedReader(inread);
// Read the ls output
String line;
returnValue = "";
while ((line = bufferedreader.readLine()) != null) {
System.out.println(line);
returnValue = returnValue + line;
}
try {// Check for failure
if (p.waitFor() != 0) {
System.out.println("XXXXexit value = " + p.exitValue());
}
} catch (InterruptedException e) {
System.err.println(e);
} finally {
// Close the InputStream
bufferedreader.close();
inread.close();
buf.close();
in.close();
}
try {// should slow this down a little
p.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
return returnValue;
}
You should be consuming stdout and stderr asynchronously.
Otherwise it's possible for the output of the command to block the input buffers and then everything grinds to a halt (that's possibly what's happening with your cat command since it'll dump much more info than echo).
I would also not expect to have to call waitFor() twice.
Check out this SO answer for more info on output consumption, and this JavaWorld article for more Runtime.exec() pitfalls.
I am running a java application from the console on an HP-UX machine. In it, I generate some reports, zip them, and then email them. Everything is working, except the email.
I am using the mail binary to send mail from the command line. Since it's HP-UX, it's a bit different than the standard GNU sendmail.
This is the code I'm using to send the mail:
public static void EmailReports(String[] recipients, String reportArchive, String subject){
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
String today = dateFormat.format(new Date());
File tempEmailFile;
BufferedWriter emailWriter;
try {
tempEmailFile = File.createTempFile("report_email_" + today, "msg");
emailWriter = new BufferedWriter(new FileWriter(tempEmailFile));
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not create temporary file.");
return;
}
try {
emailWriter.write("SUBJECT: " + subject + "\n");
emailWriter.write("FROM: " + FROM + "\n");
emailWriter.write(BODY + "\n");
emailWriter.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not write to temporary file.");
}
//read the archive in
try {
FileInputStream archiveIS = new FileInputStream(new File(reportArchive));
OutputStream archiveEncoder = MimeUtility.encode(new FileOutputStream(tempEmailFile, true), "uuencode", Zipper.getArchiveName(reportArchive));
//read archive
byte[] buffer = new byte[archiveIS.available()]; //these should never be more than a megabyte or two, so storing it in memory is no big deal.
archiveIS.read(buffer);
//encode archive
archiveEncoder.write(buffer);
//close both
archiveIS.close();
archiveEncoder.close();
} catch (FileNotFoundException e) {
System.out.println("Failed to send email. Could not find archive to email.");
e.printStackTrace();
} catch (MessagingException e) {
System.out.println("Failed to send email. Could not encode archive.");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not encode archive.");
}
System.out.println("Sending '" + subject + "' email.");
try {
Process p = Runtime.getRuntime().exec("mail me#example.com < " + tempEmailFile.getAbsolutePath());
System.out.println("mail me#example.com < " + tempEmailFile.getAbsolutePath());
StringBuffer buffer = new StringBuffer();
while(p.getErrorStream().available() > 0){
buffer.append((char) p.getErrorStream().read());
}
System.out.println("STDERR: " + buffer.toString());
buffer = new StringBuffer();
while(p.getInputStream().available() > 0){
buffer.append((char) p.getInputStream().read());
}
System.out.println("STDOUT: " + buffer.toString());
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not get access to the shell.");
}
}
When I run the program, and it sends the email, I get a blank email, no subject, no body, no attachment, and it's from the user#hostname from the HP-UX box instead of from the email specified in FROM.
However, when I run the same line that it runs (see the command printed out after I call exec), I get the correct email, from the correct user, with a subject, body, and attachment.
STDOUT and STDERR are both empty. It's almost as if I'm sending mail a blank file, but when I print the file before I call the exec, it's there.
What's going on here?
Edit: Attempts made:
Using Ksh:
try {
String cmd = "mail me#example.com.com < " + tempEmailFile.getAbsolutePath();
Runtime.getRuntime().exec(new String[] {"/usr/bin/ksh", cmd});
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not get access to the shell.");
}
Using STDIN:
try {
System.out.println("mail me#example.com < " + tempEmailFile.getAbsolutePath());
Process p = Runtime.getRuntime().exec("mail me#example.com ");
FileInputStream inFile = new FileInputStream(tempEmailFile);
byte[] byteBuffer = new byte[inFile.available()];
inFile.read(byteBuffer);
p.getOutputStream().write(byteBuffer);
inFile.close();
p.getOutputStream().close();
StringBuffer buffer = new StringBuffer();
while(p.getErrorStream().available() > 0){
buffer.append((char) p.getErrorStream().read());
}
System.out.println("STDERR: " + buffer.toString());
buffer = new StringBuffer();
while(p.getInputStream().available() > 0){
buffer.append((char) p.getInputStream().read());
}
System.out.println("STDOUT: " + buffer.toString());
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not get access to the shell.");
}
I strongly suspect the problem is the redirection. That's normally handled by the shell - and there's no shell here.
Either you need to execute the process normally and then get the process's standard input stream and write to it from Java, or (probably simpler) run /bin/sh (or whatever) to get the shell to do the redirection.
Try exec'ing { "ksh", "-c", "mail me#example.com < " + etc }. The -c option tells the shell specifically to parse the next argument as a shell command with possible redirection and so on. Without the -c, ksh follows a heuristic to decide what to do with its command line, and it may not be running the command in the way you want it to.
Split into two lines, just to get better readability:
String cmd = "mail me#example.com < " + tempEmailFile.getAbsolutePath () ;
Process p = Runtime.getRuntime().exec (cmd);
This will look for a program named "mail me#example.com < " + tempEmailFile.getAbsolutePath (). It will not do redirection - for that to do you have to read the output of that process yourself.
Furtermore it will not lookup the path, so you might have to specify the whole path /usr/bin/mail or whatever it is.
And you have to split command and parameters; use an Array of String instead: ("/path/to/prg", "param1", "param2", "foo=bar");
You can use redirection, if you call as program a script, like
String cmd = "/usr/bin/mail me#example.com < " + tempEmailFile.getAbsolutePath () ;
String cmdarr = new String [] {"/bin/bash", "-c", cmd};
Process p = Runtime.getRuntime().exec (cmdarr);
It is shorter than invoking file redirection from Java yourself, more simple but you lose the ability to react sensible on different errors.
I want to run OSGi framework on another computer (in a main method). So I wanted to know is there any way to connect to the OSGi console from the other computer and manage bundles?
I thought maybe using a java.net.Socket would help, and that's how I implemented that. I've used 2 threads. one for processing user input stream, and the other one that processes OSGi Console response. This is the first thread (processes user input stream):
configMap.put("osgi.console", "6666");
Framework fwk = ff.newFramework(configMap);
try {
fwk.start();
} catch (BundleException e) {
e.printStackTrace();
}
//__________________________________________________________________//
try {
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
Socket socket = new Socket(InetAddress.getByName("0.0.0.0"), 6666);
printlnInfo("Socket has been created: " + socket.getInetAddress() + ":" + socket.getPort());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
ConsoleOutputReciever fr = new ConsoleOutputReciever();
new Thread(fr).start();
while (true) {
String userInput = "";
while ((userInput = stdIn.readLine()) != null) {
System.out.println("--> " + userInput);
out.write(userInput + "\n");
out.flush();
}
System.out.println("2");
}
} catch (Exception e1) {
e1.printStackTrace();
}
This is the second thread (processes OSGi Console response):
public class ConsoleOutputReciever implements Runnable {
public Scanner in = null;
#Override
public void run() {
printlnInfo("ConsoleOutputReciever Started");
try {
Socket socket = new Socket(InetAddress.getByName("0.0.0.0"), 6666);
printlnInfo("Socket has been created: " + socket.getInetAddress() + ":" + socket.getPort());
String osgiResponse = "";
in = new Scanner(socket.getInputStream());
try {
while (true) {
in = new Scanner(socket.getInputStream());
while (in.hasNext()) {
System.out.println("-- READ LOOP");
osgiResponse = in.nextLine();
System.out.println("-- " + osgiResponse);
}
}
} catch (IllegalBlockingModeException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
but I only receive the first response of the OSGi console. like this:
--READ LOOP
--
--READ LOOP
ss
--> ss
Any ideas about the problem or any other way to connect to OSGi console remotely?
you are using blocking io, thus your inner while loop will never finish until the socket is closed. you need 2 threads to accomplish this with blocking io streams. 1 thread reads from stdin and writes to the socket output stream, the other thread reads from the socket input stream and writes to stdout.
also, you probably want to write a newline after sending the userInput to the osgi console (Scanner.nextLine() eats the newline).
lastly, you don't generally want to use the Print* classes when working with sockets as they hide IOExceptions.
Instead of building your own thing you might want to use one of the remote shells that are available, for example the Apache Felix one at http://felix.apache.org/site/apache-felix-remote-shell.html
NOTE: Coming back to this later as I've been unable to find a working solution. Draining the input streams manually instead of using BufferedReaders doesn't seem to help as the inputStream.read() method permanently blocks the program. I placed the gpg call in a batch file, and called the batch file from Java to only get the same result. Once gpg is called with the decrypt option, the input stream seems to become inaccessible, blocking the entire program. I'll have to come back to this when I have more time to focus on the task. In the mean time, I'll have to get decryption working by some other means (probably BouncyCastle).
The last option to probably try is to call cmd.exe, and write the command through the input stream generated by that process...
I appreciate the assistance on this issue.
I've been working on this problem for a couple days and haven't made any progress, so I thought I'd turn to the exeprtise here for some help.
I am creating a simple program that will call GnuPG via a Java runtime process. It needs to be able to encrypt and decrypt files. Encryption works, but I'm having some problems decrypting files. Whenever I try to decrypt a file, the process hangs.exitValue() always throws it's IllegalThreadStateException and the program chugs along as if it's still waiting. The code for these methods is attached below. The ultimate goal of the program is to decrypt the file, and parse it's contents in Java.
I've tried three approaches to getting the gpgDecrypt method to work. The first approach involved removing the passphrase-fd option and writing the passphrase to gpg via the gpgOutput stream in the catch block, assuming it was prompting for the passphrase like it would via the command line. This didn't work, so I put the passphrase in a file and added the -passphrase-fd option. In this case, the program repeats infinitely. If I write anything via the gpgOutput stream the program will complete. The Exit value printed will have a value of 2, and the result variable will be blank.
The third option is BouncyCastle, but I'm having problems getting it to recognize my private key (which is probably a separate post all together).
The keys I'm using to encrypt and decrypt are 4096-bit RSA keys, generated by GnuPG. In both cases using the passphrase and the passphrase file, I've tried piping the output to a file via > myFile.txt, but it doesn't seem to make any difference.
Here are the gpgEncrypt, gpgDecrypt and getStreamText methods. I posted both since the encrypt works, and I can't see any glaring differences between how I'm executing and handling the process between the encrypt and decrypt methods. getStreamText just reads the contents of the streams and returns a string.
EDIT: Quick note, Windows environment. If I copy the decrypt command output, it works via the console just fine. So I know the command is valid.
public boolean gpgEncrypt(String file, String recipient, String outputFile){
boolean success = true;
StringBuilder gpgCommand = new StringBuilder("gpg --recipient \"");
gpgCommand.append(recipient).append("\" --output \"").append(outputFile).append("\" --yes --encrypt \"");
gpgCommand.append(file).append("\"");
System.out.println("ENCRYPT COMMAND: " + gpgCommand);
try {
Process gpgProcess = Runtime.getRuntime().exec(gpgCommand.toString());
BufferedReader gpgOutput = new BufferedReader(new InputStreamReader(gpgProcess.getInputStream()));
BufferedWriter gpgInput = new BufferedWriter(new OutputStreamWriter(gpgProcess.getOutputStream()));
BufferedReader gpgErrorOutput = new BufferedReader(new InputStreamReader(gpgProcess.getErrorStream()));
boolean executing = true;
while(executing){
try{
int exitValue = gpgProcess.exitValue();
if(gpgErrorOutput.ready()){
String error = getStreamText(gpgErrorOutput);
System.err.println(error);
success = false;
break;
}else if(gpgOutput.ready()){
System.out.println(getStreamText(gpgOutput));
}
executing = false;
}catch(Exception e){
//The process is not yet ready to exit. Take a break and try again.
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
System.err.println("This thread has insomnia: " + e1.getMessage());
}
}
}
} catch (IOException e) {
System.err.println("Error running GPG via runtime: " + e.getMessage());
success = false;
}
return success;
}
public String gpgDecrypt(String file, String passphraseFile){
String result = null;
StringBuilder command = new StringBuilder("gpg --passphrase-fd 0 --decrypt \"");
command.append(file).append("\" 0<\"").append(passphraseFile).append("\"");
System.out.println("DECRYPT COMMAND: " + command.toString());
try {
Process gpgProcess = Runtime.getRuntime().exec(command.toString());
BufferedReader gpgOutput = new BufferedReader(new InputStreamReader(gpgProcess.getInputStream()));
BufferedReader gpgErrorOutput = new BufferedReader(new InputStreamReader(gpgProcess.getErrorStream()));
BufferedWriter gpgInput = new BufferedWriter(new OutputStreamWriter(gpgProcess.getOutputStream()));
boolean executing = true;
while(executing){
try{
if(gpgErrorOutput.ready()){
result = getStreamText(gpgErrorOutput);
System.err.println(result);
break;
}else if(gpgOutput.ready()){
result = getStreamText(gpgOutput);
}
int exitValue = gpgProcess.exitValue();
System.out.println("EXIT: " + exitValue);
executing = false;
}catch(IllegalThreadStateException e){
System.out.println("Not yet ready. Stream status: " + gpgOutput.ready() + ", error: " + gpgErrorOutput.ready());
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
System.err.println("This thread has insomnia: " + e1.getMessage());
}
}
}
} catch (IOException e) {
System.err.println("Unable to execute GPG decrypt command via command line: " + e.getMessage());
}
return result;
}
private String getStreamText(BufferedReader reader) throws IOException{
StringBuilder result = new StringBuilder();
try{
while(reader.ready()){
result.append(reader.readLine());
if(reader.ready()){
result.append("\n");
}
}
}catch(IOException ioe){
System.err.println("Error while reading the stream: " + ioe.getMessage());
throw ioe;
}
return result.toString();
}
I forget how you handle it in Java, there are 100 methods for that. But I was stuck with decrypt command itself, it was very helpful, though you didn't need all those quotes and if you wish to decrypt a large file, it goes like this:
gpg --passphrase-fd 0 --output yourfile.txt --decrypt /encryptedfile.txt.gpg/ 0</passwrdfile.txt
Have you tried to run that command from command-line, not from Java code?
There can be an issue with 'for your eyes only' option, when GnuPG will wait for console output.
This may or may not be the problem (in the decrypt function)
BufferedReader gpgOutput = new BufferedReader(new InputStreamReader(gpgProcess.getInputStream()));
BufferedReader gpgErrorOutput = new BufferedReader(new InputStreamReader(gpgProcess.getInputStream()));
BufferedWriter gpgInput = new BufferedWriter(new OutputStreamWriter(gpgProcess.getOutputStream()));
You are wrapping the result of getInputStream twice. Obviously gpgErrorOutput should be wrapping the error stream, not the input stream.
I stumbled upon this thread today because I was having the exact same issue as far as the program hanging. Cameron's thread from above contains the solution, which is that you have to be draining the inputStream from your process. If you don't, the stream fills up and hangs. Simply adding
String line = null;
while ( (line = gpgOutput.readLine()) != null ) {
System.out.println(line);
}
Before checking the exitValue fixed it for me.
It worked for me when i replace the decrypt command with below command
gpg --output decrypted_file --batch --passphrase "passphrase goes here" --decrypt encrypted_file
int exitValue = gpgProcess.exitValue();
// it gives process has not exited exception
The following code works with GNUPG 2.1.X
public static boolean gpgEncrypt(String file, String recipient,
String outputFile) {
boolean success = true;
StringBuilder gpgCommand = new StringBuilder("gpg --recipient \"");
gpgCommand.append(recipient).append("\" --output \"")
.append(outputFile).append("\" --yes --encrypt \"");
gpgCommand.append(file).append("\"");
System.out.println("ENCRYPT COMMAND: " + gpgCommand);
try {
Process gpgProcess = Runtime.getRuntime().exec(
gpgCommand.toString());
BufferedReader gpgOutput = new BufferedReader(
new InputStreamReader(gpgProcess.getInputStream()));
BufferedWriter gpgInput = new BufferedWriter(
new OutputStreamWriter(gpgProcess.getOutputStream()));
BufferedReader gpgErrorOutput = new BufferedReader(
new InputStreamReader(gpgProcess.getErrorStream()));
boolean executing = true;
while (executing) {
try {
int exitValue = gpgProcess.exitValue();
if (gpgErrorOutput.ready()) {
String error = getStreamText(gpgErrorOutput);
System.err.println(error);
success = false;
break;
} else if (gpgOutput.ready()) {
System.out.println(getStreamText(gpgOutput));
}
executing = false;
} catch (Exception e) {
// The process is not yet ready to exit. Take a break and
// try again.
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
System.err.println("This thread has insomnia: "
+ e1.getMessage());
}
}
}
} catch (IOException e) {
System.err.println("Error running GPG via runtime: "
+ e.getMessage());
success = false;
}
return success;
}
// gpg --pinentry-mode=loopback --passphrase "siv_test" -d -o
// "sample_enc_data_op.txt" "sample_enc_data_input.gpg"
public static String gpgDecrypt(String file, String passphrase,
String outputfile) {
String result = null;
StringBuilder command = new StringBuilder(
"gpg --pinentry-mode=loopback --passphrase \"");
command.append(passphrase).append("\" -d -o \"").append(outputfile)
.append("\" --yes \"").append(file)
.append("\"");
System.out.println("DECRYPT COMMAND: " + command.toString());
try {
Process gpgProcess = Runtime.getRuntime().exec(command.toString());
BufferedReader gpgOutput = new BufferedReader(
new InputStreamReader(gpgProcess.getInputStream()));
BufferedReader gpgErrorOutput = new BufferedReader(
new InputStreamReader(gpgProcess.getErrorStream()));
BufferedWriter gpgInput = new BufferedWriter(
new OutputStreamWriter(gpgProcess.getOutputStream()));
boolean executing = true;
while (executing) {
try {
if (gpgErrorOutput.ready()) {
result = getStreamText(gpgErrorOutput);
System.err.println(result);
break;
} else if (gpgOutput.ready()) {
result = getStreamText(gpgOutput);
}
String line = null;
while ((line = gpgOutput.readLine()) != null) {
System.out.println(line);
}
int exitValue = gpgProcess.exitValue();
System.out.println("EXIT: " + exitValue);
executing = false;
} catch (IllegalThreadStateException e) {
System.out.println("Not yet ready. Stream status: "
+ gpgOutput.ready() + ", error: "
+ gpgErrorOutput.ready());
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
System.err.println("This thread has insomnia: "
+ e1.getMessage());
}
}
}
} catch (IOException e) {
System.err
.println("Unable to execute GPG decrypt command via command line: "
+ e.getMessage());
}
return result;
}
private static String getStreamText(BufferedReader reader)
throws IOException {
StringBuilder result = new StringBuilder();
try {
while (reader.ready()) {
result.append(reader.readLine());
if (reader.ready()) {
result.append("\n");
}
}
} catch (IOException ioe) {
System.err.println("Error while reading the stream: "
+ ioe.getMessage());
throw ioe;
}
return result.toString();
}