Thursday, December 10, 2009

perl & java IPC

recently, i've ran into a situation where i've needed my perl cron script to communicate with java. i did not want to start up a new jvm or create database connections for each call, as this would be very sloppy. below is an example of how to do this.

in this example, perl starts the java process and communicates via standard in/out/err. right now, the java program only provides a useless 'reverse' service, but could be updated to do something more useful. if the java process has any exceptions, it will handle those and exit normally.

Main.java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main{
public static void main(String args[]){
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
boolean running = true;
int processed = 0;

while(running){
try{
String s = in.readLine();
if (s == null || "".equals(s)){
running = false;
}else{
System.out.println(new StringBuffer(s).reverse().toString());
processed++;
}
if (processed == 100) throw new IllegalArgumentException("blah");
}catch(IOException e){
e.printStackTrace();
}
}
System.err.println("successfully processed " + processed);
}
}


pipe.pl

#!/usr/bin/perl -w


use FileHandle;
use IPC::Open3;
use strict;

my $pid = open3(*CHILD_IN, *CHILD_OUT, *CHILD_ERR, "java Main");
CHILD_IN->autoflush();

my $out = "";
my $err = "";
my $i = 0;
for(1..1000000){
$i++;
print CHILD_IN "hello there $i\n";
$out = ;
if (defined $out){
chomp($out);
print("received: $out\n");
}else{
# error handling:
while($err = ){
chomp($err);
print("ERROR: $err\n");
}
last;
}

}

print CHILD_OUT "\n"; # send blank line to stop

# wait for process to end
waitpid($pid, 0);

print("stopping\n");