プチIT化

WARファイルのデプロイ中に配備エラー、原因調査&対処しました

こんにちは、わたあめです。最近はJavaプログラムを触っています。カタカタ。

今回出会ったエラーは、Javaで作成したWebプログラムにアクセスすると、HTTP Status 404の「The requested resource is not available」が表示されるというエラーです。tomcatサービスまわり・Eclipseまわりを調査&解決しましたので、情報共有します。

わたあめ
わたあめ
エラーは嫌ですよね。手がかりから少しずつ道を開いていきましょ~!
これから記載する内容はわたあめが実際に行った対処方法で、状況が異なれば同じ方法で解決できるわけではありません。対処等は自己責任でお願いします。

事象詳細

今回の事象の詳細です。

  • プログラム(ソースコード自体)に変更は加えておらず、いつも通りの手順でwarファイルをエクスポートし、Tomcatに配置。
  • Tomcatのサービスを再起動したところ、warのデプロイ中にエラーが発生。(ログで確認)
  • Webブラウザからアクセスすると、HTTP Status 404の「The requested resource is not available」が表示される。
  • バックアップしておいたwarファイルでも同じ現象が起きた。
わたあめ
わたあめ
最大の謎:いつもならば同じ手順でエラー発生しないのに、なぜ?!

次章でエラー原因を詳しく追っていきましょう。

エラーの確認方法とエラー原因

まずはTomcatのエラーを確認

エラーが出た時は、とにかくログファイルの確認で手がかりを拾うのが良いです。Tomcatのログファイルを確認します。確認するログファイルは、Tomcatホームディレクトリのlogsフォルダの「catalina.YYYY-MM-DD.log」です。

loglotate設定によって、ファイル名など多少異なることがあります。

ログの中には通常「情報」や「重大」などといったログレベルが記載されています。その中で「重大」といったサービス実行時の妨げになっているログレベルのログを探します。

【怪しいログ1】重大: ContainerBase.addChild: start:

今回はまず「重大: ContainerBase.addChild: start:」というログがありました。

詳細な内容については、その行を読み進めると良いです。今回は「Caused by: java.lang.NoClassDefFoundError: XXXXXXX」と記載されており、クラスが定義されておらず、参照できなかったというエラーだと読み取れます。(英語をなんとなく解釈してみたり、とにかくエラーメッセージでググる。)

【怪しいログ2】重大: Webアプリケーションアーカイブ C:\tomcatX\xxxx.war を配備中のエラーです

上記のようなwarファイルの配備も失敗したとのエラーも出ていました。読み進めると「java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [XXXX]」とでていたので、前に記載したエラー関連でスタートできなかったという事が読み取れます

エラー原因:クラス名が間違っていた

今回上記のエラーからなんとなく推測できるとおり、クラス名が間違っていました。具体的には、クラス名を変更したときにの修正漏れがあり、存在しないクラスを参照していました(汗)。

対処:プログラムを修正しクラスファイルを再構築

今回行った対処手順は以下です。わたあめは開発環境としてEclipseを利用しているので、その手順になります。

  1. ログを確認し、エラー原因となっていたクラスに関連するソースコードの箇所を修正。
  2. Eclipseのメニューバーの[プロジェクト]>[自動的ビルド]にチェックが入っていることを確認。
  3. Eclipseのメニューバーの[プロジェクト]>[クリーン]をクリック。

今回は昔のclassファイルが残存していることが懸念されたので、一度classファイルをきれいに削除(クリーン)して再ビルドしました。これで、無事に動くようになりました。その理由は次章に詳しく書きます。

「自動的にビルド」設定は注意する(自戒)

自動的にビルドする設定が有効になっている場合、コンパイル対象をEclipse側で判断することになります。そうなると、ビルドでのクラスファイルの生成はEclipse任せで、更新しなければならないクラスファイルが更新されていない可能性があります。(私の環境で今まで出来ていたのに出来なくなった原因は多分コレ。)

コンパイルされない古いバージョンのクラスファイルが残っていたがために、何かのきっかけで新バージョンのクラスファイルとなった際に、クラス定義と参照が失敗しエラーとなったようです。(ロジックも古いままだったのか、恐ろしい。。)

わたあめのEclipseのバージョンは古いので、新しいバージョンのEclipseでは良きに図らってくれるかも。

自動ビルド設定の確認方法

設定が有効になっているかは、[プロジェクト]>[自動的にビルド]で設定を確認できます。チェックがついていれば有効、そうでなければ無効です。

自動的にビルドする設定は更新されたところのみコンパイルするという効率的な動きをしてくれるので、残しました。設定を有効にしたまま、クリーン作業を行うという対処にしました。クリーン作業を行うと、クラスファイルが全くない状態となり、全ファイルがビルド対象となります。

わたあめ
わたあめ
ソースコード変えてないけれど、エラーが出た時はクラスファイルが古い可能性を疑ってみるのも一つの手かと思います!

さいごに

いかがだったでしょうか。エラーの原因特定(私の場合も仮説のままですし)と対処って、時間がかかるし状況によって解も様々で難しいですよね。一刻も早くこれを読んでいる方のエラーが解消されますように。

それでは、また!

flier(フライヤー)