1

Can someone help me in the below scenario,

I need to call a perl script from my java code. The perl script is an interactive code, which gets the input from the user during its execution and continues further to end. So, the example I have used is, the perl script when executed asks for the age by printing in the console "How old are you?", when the user enter some value say '26'. Then it prints "WOW! You are 26 years old!".

When I tried calling this script from my java code, the process waits till I give the value as 26 in the outputstream, while in the inputstream there is no value. Then finally when again I read the inputstream, i get the entire output of the script together. So, here can't I make it interactive?

I have went through many forums and blogs, but couldn't locate any, which exactly target my requirement.

Here is the java code

import java.io.*;

public class InvokePerlScript {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Process process;

        try
        {
        process = Runtime.getRuntime().exec("cmd /c perl D:\\sudarsan\\eclips~1\\FirstProject\\Command.pl");

              try {
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
             }
                } catch (IOException e) {
          e.printStackTrace();
                 }

        try {
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
            out.write("23");
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

            process.waitFor();
        if(process.exitValue() == 0)
        {
        System.out.println("Command Successful");
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String line = null;
                while ((line = in.readLine()) != null) {
                System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        else
        {
        System.out.println("Command Failure");
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                String line = null;
                while ((line = in.readLine()) != null) {
                System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        }
        catch(Exception e)
        {
        System.out.println("Exception: "+ e.toString());
        }
    }

}

Perl code is as below

$| = 1;
print "How old are you? \n";
$age = <>;
print "WOW! You are $age years old!";

Thanks in advance, Sudarsan

3
  • Please post the java and perl code that you're using. Commented Mar 3, 2011 at 8:57
  • Sounds like you have a buffering issue. Have you tried setting $| to non-zero in your perl to flush your output? Commented Mar 3, 2011 at 9:19
  • After adding the $|=1 also this didnt work :-( Commented Mar 4, 2011 at 6:49

2 Answers 2

1

Are you calling flush() on the OutputStream in Java after writing the values? If you don't, there's a good chance they'll just be held in the stream's buffer within the Java process, and so never make it to Perl (with the result that both processes end up waiting for the other's IO.)

(Depending on the implementation of the stream this may or may not be necessary, but it certainly wouldn't hurt - and I've been bitten by this in the past. Usually one doesn't need to be as careful, since flushing happens implicitly when close() is called, but here you can't close the stream after you've finished writing.)

Sign up to request clarification or add additional context in comments.

1 Comment

Hi Adrzej, My problem is not with the outputStream. I want to read the data(first print statement in the perl code) in the inputstream and then flush my data back to the outputStream and then finally get the second print statement of the perl code by reading the inputstream again.
1

It looks like you're trying to read a full line in this code:

        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = null;
        while ((line = in.readLine()) != null) {
           ...

However, in your perl code, you are not printing an endline character, so readLine never returns (as per the documentation).

2 Comments

Wow, that's really a good catch. Thanks for that, it makes sense. Now I have modified the perl code to have the endline character and the java code to read the first output line of the perl script. Now I am getting the first print statement in my java console, however the java code didnt proceed further, when I debugged, I found that the main thread keeps on waiting at the line "line = in.readLine()". Please suggest how to get rid of this, I can't use in.close() immediately after reading my first line, b'coz there might be more line after that I want to read.
@sudan, you need to add the logic to deal with the output from the perl script in the while loop, or you'll have to do some threading, with one thread listening for output and one thread funneling the input to perl.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.