snbhsmt_log

ネットワークとコンピュータ、その他いろいろ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

FC4 で Tomcat が停止できない

Fedora Core 4 にインストールした Tomcat 5.0.28 を catalina.sh stop で停止しようとしたら出来ず、ログを見ると以下の例外が発生していた。

Catalina.stop: java.net.SocketException: Invalid argument or cannot assign requested address
java.net.SocketException: Invalid argument or cannot assign requested address
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:305)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:171)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:158)
        at java.net.Socket.connect(Socket.java:452)
        at java.net.Socket.connect(Socket.java:402)
        at java.net.Socket.<init>(Socket.java:309)
        at java.net.Socket.<init>(Socket.java:124)
        at org.apache.catalina.startup.Catalina.stopServer(Catalina.java:410)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:324)
        at org.apache.catalina.startup.Bootstrap.stopServer(Bootstrap.java:336)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:427)
とりあえず telnet で 8005 番ポートにつないで停止。

127.0.0.1:8005 に接続できるか出来ないかの問題っぽいが、 iptables で DROP している訳でもなく、そういえば SELinux が関係しているのかと 考えて無効にしてみたら catalina.sh stop できた。 しかし Tomcat を利用する時は SELinux を無効にするというのでは問題なので 別の手を考える。

Tomcat の LISTEN 状態は netstat -a --inet しても表示されず、 --inet6 だと表示される事から IPv6 が有効になっている事がわかる。 そういえば Java の IPv6 周りはヤヤコシイと聞くので、 JVM に IPv4 を優先するオプションを付けてみる。

JAVA_OPTS="-Djava.net.preferIPv4Stack=true"
この状態で Tomcat を起動すると netstat -a --inet で LISTEN 状態が確認でき、 catalina.sh stop で正常に停止する事が確認できた。 SELinux の設定については勉強不足でよく解らないし、IPv6 を使う予定は無いので、 とりあえずこの方法で良しとする。

java.net.preferIPv4Stack システム・プロパティを true にすると、 IPv6 アドレスより IPv4 アドレスを優先する。 Java は標準で IPv6 が有効なシステムでは IPv6 で繋ごうとするらしいが、 繋げなかった場合 IPv4 なら繋がるかを試してくれないらしい。本当か ?

FC4 の lo インターフェースには IPv6 アドレスが割り当てられている。 これが無ければ java.net.preferIPv4Stack=false でも bind 出来るのだろうか。

  • Fedora Core 4
  • j2sdk 1.4.2_08
  • Tomcat 5.0.28

2006/01/02 更新
いつの間にか、java.net.preferIPv4Stack=true にしなくても Tomcat を正常に 停止できるようになっていた。よく解らないが SELinux のルールをアップデートした からかもしれない。

Tomcat 5.0.14 以降のログ出力に Log4J を利用する

Tomcat のログ出力に Log4J を利用する場合、 5.0.14 以前と以降では異なる設定が必要らしい。

5.0.13 までは 4.1.x の頃と同じだったけど、5.0.14 以降は Commons Logging API パッケージを System クラスローダで読み込む必要があるらしく、bin/commons-logging-api.jar が起動時にクラスパスにセットされる様になっている。 Tomcat のクラスローダ階層からすると、System クラスローダにてロードされた Commons Logging API パッケージから Log4J API パッケージを参照可能にする為には、 同じく System クラスローダにてロードさせる必要がある。 つまり、Log4J 関連のファイルも Tomcat 起動時のクラスパスに含める必要がある という事になる。

標準の起動スクリプトである catalina.sh には、ユーザが起動時のクラスパスに クラスを追加する方法が無いので、catalina.sh を編集するしかない。 行った方法は以下。

まず、commons-logging.jar と log4j-*.jar を何処かに置く。 ここでは $CATALINA_HOME/bin に置く事にする。
あと設定ファイル (log4j.xml / log4j.properties) をクラスパス経由で検索させるなら、 それも何処かに置く。 ここでは $CATALINA_BASE/classes ディレクトリを作成して、 log4j.xml をそのディレクトに置く事にする。
そして上記 JAR ファイルと設定ファイルがクラスパスに設定される様に catalina.sh を変更する。 ここでは以下の様に変更した。

#CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar:"$CATALINA_HOME"/bin/commons-logging-api.jar

if [ -z "$CATALINA_BASE" ] ; then
  CATALINA_BASE="$CATALINA_HOME"
fi

CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar:"$CATALINA_HOME"/bin/commons-logging.jar:"$CATALINA_HOME"/bin/log4j-1.2.8.jar:"$CATALINA_BASE"/classes

問題点:
ウェブアプリで Commons Logging や Log4J を用いる場合、 WEB-INF/{lib,classes} のものよりも System クラスローダでロードされたものが 優先されてしまう。 だから WEB-INF/classes/log4j.properties などの個別の設定も参照されず、 すべて $CATALINA_BASE/classes/log4j.properties で設定しなければならない。

  • Tomcat 5.0.28
  • Commons Logging 1.0.4
  • Log4J 1.2.8

catalina.properties

Tomcat 5.0 以降には conf ディレクトリ中に catalina.properties と いうファイルが存在する。 このファイルにプロパティを書いておくと、それらはシステム・プロパティとして 設定される様である。

catalina.properties は org.apache.catalina.startup.CatalinaProperties#loadProperties() で読み込まれ、System#setProperty() される。

標準で記述されている package.access と package.definition は、 java.lang.SecurityManager#checkPackageAccess(), java.lang.SecurityManager#checkPackageDefinition() で利用されるもの。

common.loader, server.loader, shared.loader は、 それぞれのクラスローダのクラスパスを指定するもので、 org.apache.catalina.startup.Bootstrap#createClassLoader() にて クラスローダを作成する時に利用される。

*.loader プロパティの存在は、{common,server,shared}/classes/ 内の class ファイルと {common,server,shared}/{lib,endorsed}/*.jar 以外の ファイルでも、クラスローダに渡す事ができる事を表していると思う (未確認だけど) 。

Tomcat 5 系に移行

Tomcat 5.0.28 が 2004/08/28 にリリースされ、これを期に 5.0 系を 使い始めたと言う事で、ちょっと気が付いた事を 2 つ書く。

catalina.sh version とか version.sh とかで Tomcat のバージョンが 表示される。 インストールしてある Tomcat のバージョンって何だっけ ? と いった場合にこれで確認が可能。

catalina.50.sh という実行ファイルが追加されている。 catalina.sh との違いは -Djava.endorsed.dirs=... しない点だけであり、 どういう用途に利用するのか良く解らない。

Security Manager を有効にすると以下のワーニングが出る。

2004-08-29 18:34:02,125 [main] WARN  org.apache.commons.beanutils.MethodUtils
 - Cannot use JVM pre-1.4 access bug workaround due to restrictive
 security manager.

« Prev|Top

HOME

snbhsmt

Author:snbhsmt
Google Profiles

http://www.ksky.ne.jp/~snbhsmt/

全ての記事を表示する

この人とブロともになる

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。