Jettyにしばらくアクセスしてないとjava.lang.NoClassDefFoundErrorが発生した話


普段tomcatを使ってて、業務で(組み込みではない)Jettyは使ったことなかったので知らなかったわーという話。

環境

AmazonLinux2
Jetty9.4
Java8

結論

  • Linuxは標準で/tmp 配下を消しているが、Jettyのwarのキャッシュを置くデフォルトのディレクトリが /tmp を指しているので、定期削除のタイミングでキャッシュディレクトリが削除されていたのが原因

経緯

  • Jettyを起動したまま、数日間放置。
  • 久々にアクセスするとInternal Server Errorが発生していて、ログを確認すると、java.lang.NoClassDefFoundErrorと出ていた。
  • そのクラスがないのはアカンじゃろ、と思いながらも、Jettyを再起動すると直るので、よくわからないからいいか。
  • というのを度々発生させる
  • JettyってアクセスしてないとGC発生してメモリから消しちゃうの?そんなの運用に耐えられなくない???
  • そして、日数があんまり経ってないのに発生した。再起動したらやっぱり直る。これは誰かが消してる??
  • ググった結果、以下の記事にあたる。
  • 試しに、Jetty起動中に/tmpのキャッシュディレクトリを消すと、再現したので、これが正解の模様

tmpwatch とは

Linuxとか標準で用意している機能。
詳しくは以下の記事が参考になる
【Linux】【Cent OS】/tmpと/var/tmp以下のファイルを放っておくと勝手に削除される話
そういえば、いつの間にかキレイになってるなぁとは思ってたけど、あんまり気にしたことなかった

AmazonLinux2の /usr/lib/tmpfiles.d/tmp.conf を確認すると以下の設定になってる。
tmpは10日でキレイになるのか

/usr/lib/tmpfiles.d/tmp.conf
# Clear tmp directories separately, to make them easier to override
v /tmp 1777 root root 10d
v /var/tmp 1777 root root 30d

対策

Jettyが週1、2で停止する場合はtmpwatchを疑うべきかも に書いてる通りなんだけど

① Jettyが使用するjava.io.tmpdirのシステム設定の場所を指定する

で対応。

jetty.service の EnvironmentFile で指定したファイルに追記しました。

TMPDIR=/opt/jetty/temp

起動プロセスのVMオプションのtmpdirが

 -Djava.io.tmpdir=/opt/jetty/temp

となっていればOK