デバッグ用の起動オプションを昔からそのまま持ち回っているプロジェクトが、JDK 23 で止まります。
Unrecognized option: -Xnoagent
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
main() に到達する前に止まっています。同じ形で、別のオプションでも出ます。
Unrecognized option: -Xnoagent(JDK 23 以降)Unrecognized option: -Xfuture(JDK 24 以降)Unrecognized option: -checksource/-cs/-noasyncgc(JDK 24 以降)
エラー文が Unrecognized option: か Unrecognized VM option か
同じ「起動できない」でも、エラー文が 2 通りあります。
Unrecognized option: -Xnoagent (これ)
Unrecognized VM option 'UseBiasedLocking' (別の記事の対象)
-Xnoagent を弾いているのは java コマンド(launcher)です。 JDK 23 の release note も、これを launcher のオプションとして扱っています。だからエラーに VM が付きません。いっぽう UseBiasedLocking のような -XX: フラグを弾くのは、その先の HotSpot VM で、そちらは Unrecognized VM option 'X' になります。
ただし「-X なら launcher、-XX なら VM」という規則ではありません。 -Xmx64m は -X で始まりますが、VM のヒープ上限を指定するもので、JDK 25 でも問題なく起動します(実測)。接頭辞では処理層を判別できないので、この記事で扱うのは -Xnoagent とその周辺の、実際に観測したオプションだけです。
直し方
起動オプションから -Xnoagent を消します。
# 消す
-Xnoagent
-Xnoagent が無効化していたのは、JDK 1.1 時代の旧デバッグ機構(sun.tools.debug / sun.tools.agent)です。-Xdebug -Xnoagent -Xrunjdwp:... という定番の並びは「旧エージェントを止めて、JVMTI/JDWP を使う」という意味でした。JVMTI のエージェントを止めるものではありません(それは -agentlib:jdwp で読み込む側です)。
OpenJDK はこのオプションを非推奨にするとき、「もう何リリースも無視されていて、何の機能も提供していない」と書いています。消しても失われる動作はありません(消して終了コード 0 で起動することは実測しました)。リモートデバッグは -agentlib:jdwp=... が担っていて、-Xnoagent とは無関係です。
JAVA_OPTS、Dockerfile の ENV、CI の設定、IDE の実行構成、起動スクリプトなど、JVM 引数を組み立てている場所を全部見てください。-Xnoagent は古いデバッグ設定に紛れて残っていることが多く、-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,... という 20 年前からコピーされ続けている行がそのまま生き延びていることがあります。
予告はいつ出るか(オプションごとに違う)
-Xnoagent を各 JDK で実測した結果です。
| JDK | 結果 |
|---|---|
| 17 / 21 | 無警告で起動(rc=0) |
| 22 | Option -Xnoagent was deprecated in JDK 22 and will likely be removed(警告つき・rc=0) |
| 23 / 24 / 25 | Unrecognized option: -Xnoagent(起動拒否・rc=1) |
非推奨の警告が出るのは 22 の 1 版だけで、その次の 23 でもう拒否されます。17(LTS)や 21(LTS)から 23 以降へ上げると、警告の段を 1 度も見ないまま起動拒否に当たります。
予告のタイミングはオプションごとに違います。 -Xfuture は 17 の時点から Warning: -Xfuture option is deprecated and may be removed を出していて(実測)、削除は 24 です。「まとめて非推奨になり、まとめて消える」わけではないので、1 つ消したからといって残りが安全とは限りません。
-Xfuture は消すだけでなく、読み替える
-Xfuture は JDK 24 で削除され、同じ 24 で -checksource・-cs・-noasyncgc も消えています(実測。17〜23 では警告つきで rc=0、24 以降は Unrecognized option で rc=1)。-Xfuture を消して再起動したら -checksource で止まった、という踏み方をします。
ただし -Xfuture だけは、単に消すと機能が失われます。 これは厳密なクラスファイル検証を有効にするオプションで、実際に働いていました。OpenJDK は削除にあたり、代替として -Xverify:all を挙げています(JDK-8339918)。
# 検証を強めるために -Xfuture を付けていたなら
-Xverify:all # JDK 24 / 25 で受理される(実測)
厳密検証のために意図して付けていたのなら、消すだけでは検証が静かに緩みます。-Xverify:all へ読み替えてください。-checksource / -cs / -noasyncgc には代替がありません(同 release note)。消すだけで済みます。
(-Xverify:none は別物です。こちらは検証を切る指定で、JDK 13 で非推奨になったものの JDK 25 でもまだ警告つきで起動します。取り違えないでください。)
(-t・-tm も JDK 24 の削除一覧にありますが、これは 17→24 の境界にはなりません。launcher が -t/-tm を -Xt/-Xtm に変換して VM へ渡していただけで、その -Xt/-Xtm 自体がずっと未サポートだったからです。JDK 17 の時点で既に拒否されます(実測)。24 の削除は、死んだ変換コードの掃除です。)
フラグを消せないとき:IgnoreUnrecognizedVMOptions
-XX:+IgnoreUnrecognizedVMOptions を付けると、-Xnoagent を残したままでも起動します(実測)。
-XX:+IgnoreUnrecognizedVMOptions -Xnoagent → 起動する
名前は「Unrecognized VM Options」ですが、-XX の VM オプションだけでなく、-X の launcher オプション(-Xnoagent)も黙らせます。ただしこれは起動を通すだけです。他の未知オプションも一律に飲み込むので、フラグを打ち間違えてもエラーになりません。恒久的な設定にはせず、出どころを直すまでの足場に留めてください。
切り分け
- エラー文が
Unrecognized VM option 'X'(VMが付く・クォートあり) → 弾いているのは HotSpot VM で、-XX:のフラグです。別の記事です。Unrecognized VM option 'UseBiasedLocking'(JDK 17 → 21) や CMS のフラグ(Java 8 → 17) を参照してください。 -Xnoagentの隣に-Xdebugが並んでいる → ほぼ必ず並んでいます。-Xdebugは起動を止めません——JDK 22 で非推奨になりましたが、25 でも警告つきで起動します(実測)。原因は-Xnoagentのほうです。-Xdebugもついでに消して構いません。- 1 つ消したら次で止まった →
-Xfutureを消したなら、-checksource・-cs・-noasyncgcが同じ 24 で消えています。まとめて消してください(-Xfutureだけは-Xverify:allに読み替え)。 - 警告が 1 度も出なかったのに、上げたら拒否された →
-Xnoagentは非推奨警告が 22 の 1 版だけです。LTS を渡り歩くと、その版を飛ばします。 -Xnoagentを消すとデバッグに影響するか → しません。-Xnoagentが止めていたのは JDK 1.1 時代の旧デバッグ機構で、いまのリモートデバッグは-agentlib:jdwp=...(-Xrunjdwpの後継)が担っています。両者は無関係です。
検証環境
eclipse-temurin@sha256:83177670e43c17769a5402a60601545318e45e63adf634fb5022340e516cded4(openjdk 23.0.2)、ネットワーク不要- 再現:
java -Xnoagent -cp ... Appが JDK 23 でUnrecognized option: -Xnoagent→ 終了コード 1(main()のAPP_STARTEDは出力されない) - 修正:
-Xnoagentを外して同じ 23.0.2 で終了コード 0・APP_STARTED・シグネチャ消滅(Java のソースは再現・修正で同一) - 17/21 は無警告・22 は非推奨警告・23 以降は拒否の版境界、
-Xfutureが 17 から警告を出し 24 で削除されること、-checksource/-cs/-noasyncgcが 24 で同時に消えること、-t/-tmは 17 で既に拒否されること、-Xverify:allが JDK 24・25 で受理されること、-Xdebugが 23・25 で警告つきで起動すること、-Xmx64mが JDK 25 で問題なく起動すること、IgnoreUnrecognizedVMOptionsが-Xnoagentを残して起動できることは、eclipse-temurinの 17.0.19 / 21.0.11 / 22.0.2 / 23.0.2 / 24.0.2 / 25.0.3(いずれも digest 固定)でそれぞれ実行して確認しました -Xnoagentが JDK 1.1 時代の旧デバッグ機構(sun.tools.agent)を止める指定だったこと、-Xfutureの代替が-Xverify:allであること、-t/-tmの変換が launcher 共通の挙動だったことは、OpenJDK の一次情報(JDK-8312072 / JDK-8339918)に拠ります。-Xfutureが実際にどれだけ検証を強めていたかは実測していません- 上記以外のパッチ版は網羅していません