- JAVA
ExceptionInInitializerErrorの原因と直し方|Java
java.lang.ExceptionInInitializerError は、クラスの static の初期化(static 変数の初期値、static ブロック)の中で例外が起きたときのエラーです。 本当の原因は、すぐ下の Caused by: に書かれています。
Exception in thread "main" java.lang.ExceptionInInitializerError
at App2.main(App2.java:2)
Caused by: java.lang.NumberFormatException: For input string: "30s"
at java.base/java.lang.Integer.parseInt(Integer.java:662)
at Config2.<clinit>(App2.java:1)
<clinit> は「クラスの static の初期化」を表します。 この例では、Config2 の static 変数の初期化で、"30s" を数値に変換しようとして失敗しています。
そして、2回目以降にそのクラスを使うと、別のエラーに変わります。
java.lang.NoClassDefFoundError: Could not initialize class Config
| 何回目か | 出るエラー | 読むところ |
|---|---|---|
| 1回目 | ExceptionInInitializerError |
Caused by: が本当の原因 |
| 2回目以降 | NoClassDefFoundError: Could not initialize class ○○ |
ログをさかのぼって、1回目の ExceptionInInitializerError を探す |
確認環境:OpenJDK 8u504・11.0.32・17.0.20・21.0.10・25.0.4 で、同じ class ファイルを動かしました(確認日 2026年10月11日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「ExceptionInInitializerErrorの原因と直し方|Java」
再現
class Config {
static final int TIMEOUT = Integer.parseInt(System.getProperty("app.timeout", "30s"));
static String hello() { return "timeout=" + TIMEOUT; }
}
public class App {
public static void main(String[] args) {
for (int i = 1; i <= 2; i++) {
try {
System.out.println(Config.hello());
} catch (Throwable e) {
System.out.println("[" + i + "回目] " + e);
// Caused by を順に表示
}
}
}
}
設定値 app.timeout が無いときの既定値を、うっかり "30s"(単位付き)にした、という想定です。
[1回目] java.lang.ExceptionInInitializerError
Caused by: java.lang.NumberFormatException: For input string: "30s"
[2回目] java.lang.NoClassDefFoundError: Could not initialize class Config
Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.NumberFormatException: For input string: "30s" [in thread "main"]
2回目は、初期化をやり直さず、すぐに NoClassDefFoundError になりました。 Java 言語仕様(JLS 12.4.2)でも、初期化で例外が起きたクラスは「エラーの状態」になり、以後の初期化は行われず NoClassDefFoundError を投げる、と定められています。一度失敗したクラスは、JVM を再起動するまで使えません。
-Dapp.timeout=30 を付けて起動すると、2回とも timeout=30 と表示されました。
JDK の版で、2回目の手がかりが違う
| JDK | 2回目のエラーの Caused by |
|---|---|
| 8u504・11.0.32 | 無し(何が原因か書かれていない) |
| 17・21・25 | ExceptionInInitializerError: Exception java.lang.NumberFormatException: For input string: "30s" [in thread "main"] |
JDK 17 以降では、2回目のエラーにも、1回目の原因と、どのスレッドで起きたかが付きました。 これは JDK のバグ票(JDK-8048190「NoClassDefFoundError omits original ExceptionInInitializerError」)で改善された動きです。確認環境の JDK 8・11 では付かなかったため、以前の版では、ログをさかのぼって1回目を探すしかありません。
Web アプリ・バッチでの探し方
| 状況 | 起きやすいこと |
|---|---|
| Web アプリ | 最初のリクエストで ExceptionInInitializerError、以後のリクエストはすべて NoClassDefFoundError |
| 1回目のエラーを catch してログに出していない | ログには NoClassDefFoundError しか残らない |
| 複数のスレッドで同時に使った | 1回目は別のスレッドで起きている(JDK 17 以降は [in thread "..."] で分かる) |
ログを ExceptionInInitializerError で検索し、一番最初の1件を見ます。 その Caused by: が本当の原因です。スタックトレースの読み方は、既存の記事「Javaスタックトレースの読み方|Caused byの意味と原因の探し方」で扱っています。
よくある原因
確認環境で、static の初期化にそれぞれの処理を書いて試しました。
| static の初期化で書いたこと | Caused by |
|---|---|
設定値を数値に変換("30s") |
NumberFormatException |
無い設定ファイルを Properties.load(getResourceAsStream(...)) |
NullPointerException(inStream parameter is null) |
正しくない正規表現を Pattern.compile |
PatternSyntaxException |
正しくない書式を DateTimeFormatter.ofPattern |
IllegalArgumentException |
| 別のクラスの static 変数(null だった)を使う | NullPointerException |
static の初期化は、そのクラスを初めて使ったときに1回だけ動き、失敗するとやり直せません。 設定の読み込み・外部への接続のように失敗しうる処理は、static ではなく、起動時の処理やインスタンスの初期化で行い、失敗したら分かりやすいメッセージで止めるようにします。
class Config {
private static int timeout() {
String v = System.getProperty("app.timeout", "30");
try {
return Integer.parseInt(v);
} catch (NumberFormatException e) {
throw new IllegalStateException("app.timeout は数値で指定します: " + v, e);
}
}
}
NoClassDefFoundError には2種類ある
| エラー文 | 意味 |
|---|---|
NoClassDefFoundError: Could not initialize class Config |
クラスは見つかったが、static の初期化で失敗している |
NoClassDefFoundError: Config2(Caused by: ClassNotFoundException) |
実行するときに、クラスそのものが見つからない(jar の入れ忘れなど) |
確認環境で Config2.class を消して実行すると、NoClassDefFoundError: Config2(Caused by: ClassNotFoundException)になりました。 Could not initialize class が付いているかどうかで、原因がまったく違います。クラスが見つからない方は、既存の記事「Java ClassNotFoundExceptionの原因と対処 違いも解説」で扱っています。
確認の手順(チェックリスト)
| 順番 | 確認すること | 方法 |
|---|---|---|
| 1 | Could not initialize class が付いているか |
付いていれば static の初期化の失敗 |
| 2 | 1回目の ExceptionInInitializerError | ログを最初までさかのぼる |
| 3 | Caused by: の例外 |
本当の原因 |
| 4 | <clinit> の行 |
static の初期化のどこか |
| 5 | 直したあと | JVM(アプリ)を再起動する |
よくある質問
Q. 直したのに、まだ NoClassDefFoundError が出ます。 A. 一度初期化に失敗したクラスは、同じ JVM の中では使えないままです。アプリを再起動して確かめます。
まとめ
- static の初期化で例外が起きたエラー。
Caused by:が本当の原因 - 2回目以降は
NoClassDefFoundError: Could not initialize classに変わる - JDK 17 以降は、2回目にも1回目の原因が付く。以前の版はログをさかのぼる
- 失敗しうる処理(設定・接続)は static の初期化に書かない
- 直したら再起動。
Could not initializeの無い NoClassDefFoundError は別の原因
参考・出典
確認日はいずれも 2026年10月11日です。
- The Java Language Specification, Java SE 21「12.4.2 Detailed Initialization Procedure」:https://docs.oracle.com/javase/specs/jls/se21/html/jls-12.html
- JDK Bug System「JDK-8048190 NoClassDefFoundError omits original ExceptionInInitializerError」:https://bugs.openjdk.org/browse/JDK-8048190
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「ExceptionInInitializerErrorの原因と直し方|Java」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。