ProcessBuilder just hangs and does not complete. I have seen the numerous articles posted about this, but I still have been unsuccessful at resolving this. Can anyone see an issue with this or have a suggestion?
I'm attempting to execute a batch file that mail-enables users on active directory.
CODE:
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("TEST");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("Starting process");
ProcessBuilder pb = new ProcessBuilder(
"cmd.exe",
"/C",
"Y:\\mail-enable-users-groups.bat");
Process process = null;
try
{
process = pb.start();
ProcessOutputThread t = new ProcessOutputThread(process.getInputStream(), new StringBuffer());
t.start();
process.waitFor();
t.interrupt();
}
catch (IOException e1)
{
e1.printStackTrace();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("Process ended");
}
});
frame.add(button);
}
private static class ProcessOutputThread extends Thread
{
private StringBuffer m_output;
private InputStream m_inputStream;
public ProcessOutputThread(InputStream inputstream, StringBuffer output)
{
super( "ProcessOutputThread" );
m_inputStream = inputstream;
m_output = output;
}
@Override
public void run() {
byte[] buffer = new byte[ 8192 ];
try {
while( true )
{
int available = m_inputStream.available();
if( available == 0 )
{
try
{
Thread.sleep( 100 );
}
catch( InterruptedException e )
{
break;
}
continue;
}
int len = Math.min( buffer.length, available );
len = m_inputStream.read( buffer, 0, len );
String outString = new String( buffer, 0, len );
m_output.append( outString );
System.out.println(outString);
}
}
catch( IOException e )
{
e.printStackTrace();
}
}
}
BATCH FILE:
PowerShell.exe -command ". 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; Get-User -RecipientTypeDetails User -Filter { UserPrincipalName -ne $Null } | Enable-Mailbox
OUTPUT:
Y:\>PowerShell.exe -command ". 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; Get-User -RecipientTypeDetails User -Filter { UserPrincipalName -ne $Null } | Enable-Mailbox
You are waiting for your process, but the process generates some output and quite soon blocks until you read that output. It's a dead lock you have to solve by reading the output before calling p.waitFor().
It's a bit tricky to handle the output, because you have to wait for it. In the first iteration of your loop there is probably no output because your external program needs some time to generate it. So readline() will return null and your program will exit.
In the past I handled these situations by spawning a thread that reads the output. In the main thread I did a p.waitFor() like you did it.
I'd recommend to use apache exec instead of handling this be yourself.
Update: If you have to do it by your own, here is the way:
Start a separate thread and read the output. Don't stop reading. In your main thread call p.waitFor() and after that call join() on your thread. When catching an InterruptedException inside your thread, make sure you read all available output up to the end and then terminate your thread.
Example code:
private static class C_ProcessOutputThread extends Thread {
private StringBuffer m_output;
private InputStream m_inputStream;
public C_ProcessOutputThread(
InputStream inputstream,
StringBuffer output
) {
super( "ProcessOutputThread" );
m_inputStream = inputstream;
m_output = output;
}
@Override
public void run() {
byte[] buffer = new byte[ 8192 ];
try {
while( true ) {
int available = m_inputStream.available();
if( available == 0 ) {
try {
Thread.sleep( 100 );
}
catch( InterruptedException e ) {
break;
}
continue;
}
int len = Math.min( buffer.length, available );
len = m_inputStream.read( buffer, 0, len );
String outString = new String( buffer, 0, len );
m_output.append( outString );
}
}
catch( IOException e ) {
e.printStackTrace();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With