JBOSSとSeasarとTeeda その3

ログ設定まわりのお話です。

JBOSS関連で一番ハマったのがこれです。
JBOSS AS7.xでは各アプリケーションで利用している

Log4Jなどのロガークラスは
LogManagerがハックして一元管理する仕組みになっています。

JAVA標準のログAPILog4Jの呼び出す時に使われるクラスローダーは
以下のようにLogManager用のクラスローダーに置き換えられてしまう。

java.util.logging.Logger = org.jboss.logmanager
org.apache.log4j.Logger = org.jboss.log4j.logmanager


{JBOSS_HOME}/modules/system/layers/base/org/apache/log4/main/module.xmlを見ると

こんな記載があり、特定のパッケージの場合に
クラスを置き換えているのがわかる。
このファイルを消したりいじるとJBOSS自体が起動できるなる。
LogManagerを無効にする方法は後述します。


LogManagerではstandalone.xmlやdomain.xmlに書かれている
ログ設定に応じて出力されるようになる。
また、このXMLを変更してJBOSSを起動すると
{JBOSS_HOME}/{standalone|domain}/configuration/logging.propertiesにその設定が反映される。


上述のように基本的にはLogManagerで一元管理されるのですが
アプリケーションのクラスパス上にlog4l.xmlがある場合は
実はLog4Jのアペンダーなどの設定が優先されます。
ただし、実はここにトラップがあります。
その1でも書きましたが、私の今回のミッションはJBOSSへの

既存プロジェクト移行です。
Seasar2で作られたプロジェクトなのでSeasar系が出力するログは基本的に
CommonsLoggingが使われています。
配備するアプリケーションのcommons-logging.propertiesファイルが
置かれていてもJBOSS環境下では無視されるんですよ。
なのでLogFactoryでロガーインスタンスを作ると

apache.commons.logging.impl.SLF4JLocationAwareLogに
なってしまう。
ややこしいことにDBFluteはCommonsLoggingではなくクラスの中で
明示的にLog4jロガーを利用しているのでDBFlute関連のログは出る。
ハマる原因のひとつでした。TraceInterceptorを
ラップしてLog4Jロガーを使うように明示的に変更してあげると出ます。

一般的なプロジェクトであればこれで解決なのかもしれませんが
まだ問題はあります。
JBOSS上ではLog4j.xmlを各モジュール分読み込んでくれません。
先勝ちなのか後勝ちなのかわかりませんが、
どれかの設定がすべてに適用されるんです。

今回の移行対象のシステムは6つくらいあり、JAVAのパッケージ構成は同一で
それぞれのLog4j.xmlないでログの出力場所を変更しているんですが、
上述した仕様の為、全部同じログファイルに出力されちゃうんですよ。
まいった(>_<)>

で、結局どう解決したかというと・・・








各モジュールのWEB-INFの下に
jboss-deployment-structure.xmlという名前で
こんなXMLを配備すれば良い。これでLog4jLog4jとして動きます。


JBOSSSeasarTeedaシリーズも次回くらいが最後になるかと思います。
次はWebLogicJBOSSTomcat
サーブレットコンテナの仕様の違いや
その他、細かいところを。

JBoss Enterprise Application Platform6 構築・運用パーフェクトガイド

JBoss Enterprise Application Platform6 構築・運用パーフェクトガイド

JBOSS AS7.2よりGlassFish4の方がいいなぁ。