jdk6u23 で jps/jstat が動作しないあるある

お小遣いの残高と年齢以外の数値を計測する事は大好きなソメダです、おはようございます。

さて、皆様におかれましても、運用時の Java アプリケーションのヒープの利用状況の傾向監視は行われているとは思いますが、そういった用途に利用される事の多い jps/jstat といったユーティリティが、現在 (2011年01月) 最新の Java SE 6 update 23 では動作しない事があります。

これは、java.io.tmpdir を OS 標準のディレクトリ (Linux だと /tmp ) 以外に指定して JVM を起動した場合に発生し、例えば以下のような状況になります。

# ps -aef | grep java
tomcat   29030     1  0 Jan12 ?        01:04:01 /usr/java/default/bin/java <略> -Djava.io.tmpdir=/usr/java/tomcat/temp org.apache.catalina.startup.Bootstrap start
:
# jps
:
4519 Jps

jstat で直接 pid を指定しても駄目です。

# jstat -gc  29030 2s
29030 not found

こちら原因なのですが、jstat/jps (他に visualvm も) が、そのプラットフォームで起動している Java のプロセスを探すのに、/tmp/hsperfdata_<ユーザ名>/<プロセスID> というファイルを探すのですが、jdk6u23 以前は /tmp 以下に固定で生成されていたものが、jdk6u23 では java.io.tmpdir 以下に置かれるようになった事が原因です。実際上記の例でも java.io.tmpdir で指定したディレクトリに生成されています。

# ls  /usr/java/tomcat/temp/hsperfdata_tomcat/
29030

今の所の対処法としては、

  1. java.io.tmpdir を /tmp にする (Linux の場合)
  2. jps -J-Djava.io.tmpdir=/usr/java/tomcat/temp/ など、モニタリングツール側でオプションをつける

のどちらかです。後者の指定を行う場合、Tomcat のように別ユーザで jps を実行するには、読み込み権限の問題があるので、su する必要があったりもします。

# su - tomcat -c "jps -J-Djava.io.tmpdir=/usr/java/tomcat/temp/"

例にもあげた Tomcat は、デフォルトで java.io.tmpdir を $CATALINA_BASE/temp に指定して起動しますので、Java のバージョンをあげたら軒並みひっかかるハズです。Tomcat 本体の問題ではないにも関わらず、影響範囲が大きいからか、Tomcat の Bugzilla にも jps.exe and jvisualvm.exe cannot detect tomcat using jdk1.6.0_23 としてあげられてますし、Known Issuewiki からもリンクが貼られてます。既に Java 本体の方に バグ報告 されているので、今のところは上記の対処法で修正を待つ感じでしょうか。

蛇足ですが、この問題の根本となった修正が /tmp とか %TEMP% とかハードコードしているのやめようよ というものなんですが、Java も 6 にもなるまでも、こういった所が残っている事が趣深く、切ない気持ちになった年明けの一幕でした。

それでは今日も一日頑張りましょう。