Java プログラムと Perl プログラムとの連携に XML-RPCが使えないか検討。 まずは実験。
RPC::XMLモジュールを使う。
#!/usr/bin/perl -w use strict; use RPC::XML::Server; my $server = RPC::XML::Server->new(port => 9876); $server->add_method( {name => 'Perl.eval', signature => [ 'struct string' ], code => sub { warn $_[1]; return {value => eval $_[1]}}}); $server->server_loop;
引数の文字列を eval した結果を文字列で返す危険な手続き。
いろいろライブラリがあり迷う。 Apache XML-RPCが簡単そうなのでまずはこれで。1.2-b1 を使用。
import java.util.Vector; import java.util.Hashtable; import java.io.IOException; import org.apache.xmlrpc.XmlRpcClient; import org.apache.xmlrpc.XmlRpcException; public class XMLRPCClient { public static void main(String[] args) { String url = args[0]; String methodName ="Perl.eval"; Vector params = new Vector(); params.add(args[1]); try { XmlRpcClient client = new XmlRpcClient(url); try { //String result = (String)client.execute(methodName, params); //System.out.println(result); Hashtable result = (Hashtable)client.execute(methodName, params); System.out.println(result.get("value")); } catch (XmlRpcException ex) { System.out.println(ex.getMessage()); } } catch (IOException ex) { ex.printStackTrace(); } } }
Perl 側でプログラムを起動しておいて実行。
java -classpath .:xmlrpc-1.2-b1.jar \ XMLRPCClient http://localhost:9876/ "3 + 5"
8 が出力される。成功。簡単。
Windows の ActiveState 5.6.1 では RPC::XML の make test が通らない。 がっかり。 かわりに、SOAP::Liteに入っている XMLRPC::Lite を使ってみる。
#!/usr/bin/perl -w use strict; use SOAP::Lite +trace => qw(trace); use XMLRPC::Transport::HTTP; my $daemon = XMLRPC::Transport::HTTP::Daemon ->new(LocalPort => 9876) ->dispatch_to('Server'); $daemon->handle; package Server; sub evalcode { warn $_[1]; return +{ value => eval $_[1] }; } 1;
名前の関係から Perl.eval を Server.evalcode に変更した以外は、RPC::XMLの実験の時と一緒。 クライアントは前回の Java プログラム(メソッド名のみ上記のように修正)。
こちらは ActiveState 5.6.1 でも動作。一部ライブラリが warning を出す以外いまのおころ問題無し。Linux 環境でも warning は出る。ライブラリの undefined 扱いの問題のようだ。実害は無さそう。 SOAP::Lite を 0.55 から 0.60a に上げると少し warning が減る(無くならない)。
機能的には RPC::XML の方が使いやすそうだが、SOAP::Lite の方がメジャーという強みがある。ActivePerl 5.6.1 にも標準でバンドルされているし。
既に HTTP::Daemon で作成されているHTTPサーバで、XML-RPC インタフェースを提供したい。 前回のチェックで XMLRPC::Lite を使う事にした(RPC::XML は ActivePerl 5.6.1 build638 でテストが通らない)。 このパッケージで用意されているサーバ向けモジュールは、主に単独CGI プログラムで使うモジュールと、自前で HTTP::Daemon をまわすサーバタイプ。
そのままでは使えないので、以下のように。
handle メソッドで入出力をさせないようにするのがポイント。
Naney (なにい) です。株式会社MIXIで SNS 事業の部長をしています。
※本サイトの内容は個人的見解であり所属組織とは関係ありません。