Chetna
Chetna

Reputation: 864

Continuous response from perl to java program

I don't know if it is possible, but thougt of giving it a try.
I am executing a small perl code within my java program like this

private void executePerlCode() {
    Process process;
    ProcessBuilder processBuilder;
    BufferedReader bufferedReader = null;
    try {
        // this line is used to execute the perl program
        processBuilder = new ProcessBuilder("perl", "D:\\test\\loop.pl");
        process = processBuilder.start();

        // To get the output from perl program
        bufferedReader = new BufferedReader(new InputStreamReader(
                process.getInputStream()));
        String line;
        StringBuffer str = new StringBuffer();
        while ((line = bufferedReader.readLine()) != null) {
            str.append(line);
            System.out.println(line);
        }
        // process.waitFor();

        // Set the output on the textfield
        // jTextArea1.setText(str.toString());

    } catch (Exception e) {
        System.out.println("Exception: " + e.toString());
    } finally {
        try {
            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

And my perl code is

for (my $i=0; $i <= 9; $i++) {
print "$i\n";
sleep(1);
}

I am able to get the output of perl program in my java program. But I want the perl code to give continuous output to java code. Like this, when the loop in perl prints value of 'i' for first time, I should be able to get that value in Java code. So that I can continuously update my Java UI according to the process going on in Perl code.

Upvotes: 2

Views: 576

Answers (1)

subie
subie

Reputation: 335

There are two parts to this:

  1. Making sure that the Perl output is not buffered so output is immediately available
  2. Making Java continuously read from Perl.

To ensure that the Perl output is not buffered you need to add the following line before the for:

STDOUT->autoflush(1);

Making Java continuously read is a little more challenging and the details of the approach will depend on what you intend to do with the output.

Below is an example where all that is required is to redirect the child process's output to the Java's output.

First, a class that extends Thread is required to handle the output of the spawned process:

package com.example;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

public class StreamRedirector extends Thread {

  private InputStream inputStream;
  private OutputStream outputStream;

  public StreamRedirector(InputStream inputStream, OutputStream outputStream) {
    this.inputStream = inputStream;
    this.outputStream = outputStream;
  }

  public void run() {
    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    String line = null;
    try {
      while ((line = bufferedReader.readLine()) != null) {
        outputStreamWriter.write(line + "\n");
        outputStreamWriter.flush();
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

Then the process can be spawned. In this example, the main code immediately waits for the spawned process to exit:

Runtime rt = Runtime.getRuntime();

Process proc;
try {
  proc = rt.exec(command);
} catch (IOException e) {
  throw new CustomException("Failed to execute.", e);
}

StreamRedirector outStreamRedirector = new StreamRedirector(proc.getInputStream(), System.out);
StreamRedirector errStreamRedirector = new StreamRedirector(proc.getErrorStream(), System.err);

outStreamRedirector.start();
errStreamRedirector.start();

int exitVal;
try {
  outStreamRedirector.join();
  errStreamRedirector.join();
  exitVal = proc.waitFor();
} catch (InterruptedException e) {
  throw new CustomException("Failed to execute.", e);
}

Upvotes: 3

Related Questions