【初心者向け】java -jar コマンドでJVM(-D)オプションが効かない、ライブラリがバグってるんじゃないかと言いたくなったとき。


背景

Java製のOSSや社内に閉じたライブラリを開発していると、こんな問い合わせを受けることが何度かあったので、せめてQiitaに書いておけばググって自己解決してくれるのではないかという淡い期待をこめて。

問い合わせはこんな感じ

パターン1

ライブラリのドキュメントには、-Dxxxx=yyyyを指定すると、xxxxオプションが有効になると書いてありますが、動作しません。ライブラリがバグってませんか?

パターン2

組み込みTomcat(またはJettyなど)を使用したjarを起動する際、JMXを有効にするために-Dcom.sun.management.jmxremoteやそのほかJMXのオプションをつけてますが、アプリケーションを起動してもJMXのポートがLISTENになりません。

組み込みTomcat(またはJettyなど)のパラメータ調整が必要でしょうか?

バグってるのはライブラリでもServletコンテナでもない

誤ったコマンド
java -jar zzzz.jar -Dxxxx=yyyy -Dcom.sun.management.jmxremote

一見特段問題なく見えるんですが、正しくは下記の通りです。

正しいコマンド
java -Dxxxx=yyyy -Dcom.sun.management.jmxremote -jar zzzz.jar 

要するに、-jarオプションの後にJVM引数を指定するなって話ですね

ちなみに、java -helpコマンドで、ちゃんと順序は明示されています。言うまでもなく[options]がJVMオプションで、[args]がプログラムが処理するコマンドライン引数ですね。

$ java -help

使用方法: java [options] <mainclass> [args...]
           (クラスを実行する場合)
   または  java [options] -jar <jarfile> [args...]
           (jarファイルを実行する場合)
   または  java [options] -m <module>[/<mainclass>] [args...]
       java [options] --module <module>[/<mainclass>] [args...]
           (モジュールのメイン・クラスを実行する場合)
   または  java [options] <sourcefile> [args]
           (単一のソースファイル・プログラムを実行する場合)

 メイン・クラス、ソース・ファイル、-jar <jarfile>、
 -mまたは--module <module>/<mainclass>に続く引数は、メイン・クラスへの引数として
 渡されます。

... 以下、略

最後に

JVMオプションが効かない!?ってときは、他人を疑う前に、まずは自分の打ち込んだコマンドをご確認ください。