Running perl from java

Greetings all,
I want to execute perl code from within a java application. For example I pass the following command to my java application:

perl somescript.pl args...

This works fine and I am able to capture the script's output in my java code. However if I use the "-e" command-line option, the perl program is successfully executed but my java program shows that no output is produced. For example:

perl -e "print \"Hello World\""

My guess is that the perl interpreter works differently with the "-e" option than it does when reading and executing a perl script. I would like someone to tell me how to run a perl program using the "-e" option and capture its output in my java code. I am running perl 5.8.6 for MSwin32-x86-multi-thread on Microsoft Windows 2000 Version 5.00.2195 and Sun Microsystems java version 1.6.0_21

Now I have a problem. I am currently writing an article on the use of Runtime.exec() and ProcessBuilder that goes beyond the 'traps' article. My article is not very high powered but one section in my article relates to 3 ways to run Perl programs from Java but if I post any of my example code here or even a URL to the early draft it is likely to be 'moderated'. Sorry!

You are likely falling for one or more of the traps elaborated in the 4 sections of 'traps'. Read the article and implement ALL of the recommendations. Failure to do so will leave you very frustrated.

Retired horse trader.
Note: double-underline links may be advertisements automatically added by this site and are probably not endorsed by me.

Jimmy Clark wrote:Have Perl program write output to a temporary file and then have following Java code read the file.

Ouch! Why would one do that when the Perl stdout is available to the Java Process? All one has to do is to read the traps article to see how to access the Process stdout and to do a 'man perl' to see the options available for presenting the Perl script to Perl.

Jimmy Clark wrote:Have Perl program write output to a temporary file and then have following Java code read the file.

Ouch! Why would one do that when the Perl stdout is available to the Java Process? All one has to do is to read the traps article to see how to access the Process stdout and to do a 'man perl' to see the options available for presenting the Perl script to Perl.

If I understand Avi's post correctly (but correct me if I am wrong), he already knows how to do that and is doing it successfully, except when the use of the -e option causes it to not work.

Paul Clapham wrote: If I understand Avi's post correctly (but correct me if I am wrong), he already knows how to do that and is doing it successfully, except when the use of the -e option causes it to not work.

The '-e' command works perfectly for me on Windows using Active Perl, Linux Ubuntu, OS-X and OpenSolaris. The important point is to avoid ALL the traps exposed in the traps article.

I know of 3 ways one can present the Perl script. One can place it in a file, one can use the '-e' flag so that the script is taken as the next command line argument and one can pipe it to Perl's stdin. All work well as long as one avoids the traps.

James Sabre wrote:Read the article and implement ALL of the recommendations. Failure to do so will leave you very frustrated.

I have read the article and I am implementing all of its recommendations.
When I pass the name of a perl script, it works without any problems.
When I use the "-e" flag, I get no output via the process's standard output stream.
I will investigate how to pipe the script to perl's standard input.
(Unless you care to enlighten me here.)

James Sabre wrote:Read the article and implement ALL of the recommendations. Failure to do so will leave you very frustrated.

I have read the article and I am implementing all of its recommendations.
When I pass the name of a perl script, it works without any problems.
When I use the "-e" flag, I get no output via the process's standard output stream.
I will investigate how to pipe the script to perl's standard input.
(Unless you care to enlighten me here.)

After making sure one is not falling for any of the 'traps', the biggest problem one finds using the '-e' approach to provide the script is the hell caused by quoting quotes. To get your "Hello World" working you need :-

I have just tested this with the latest Strawberry Perl and Active State Perl 5.12.2 and it work perfectly. Funnily enough this excessive quoting is not always necessary on Linux but it does mean that it is difficult to create a '-e' script that works on both Windows and Linux.

This 'quotes hell' means that using the '-e' approach is my last resort. I prefer to pipe the script to the Process stdin. I do this by writing the script to the OutputStream obtained from Process.getOutputStream() . If you don't want to merge the the Process stdout and stderr then you need 3 threads. One to process stdout, one to process stderr and one to write the script to the process stdin. For one of these threads you can use the thread being used to create the Process object i.e. the thread you use for Process process = pb.start(). Since I am normally concerned with parsing stdout I normally use this one to process stdout and create separate threads to process stderr and stdin. If one is using this with Swing then unless the script is very large it is usually better to write the script to stdin in the pb.start() thread (the event thread).

When you have written the script to the stdin remember to close it!

Note my use of ProcessBuilder rather than Runtime.exec(). Behind the scenes Runtime.exec() uses ProcessBuilder so they are equivalent but the ProcessBuilder interface is better. Note also that I don't use the single string approach to providing the command. Behind the scenes Java converts this to the String array version by splitting the String on one or more white space. This causes very serious problems on Linux but less serious on Windows; still best not to do it.