[発生事象]
ドメインの起動時、停止時、Webアプリケーションの配備時、配備解除時、
プロセスグループの起動時、停止時に Java SEのロック用クラスの処理とWeb
アプリケーション用のクラスローダの停止処理が競合してJava SEのロック用
クラスの処理で NullPointerExceptionが発生することがあります。
この場合、ロック用クラスの状態がロック中のままとなります。したがって、
次にロックを行う場合、ロックが解除されることが無いためそのスレッドがデ
ッドロックします。
デッドロックするスレッドによって以下の様な事象が発生します。
- ドメイン起動/停止処理スレッドがデッドロックした場合
ドメインがストール
- プロセスグループ起動/停止処理スレッドがデッドロックした場合
プロセスグループがストール
- アプリケーション処理スレッドがデッドロックした場合
アプリケーションがストール
- 運用管理コマンド処理スレッドがデッドロックした場合
運用管理操作が受け付けられない
[確認方法]
Java SEのロック用クラスの処理の延長でのNullPointerExceptionの記録が
WebOTXのログ に記録されていれば本件に合致します。
具体的な記録の例として以下があります。
---------------------------------------------------------------
Caused by: java.lang.NullPointerException
at java.lang.ThreadLocal$ThreadLocalMap.expungeStaleEntry(ThreadLocal.java:XXX)
at java.lang.ThreadLocal$ThreadLocalMap.remove(ThreadLocal.java:XXX)
at java.lang.ThreadLocal$ThreadLocalMap.access$200(ThreadLocal.java:XXX)
at java.lang.ThreadLocal.remove(ThreadLocal.java:XXX)
at java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryReleaseShared(ReentrantReadWriteLock.java:XXX)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(AbstractQueuedSynchronizer.java:XXX)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.unlock(ReentrantReadWriteLock.java:XXX)
・・・
---------------------------------------------------------------
※WebOTXのログ
- Webアプリケーションがエージェントプロセスに配備されている場合(スタンダードモード)の場合
<ドメインdir>/logs/webotx_agent.log
- Webアプリケーションがプロセスグループに配備されている場合(アドバンスドモード)の場合
<ドメインdir>/logs/tpsystem/<アプリケーショングループ名>/<プロセスグループ名> 配下のプロセスグループのログ
ただし、ログに出ない場合もあるため、事象発生時にスレッドダンプを採取して確認し、
Java SEのロック用クラスがロックをしようとして進まない状態で
あれば本件に合致します。
※この時WebOTXのコマンドでのスレッドダンプ採取は出来ない場合
があるためJavaが提供するスレッドダンプ採取機能で採取する
必要があります。
事象発生時のスレッドダンプの例は以下のとおりです。
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000xxxxxxxx> (a java.util.concurrent.locks.ReentrantReadWriteLock$FairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:XXX)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:XXX)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared(AbstractQueuedSynchronizer.java:XXX)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(AbstractQueuedSynchronizer.java:XXX)
at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lock(ReentrantReadWriteLock.java:XXX)
スレッドダンプを何回か採取して、このスレッドに動きが無ければ本件に合致します。
[復旧方法]
事象発生時にはWebOTXがストールしますので、ドメインの再起動(強制停止→起動)を
して頂くようお願いいたします。
強制停止は、下記のように指定することで、当該ドメインの全プロセスが停止します。
otxadmin> stop-domain --force=true --wait_timeout=0 <ドメイン名>
JavaVMオプションに、ThreadLocalのメモリリークチェックを行わない設定を行います。
- 運用管理コマンドご利用の場合
otxadmin> create-jvm-options -Dcom.nec.webotx.webcontainer.EnableCheckThreadLocalsForLeaks=false
- 運用管理コンソールご利用の場合
ドメイン > アプリケーションサーバ > JVM構成 > [JVMオプション]タブ > JVM オプション
以下の値を追加します。
-Dcom.nec.webotx.webcontainer.EnableCheckThreadLocalsForLeaks=false
プロセスグループ上にWebアプリケーションを配備している場合は、併せてプロセスグループに対して以下の設定を行います。
- 運用管理コマンドご利用の場合
otxadmin> add-pg-javasystem-property --apgroup ${アプリケーショングループ名} --javasystemprop com.nec.webotx.webcontainer.EnableCheckThreadLocalsForLeaks --value false ${プロセスグループ名}
- 運用管理コンソールご利用の場合
ドメイン > TPシステム > アプリケーショングループ > ${アプリケーショングループ名} > プロセスグループ > ${プロセスグループ名} > [Javaシステムプロパティ]タブ > Javaシステムプロパティ
以下の値を追加します。
名前:com.nec.webotx.webcontainer.EnableCheckThreadLocalsForLeaks
値 :false
設定変更後はドメインを再起動します。
※V9.11, V9.20, V9.21について、本回避方法は以下のバージョン以降で有効
ですので、最新パッチを適用後、本回避策の実施をお願いします。
V9.11: V9.11.00.02以降
V9.20: V9.20.00.01以降
V9.21: V9.21.00.01以降
V9.10では回避方法はありません。急ぎでパッチが必要な場合はご連絡ください。