終了コードはクラッシュの理由ではなく、ただの肩すくめ
その数字は何も教えてくれない。全てを語るのはその上の行であり、それはすでにログフォルダに入っている。
落ちたJavaサーバーはExit Code 1を出力して停止する。メッセージはそれだけだ。終了コード1は「プロセスが異常終了した」という意味であり、原因ではなく分類にすぎず、ワールドフォルダの欠落からクラスロード中に例外を投げるMODまで、あらゆるものを含んでいる。
本当の答えがある場所
終了コードはlogs/latest.logの最終行だ。原因はその前の行にある。末尾から逆に読み、最初のException、Caused by:、Failed toに当たるまで遡る。その行がクラス名、MOD名、あるいはファイル名を明かしている。
[Server thread/ERROR]: Encountered an unexpected exception
java.lang.NoSuchMethodError: net.minecraft.world.level.Level.getBiome
at com.example.mod.ExampleMixin.inject(ExampleMixin.java:41)
Caused by: java.lang.NoClassDefFoundError: com/example/lib/Helper
ここでのNoClassDefFoundErrorは依存関係の欠落であり、ワールドの破損ではない。終了コードはそんなこと何も教えてくれなかった。
実際に目にする終了コード
| コード | 通常の意味 |
|---|---|
| 0 | 正常終了 — /stopまたはスケジュールされた再起動 |
| 1 | 未処理の例外、またはJVMが起動を拒否 |
| 137 | OSによる強制終了、ほぼ確実にOOMキラー |
| 143 | SIGTERM — コンテナオーケストレーターによる停止 |
コード137はクラッシュと誤読されやすい。JVMは失敗しておらず、その外部の何かがプロセスのメモリ使用量が多すぎると判断したのだ。
JavaとBedrockは同じ問題ではない
Bedrockのサーバーはbedrock_server.logを書き出し、Java形式の終了コードは一切出力しない — 代わりにスタックトレースとCrash report行を含むクラッシュハンドラレポートを吐き出す。Javaのログ向けに書かれたアドバイスはそのままでは通用しない。
MOD構成は違う形で失敗する
MODを入れると、最初の例外はしばしば症状にすぎない。mixinの適用失敗は連鎖を引き起こし、真の原因は最初のMixin apply failed行であり、30行後のNoSuchMethodErrorではない。ログを検索するならExceptionより先にMixinを探せ。
サーバーが起動しているかの確認
ログはなぜ死んだかを教えてくれる。今生きているかは教えてくれない。サーバーポートへのTCPチェックなら1リクエストで答えが出るし、JavaもBedrockもソケット越しに通信するので同じように機能する。
ログをServer Diagnosticsツールに貼り付ければ失敗行を抽出でき、ホストを指定すればサーバーが実際に応答しているか確認できる。