Tomcat6のendorsedディレクトリ指定 @ CentOS 6.3

某案件で、Ubuntu (12.04.1 LTS) だと動いてくれるソフト (Tomcat6上で動くヤツ)がCentOS 6.3だと動かないという問題に出会いました。warファイルに加えてendorsedディレクトリを使います。本当にそれだけ。私のやってることを知ってると「アレか」と思う人もいるかもしれませんが書きません。一般論で押さえ込みます。

さて、ここからどうやってゴールである「CentOSで動かす」に結びつけるかです。Tomcat6のビルドオプションが違うとかでしょうか。よくわかりません。私割とTomcat6初めてです。7じゃ、だめなんだって (入れるソフトの制約)。

ちなみにググるととてもたくさん「CATALINA_OPTSを指定する」と出てきます。この方法が効くディストリビューションもあるかもしれませんがCentOS 6.3の標準のtomcat6だと効きません。ぐすん

○ とりあえず問題洗い出し

war入れても動かないよわーん、というところから。

切り分けにはjenkins.warを使いました。今ここでJenkinsについて知っておく必要はありません。そういうのは猫に聞いてください。localhost:8080/jenkins開いてじじいが現れればwarの読み込みには成功する、というのがここでは重要です。

どうやってjenkins.warを見つけたんでしょうね私。war テストとかでググって最小作業量で動きそうなオープンソースの実装を見つければ良い、という感じでやったのです。ちなみにwarってなんのか私しりません。多分jarの戦争版です。知りたければWikipediaにでも行きましょう。

war使ったテストよりも前にlocalhost:8080/ が見られるかどうかをチェック、というのがUbuntuでは効くんですが、CentOSだとROOTのデフォルトhtmlがないんですね (言い換えると、パッケージインストール直後にデフォルトで動くページがひとつも用意されてない)。だからlocalhost:8080 開いてもUbuntuだと「It works!」って褒めてくれるのに、CentOSだと何も言ってくれないのです。本当にインスコしたものが (ファイアーウォールとかによって) 止められてないかを確信するために、わざわざUbuntuからその最小構成だけコピって確認してます。

Tomcat6をyumで入れた時に変なことが起きているとjenkins.war (とROOTなindex.html) も動かないはずなのです。だから、ここでは「Tomcat6は被害者」となって次に進めます。

○ ログ

並行してもちろんログ。上の話からすでにendorsedあたりがあやしいとは思えるんですが、ここで確信めいたものに変わります。ところで、こっちからはじめるべきだったんです。

/var/log/tomcat6/ 下のlocalhost.日付.logを見ます。それじゃないのに変なエラーが吐かれると行けないので、tomcat6を起動した時から変化してそうなファイルを tail /var/log/tomcat6/*とか使ってアタリつけて、後は tail -f で怪しいファイルを見ながらまたtomcat6起動します。まぁ多分上のログでいいでしょう

今回はClassNotFoundExceptionが出ていました。ClassNotFoundExceptionとtomcat6でぐぐったりします。ああ、やっぱりendorsedか。

……でも環境変数指定したのに><

○ 空気感をさぐる

仮説として「その環境変数が全く使われていない」と考えます。そして「そもそもその変数は誰がハンドルしてくれるのか」という疑問に結びつけます。なお、Ubuntuでは指定しなくてもendorsedディレクトリを作れば動くような感じに見えました。ちょっと覚えてないですけど

# Tomcat6関係のフォーラムの発言がこのあたりでぶれまくっててかなり困るんですよね。みんな使ってる環境がすごく違うのにそれは言わないものだから。

JAVA_HOMEとかは非常に強力な、Javaワールドの重要変数なので色々なところで使われるのですが、じゃぁCATALINA_OPTSってのはTomcat6本体が長年動作を保証してきた環境変数なんでしょうか。そうじゃなさそうなんですよね。

Tomcat6の構造なんて理解してる暇はないので、感触だけつかめるサイトを探したらこれを見つけました。

一見してCentOSには関係ないんですが、本家が起動スクリプトを書いてくれてないという事実が重要。そうかディストリビューションが提供している起動スクリプト中でだけこれは使われてるのだな、と推測します。ちなみに最初の「Ubuntuで動いてCentOSで動かない」からここまで直接来ることも振り返れば可能でした。自分が下手撃ってる、という仮定が裏にあった部分もあったので、と言い訳しときます。endorcedじゃもちろんうごかねーんだよ

○ OS毎に違うところを乱れ撃ち

grep でCATALINA_OPTSがどうやっても出てこないので、観念して/etc/init.d/tomcat6に関係する行をガリガリ読む。多分熟練者はここから始めますね。上の流れはぶっちゃけ遠回りです。

○ /usr/sbin/tomcat6

/etc/init.d/tomcat6 が最終的には /usr/sbin/tomcat6 を呼ぶとわかります。レベルが高いとここから初めて10秒で気づきますね。私1時間じゃすまないレベルで悩んでたんですけど。


${JAVACMD} $JAVA_OPTS $CATALINA_OPTS \
    -classpath "$CLASSPATH" \
    -Dcatalina.base="$CATALINA_BASE" \
    -Dcatalina.home="$CATALINA_HOME" \
    -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \
    -Djava.io.tmpdir="$CATALINA_TMPDIR" \
    -Djava.util.logging.config.file="${CATALINA_BASE}/conf/logging.properties" \
    -Djava.util.logging.manager="org.apache.juli.ClassLoaderLogManager" \
    org.apache.catalina.startup.Bootstrap start \
    >> ${CATALINA_BASE}/logs/catalina.out 2>&1 &
    if [ ! -z "$CATALINA_PID" ]; then
      echo $! > $CATALINA_PID
    fi


はい、どこにもCATALINA_OPTSなんてものは使われてません。動かなくて当然です。で、JAVA_ENDORSED_DIRSを指定すればいいのですね。

よく考えたらただのjavaコマンドでtomcat6も動いてんだから気づけ、って話でした。うぐぅ!

○ 作法に合わせる

ものによっては/etc/init.d/tomcat6 を直接書き換えろ、とかいう話が出てきて怪しいんですが、CentOSは/etc/tomcat6/tomcat6.confを書き換えろと書いて有ります。他ならぬ/etc/init.d/tomcat6氏がです。

JAVA_ENDORSED_DIRS="/usr/share/tomcat6/endorsed" とでも書けばいいでしょう。

export要りません。これを読む方のスクリプトで補完してます。

○ tomcat関連のファイル散らばりすぎだよ

updatedb, locate を駆使しました。これかなり便利なんですが、案外言及されたことがないんですよね。みなさん全ファイルをEclipseに探させてるんだと信じてます。

○ 感想

野良のQ&Aのひどさが印象的な件だったので書いてみました。重要なのはディストリビューション毎のブレが大きいパッケージの扱いに私が弱かった、というところでしょうね。

この話を書いたもうひとつの動機は、学生時代先輩とかが全く同じ情報量 (ネットでぐぐっても答えなし) から私が解決できない問題を解決しているのを見て、ある種の「ロジックのつなげ方」を知る手段が少ないのが気に入らなかった、というところでしょうか。原則を下にして必要に応じて材料を集めていくという解決アプローチって割とネットでも雑誌でも記事にはならないのですよ。例えば雑誌で「どうやってその知識を得たか」に絞り込んだ連載を見ることはほぼないという印象。みなエキスパートぶって「〜をやるにはーーします」と書いてあるのですが、自力で読者が力をつけられるにはこのフォーマットでは足りない気がしています。読者ってのはひ弱な私のことです悪いか!

○ 結論を書け!

JAVA_ENDORSED_DIRSを/etc/tomcat6/tomcat6.confで定義しなさい。

このブログの人気の投稿

LibreOfficeで表紙、目次、本体でフッターのページ番号のスタイルを変える

WiiUのコントローラが通信不良に陥った話

技術書典2 あ-03 『もわねっとのPythonの本』