(FreeBSD)TomcatでServletする(1/2)

  • 投稿日:
  • by
  • カテゴリ:

HTTPのクライアント側で動作する小さなJavaアプリを指すアプレット(applet)と呼ぶが、それに対してサーバー側で動作する小さなJavaアプリを指すサーブレット(servlet)という言葉がある。昔かすかに聞いた覚えはあるが、その後servletなんて言葉はすっかり忘れていた。
先月から興味があってJDBCを勉強し始めているが、その関連の本を読むと、よくServletの話が出てくる。JavaはWebで使われることが多く、データベースをクライアント側で使うことは稀であるから、JDBCはServletで使われることが多い、ということになるのだろうか。

という訳で、このFreeBSDのWebサーバーにServletを動かす環境を作ってみたので、その過程を報告する。

まず必要なソフトであるが、Java開発環境であるJDK、Java動作環境であるJRE(Java VM)は当然として、クライアントの要求を受けてJavaアプリを起動するHTTPサーバーが必要だ。当初はCGIと似たような動作なのでApacheの設定かプラグインでできると思っていたが、過去にはJServというプログラムを使ってそのようなことをしていたようだが、今はTomcatという異なるHTTPサーバーを使うのがオープンソースでは主流のようだ。他にJRunやResinなどがあるが、これらは基本的には商用である。
蛇足だが、現在TomcatはApacheのプロジェクトで開発されているらしい。Jakarta TomcatとApache Tomcatは同じものである。

次に具体的なインストールの方法を記す。

●FreeBSDへのJDKのインストール
JDKにはJREが含まれているので、Java環境としてはJDKだけをインストールすれば良い。
しかし、最初につまづくのが、Sunが配布するJDKには、Linux用のバイナリはあるが、FreeBSD用のバイナリが無いことだ。従って、インストールするバイナリは次の3通りから選択する必要がある。
 (1) JDKのソースコードをコンパイルしてFreeBSD nativeなバイナリを作る
 (2) FreeBSDのLinux emulationによって、Linux用のバイナリを使う
 (3) Sun以外が配布するFreeBSD nativeなバイナリを使う

勿論(3)が一番楽である。FreeBSDのバージョンが5.5以降でJavaのバージョンが(1.4以前でなく)1.5で良いなら、FreeBSD Foundationが配布するDiablo JDKをインストールすれば良い。これはportsを使用してインストールすることもできる。

しかしながら、このサーバーのように、4.x以前のFreeBSDしか動かず(未だ原因不明)、HDDの空き容量が2G以上必要なJDK1.5のコンパイルができない場合は、別の選択をせざるを得ない。

JDK1.4については、(3)のようなバイナリは存在しない。CPUがPentium 150MHzであるこのサーバーでは、(2)のようにしてLinux emulationでLinuxのJREを動かすのでは、動作速度に難があり使い物にならない。
従ってJDK1.4をソースからコンパイルしたいのだが、少なくとも現時点のportsでは、なんとJDK1.4をコンパイルするのに(2)のLinux emulationによるLinuxのJDK1.4が必要になる。そして、portsのMakefileに書かれていたが、LinuxのJDK1.4を動かすには、FreeBSDが5.4以降である必要がある。
ついでに、JDK1.4のMakefileを動かし始めると、コンパイルには1.7GのHDDの作業領域が必要だという注意書きが表示された。このサーバーには0.4Mも空きが無いので、どの道無理であった。

Tomcat 5.5を動かすにはJDK1.4以上が必要なのだが、Tomcat 4.1なら、JDK1.2以上があれば良いので、このサーバーにはJDK1.3を入れることにした。
JDK1.3についても現在は(3)のようなバイナリが存在しない(過去にはDiablo JDKの1.3があったようだ)が、portsを使えば、JDK1.3のソースコードからのコンパイルは、Linuxのバイナリが必要になることも無く、実に簡単にできた。JDK本体のコンパイルはPentium 150MHzでも2~3時間でできたし、HDDの作業領域も300Mで足りた。

●Tomcatのインストール
packages/portsを使えば、特に難しいことは無かった。このサーバーにTomcat 4.1を、別のPCにTomcat 5.5をインストールしたが、どちらもバイナリのインストール自体は容易だった。
敢えて注意すべきことを挙げると、上に書いたことと重複するが、JDKが1.3以前だとTomcat 5.0以降は動かせないことと、packages/portsのパッケージ名ではtomcat??とapache-tomcat??は同じものだということがある。

Tomcatの起動スクリプトは/usr/local/etc/rc.d/に作られるので、それを参考に、/etc/rc.confにtomcat_enable等の行を追加すれば、Tomcatが起動できるようになる。(OS起動時にも自動的に起動されるようになる)
ちなみに、このサーバーの/etc/rc.confの設定は、

tomcat41_enable="YES"
tomcat41_java_home="/usr/local/jdk1.3.1"
tomcat41_java_vendor="sun"
tomcat41_java_version="1.3"
tomcat41_java_os="native"
tomcat41_java_opts="-Xverify:none"
である。最後の行は、JDBCのI/Fの都合で追加したものであり、Tomcat単体としては必要ない。

ただ1点問題なのは、Tomcat 4.1は、起動スクリプトを使ってTomcatの起動はできるが、状態表示や終了ができないことだ。通常運用だと特に問題無いのだが、Servletのクラスファイルを更新するとTomcatを再起動する必要がある(Tomcat自体がJava VM上で動いておりServletを1回起動したらその名前のクラスはロード済になってしまうため)ので、Servlet開発中は不便である。
原因はロックファイル(/var/run/tomcat41.pid)がうまく作られない(中身が空になる)ことなのだが、/usr/local/etc/rc.subrとにらめっこしているが、今の所修正方法を発見していない。
FreeBSD 5.5のTomcatだとそういう問題は起こらないので、Tomcat 4.1のportsがFreeBSD 4.x以前のことを考えていない可能性がある。
また、samba等他のサーバープログラムの起動スクリプトを一通り見たが、サーバープログラムが自前でdaemon起動しロックファイルを管理しているものばかりで、Tomcatのようにdaemonコマンドを使用してJavaのようなインタプリタをdaemon起動するものは無く、参考にならなかった。起動スクリプトにてJava起動後のpidを取得してロックファイルに格納するというのは、OSの助けが無い限り、並の手段では不可能のように思える。


なお、Servlet対応のHTTPサーバーを入れなくても、Java VMを起動するCGIを作ればApacheでもServletを動かせるのではないかとも思われるが、例えばフォームデータやHTTPコネクションの情報の受け渡しが結構面倒であるし、そもそもServletにはSunが規定する仕様があるので、それに対応するCGIを作るのは容易ではないのである。