最近のJavaEEの傾向というと、言語そのものやEJBやJSFといった技術よりも、(少なくとも同じくらいには)Javaとほかの言語との連携に注目が集まっているように思う。
そこではJavaVMやJavaEEアプリケーションサーバは、ほかの言語が動作するためのプラットフォームとして動作する。ちょうど、Microsoft系でいうところのCLR(Common Language Runtime)のような位置づけといえば良いだろうか。CLRの上ではC#やVisualBasicなどが動く。まぁ、CLR自体がもともとはJavaVMをかなり意識して作られたものだともいえるが。
さて、Javaとほかの言語の連携といえば、私は最近JRubyを試していた。ちょうど仕事がプロトタイプ的な成果物で良かったことも手伝ってGlassfish上でJRuby on Railsのアプリを動かすということをやった。
その勢いに乗ってプライベートでも何かしたいと思い、JavaとPHPの連携について調査した。Quercusというものがあって、それはPure Javaで実装されたPHPエンジンなのだという。具体的に言えば、QuercusServletというサーブレットをTomcatやGlassfishといったアプリケーションサーバ上で動作させ、拡張子がPHPのPHPファイルにマッピングするのだ。
手っ取り早くは、web.xmlを見てもらえれば分かるだろう。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Quercus</display-name>
<welcome-file-list>
<welcome-file>index.php</welcome-file>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.php</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Quercus Servlet</servlet-name>
<servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>
<init-param>
<param-name>ini-file</param-name>
<param-value>WEB-INF/php.ini</param-value>
</init-param>
<!--
<init-param>
<param-name>script-encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
-->
</servlet>
<servlet-mapping>
<servlet-name>Quercus Servlet</servlet-name>
<url-pattern>*.php</url-pattern>
</servlet-mapping>
</web-app>
Quercusを使ってJavaアプリケーションサーバ上で動作するPHP環境を作るには、ちょうどphpinfo()のスクリプトだけが動作するようなほとんど空のwarファイルを作ってディプロイし、展開されたアプリケーションディレクトリの中に動作させたいPHPスクリプトを置いていくというのが手っ取り早い。もちろん、本番運用に持って行くには動作させたいPHPスクリプトを含めたwarファイルを作るべきだとは思うが。
Quercusはcaucho社のアプリケーションサーバResinの中に入っている。Resinはオープンソース版が準備されている(オープンソース版がResin、商用版はResin Pro)ので、そちらのファイルをダウンロードし、Quercusが含まれているJarファイルだけを抜き取り、warファイルの中に入れてしまう。
Resinはここからダウンロードしよう。本エントリーの執筆時点での最新バージョンは4.0.14だった。
ファイルを展開した後、
resin.jar
javamail-141.jar
の2つを、warファイルのWEB-INF/libディレクトリにコピーしよう。
web.xmlファイルは、上記のとおり作成し、warファイルのWEB-INFディレクトに配置する。
注意すべきは日本語の取り扱い。GoogleでQuercusに関する情報を探しているとResin3の頃の情報が多く引っかかる。そこで紹介されているweb.xmlには、サーブレットのinit-paramとして、script-encodingがUTF-8だといういかにもそれっぽい記述があったりする。当然、今回作成するweb.xmlにも書きたくなるわけだが、これを書くと日本語は文字化けする。私は、ここで何時間もはまってしまったのだが、正しい答えはscript-encodingに関しては何も書かないことだ。何も書かなければ文字化けしない。
あと、php.iniについてはinit-paramに書いたことがきちんと反映される。上記の例ではWEB-INFディレクトリにphp.iniを置くことにしているが妥当な選択だと思う。ちなみに、Glassfish(V3)では、PHPスクリプトはホットディプロイになるが、それ以外はwarの再ディプロイかGlassfishの再起動をしないと反映されなかった。あと、php.iniに書いたことがきちんと反映されるかは試していない。ただ、Quercusでphpinfo()をやると、php.iniをどこから読み出したかという出力があるのだが、そこがnullからきちんとphp.iniを配置したディレクトリのフルパス出力に変わった。
MySQLの接続については、WEB-INF/libディレクトリにMySQLのJDBCドライバ(mysql-connector-java-5.1.14-bin.jar)を配置しておこう。mysql_connect()など一連のMySQLアクセスが可能になる。
こうして作成したwarファイルをアプリケーションサーバにディプロイする。たとえば、Glassfishでは管理コンソールで配備するか、/path_to_glassfish/domains/domain1/autodeployに置けばディプロイされる。ディプロイされると、/path_to_glassfish/domains/domain1/applicationsの下にwarファイル名のディレクトリが出来て展開されているので、そこにPHPファイルを置く。たとえば、WordPressのファイルをそのまま配置する。あとは、ふつうにWordPressのインストールプロセスを進めれば良い。
caucho社によれば、QuercusではWordPressやXOOPSといったPHPで作成されたポピュラーなアプリケーションは動作するという。私が試したところだと、WordPressについては動作を確認できた。XOOPSはインストールプロセスの途中でエラーが発生してしまった。私が試したXOOPSは本家版の最新バージョンであるXOOPS2.5.0だったので、例えば本家版でも2.4とか、XOOPS Cube Legacyなら動くかもしれない。(XOOPS Cube LegacyはEUC-JPなのでUTF-8化されたホダ塾ディストリビューションとかの方が良いかも?とか思ったりする。)これは、試してみたらまたここでレポートする。
一方、phpMyAdminはQuercusでは動かないようだ。MySQLとの接続方法がphpMyAdminはDBIを使っているので、その辺が問題ではないかと思う。