はじめに
従来のWebSphere Application Serverでは汎用JVM引数の設定で、コマンドに引数をとる場合など、つまりスペースが入る場合は、""で囲んで記述していました。
参考:https://www.ibm.com/developerworks/jp/websphere/library/was/was_tips/31.html
汎用JVM引数の設定を下記のように行います。
(ア)UNIX/Linuxの場合
-Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec="kill -9 %pid"
Libertyでも同じように設定するのだろうと思い込み、jvm.optionsに上記と同じ記述を行ったところ、OutOfMemoryErrorを起こしてもJVMがkillされませんでした。。
ので調査してみたところ、以下の情報が見つかりました。
https://www-01.ibm.com/support/docview.wss?uid=swg1PI74586
The fix for this APAR adds the quotes back in when processing
the jvm.options file.
Libertyの場合、jvm.optionsを処理するときには単引用符を内部的に付加しているようです。そのため二重引用符をユーザーが記述すると、'"xxx"'となってしまうようです。
上記の設定の場合、「killコマンド」&引数と認識されず、「kill -9 %pid」というコマンドとして認識されてしまい、command not foundなエラーが発生します。
試してみる
前提条件
- CentOS 7.1
- Open Liberty: 18.0.0.3
- Eclipse OpenJ9: 1.8.0_162
- OutOfMemoryErrorを起こすアプリ:こちらで入れた問題判別ハンズオン用アプリを使用
""付きの場合
1. jvm.optionsを設定する
# Kill JVM when OutOfMemoryError occured.
-Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec="kill -9 %pid"
2. server start server1でJVMを起動し、OOMEアプリを実行しOOEM発生を確認
server start server1
[ERROR ] SRVE0777E: アプリケーション・クラス 'pdpro.oome.MyOutOfMemoryErrorServlet.doTask:83' によって例外がスローされました
java.lang.OutOfMemoryError: Java ヒープ・スペース
at pdpro.oome.MyOutOfMemoryErrorServlet.doTask(MyOutOfMemoryErrorServlet.java:83)
at pdpro.oome.MyOutOfMemoryErrorServlet.doPost(MyOutOfMemoryErrorServlet.java:34)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1255)
at [internal classes]
3. 生成されたjavacoreから、上記汎用JVM引数は読み込まれていることを確認
0SECTION TITLE subcomponent dump routine
NULL ===============================
1TICHARSET UTF-8
1TISIGINFO Dump Event "systhrow" (00040000) Detail "java/lang/OutOfMemoryError" "Java ヒープ・スペース" received
1TIDATETIME Date: 2018/10/09 at 08:40:09:587
1TINANOTIME System nanotime: 1698026317031
1TIFILENAME Javacore filename: /opt/IBM/OpenLiberty/wlp/usr/servers/server1/javacore.20181009.084006.4819.0005.txt
1TIREQFLAGS Request Flags: 0x81 (exclusive+preempt)
1TIPREPSTATE Prep State: 0x104 (exclusive_vm_access+trace_disabled)
(略)
2CIUSERARG -Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec="kill -9 %pid"
4. console.logを確認すると、上記で設定したkill -9 %PIDは、コマンドが見つからずエラーになっていることがわかる
(略)
JVMDUMP039I ダンプ・イベント "systhrow"、詳細 "java/lang/OutOfMemoryError" (場所: 2018/10/09 08:40:06) を処理しています - お待ちください。
(略)
JVMDUMP007I JVM は Tool ダンプ ('"kill -9 4819"' を使用する) を要求しています
JVMDUMP011I Tool ダンプはプロセス 5036 を作成しました
/bin/sh: kill -9 4819: コマンドが見つかりません
JVMDUMP013I ダンプ・イベント "systhrow"、詳細 "java/lang/OutOfMemoryError" を処理しました。
5. server statusで確認しても稼働中であることがわかる
./server status server1
サーバー server1 はプロセス ID 4819 で稼働中です。
""無しの場合
1. jvm.optionsを設定する
# Kill JVM when OutOfMemoryError occured.
-Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec=kill -9 %pid
2. 上記同様に、OOMEアプリを実行しOOEM発生
3. 生成されたjavacoreから、上記汎用JVM引数は読み込まれていることを確認
0SECTION TITLE subcomponent dump routine
NULL ===============================
1TICHARSET UTF-8
1TISIGINFO Dump Event "systhrow" (00040000) Detail "java/lang/OutOfMemoryError" "Java ヒープ・スペース" received
1TIDATETIME Date: 2018/10/09 at 08:58:15:455
1TINANOTIME System nanotime: 2783894610353
1TIFILENAME Javacore filename: /opt/IBM/OpenLiberty/wlp/usr/servers/server1/javacore.20181009.085808.5733.0003.txt
1TIREQFLAGS Request Flags: 0x81 (exclusive+preempt)
1TIPREPSTATE Prep State: 0x104 (exclusive_vm_access+trace_disabled)
(略)
2CIUSERARG -Xdump:tool:events=systhrow,filter=java/lang/OutOfMemoryError,exec=kill -9 %pid
4. console.logを確認すると、上記で設定したkill -9 %PIDはエラーなく実行されていることがわかる
(略)
JVMDUMP039I ダンプ・イベント "systhrow"、詳細 "java/lang/OutOfMemoryError" (場所: 2018/10/09 08:58:08) を処理しています - お待ちください。
(略)
JVMDUMP007I JVM は Tool ダンプ ('kill -9 5733' を使用する) を要求しています
JVMDUMP011I Tool ダンプはプロセス 5860 を作成しました
JVMDUMP039I ダンプ・イベント "systhrow"、詳細 "java/lang/OutOfMemoryError" (場所: 2018/10/09 08:58:15) を処理しています - お待ちください。
5. server statusで確認しても停止中であることがわかる
./server status server1
サーバー server1 は稼働していません。
まとめ
というわけでLibertyでは汎用JVM引数をjvm.optionsに記述するときは、コマンドの引数などでスペースがある場合でも""で囲む必要は無くなりました。
なお、WebSphere LibertyでもOpen Libertyでも上記内容は同じのようです。
追記
マニュアルにもいつの間にか追記されてました。。
https://www.ibm.com/support/knowledgecenter/ja/SSD28V_9.0.0/com.ibm.websphere.wlp.core.doc/ae/twlp_admin_customvars.html
プロパティー値を引用符で囲まないでください。