【Java】実行可能JARの起動方法(ダブルクリック不可時の対処)

Java

コマンドによる起動

はじめに、ひとまず実行可能JARを起動したいだけであれば、これから説明する手順で設定を行う必要はありません。javaコマンドの-jarオプションで実行可能JARを指定してプログラムを実行すればそれで済むためです。( 実行可能JARのダブルクリック

# javaコマンドで実行(-jarオプションで実行可能JARを指定)
> java -jar app-1.0.0.jar

ここでは、javaコマンドで正常に実行できることを確認した上で、より便利に実行可能JARを起動できるようダブルクリックによる起動を行うための設定を説明していきます。

これ以降、対象のJARファイルが、javaオプションの-jarオプションで正常に起動できることを確認済みであることを前提に、設定面からダブルクリックで起動できるようにするための手順を説明していきます。

しかし、そもそも起動しようとしている対象のJARファイル自体に問題がある場合、これ以降の対処方法を実施しても問題は解消されません。そのためまずは対象のJARファイルが、> java -jar {jarfile} で正常に実行できる単一の実行可能JAR(Fat JAR)であることを今一度確認しておく必要があります。

まず第一に 実行可能JAR であることは必須です。実行可能JARの場合、マニフェストファイルにMain-Class属性が定義されており、エントリポイントとなるメインクラスを指定しなくても、javaコマンドの-jarオプションで直接JARを指定しプログラムを起動できます。そのためMain-Class属性がない通常のJARMavenの例)は、次のように-cpコマンドでJARをクラスパスに追加するやり方でなければ実行することができません。

# 実行可能JARでないため-jarオプションにJARファイルを指定してもエラーになる
> java -jar target\app-1.0.0.jar
target\app-1.0.0.jarにメイン・マニフェスト属性がありません

# 実行可能JARでないため-cpオプションでJARをクラスパスに設定した上で
# 引数にはエントリポイントとなるメインクラスを指定して実行する必要がある
#        JARをクラスパス追加      javaコマンドの引数
#       /                        /
#      |----------------------| |--------------|
> java -cp target\app-1.0.0.jar com.example.Main
Person01 has been created!

続いて仮に実行可能JARであっても、Fat JAR でない場合、依存関係の不足でエラーが発生している可能性もあります。この場合、マニフェストファイルのClass-Path属性に記述されたパスに正しく依存先のJARが配置され依存関係が解決されていれば実行できますが、そうでない場合、単体では実行できない実行可能JARであるため、注意が必要です。

いずれにしても、これらのエラーは先に示した通り、一度コンソール上でコマンドによる実行を試行しておけば、エラーの発生有無を事前に確認することができます。

最後に、たとえ正常に実行できる単一の実行可能JARであることが確認できていたとしても、GUIアプリケーションを起動するようなもの(例:LombokJD-GUI)でない限り、例えば標準出力にメッセージを表示するだけのようなプログラムの場合、ダブルクリックで起動したプログラムは正常終了した後すぐにコンソールが閉じてしまう(あるいは javaw.exe による起動の場合はコンソールウィンドウが開くことすらない)ため、正常にプログラムの起動と終了が行われていても、ダブルクリックによって何も起きていないように見えてしまいます。そのため、対象の実行可能JARの起動でエラーが発生しないことだけでなく、そのアプリケーションがどのような処理を起動するプログラムなのかを確認しておくことが肝要です。

ダブルクリックによる起動

前述 の通り、実行可能JARをダブルクリックで起動するというのはすなわち、javaコマンド(正確には多くの場合 javawコマンド )の-jarオプションで実行可能JARを指定してプログラムを実行するということです。従ってここからは、JARファイルをダブルクリックした時に、javaコマンドによって起動されるような設定を行っていきます。

ファイルの関連付け

インストーラを使用してJavaをローカル環境に入れた場合、大抵は何もしなくてもダブルクリックで実行可能JARを起動できるようになっています。しかし上手くいかない場合、この手順を試すことで解消することがあります。

Windowsではファイルの関連付けという仕組みによって、この拡張子のファイルはこのアプリケーションで起動する、ということが制御されています。例えば、拡張子が .txt のファイルをダブルクリックするとそのファイルはメモ帳で開かれ、.xlsx という拡張子のファイルをダブルクリックするとExcelが開かれるのは、この仕組みによるものです。

普段は意識せず当然に感じてしまいますが、例えばファイルのアイコン等もファイルの中身で判断しているのではなく、あくまで拡張子に関連付けられたアプリケーションが何かということによって表示が切り替わっているにすぎません。( ファイルの種類ハンドラー

手順は次の通りです。まず対象のJARファイルを右クリックして表示されるメニューから(または Alt + Enter で)プロパティを開きます。続いてプラグラムの[変更(C)..]を押下し、表示されたメニューからJavaを選択します。[OK]または[適用(A)]でプロパティを閉じると、関連付けが完了します。関連付けによってアイコン表示も変わるため、正しく適用されたことを確認できます。

この状態で再度ダブルクリックすると、関連付けられたjavaコマンドによって実行可能JARが実行され、アプリケーションを起動することができるようになります。

多くの場合はこの手順だけで起動できるようになりますが、ZIP版のJavaをダウンロードして使用している場合など、通常はインストーラによって行われる設定が不十分なため、これだけでは解決しないこともあります。そのような場合、次の手順に従って手動での設定追加が必要です。

レジストリの編集

ファイル拡張子とプログラム識別子

ファイルの関連付け により、Windowsのレジストリには、ファイル拡張子(<file_extension>キー)と プログラム識別子ProgID キー)が登録されます。( 動詞とその他のファイルの関連付け情報の登録

どちらも HKEY_CLASSES_ROOT 直下にあり、実行コマンドが登録された ProgID が、<file_extension> によって、ファイル名の拡張子に関連付けられています。

例)ProgID が「jar_auto_file」
HKEY_CLASSES_ROOT
   .jar
      (既定) = jar_auto_file
   jar_auto_file
      shell
         open
            command
               (既定) = "C:\Users\xxx\jdk\bin\javaw.exe" -jar "%1" %*

これらは、レジストリエディタ や reg commands で確認することが可能です。

▼ レジストリエディタの場合

reg query コマンド の場合

> reg query "HKEY_CLASSES_ROOT\.jar"

HKEY_CLASSES_ROOT\.jar
    (既定)    REG_SZ    jar_auto_file

> reg query "HKEY_CLASSES_ROOT\jar_auto_file\shell\open\command"

HKEY_CLASSES_ROOT\jar_auto_file\shell\open\command
    (既定)    REG_SZ    "C:\Users\xxx\jdk\bin\javaw.exe" -jar "%1" %*

ここで重要なのが、拡張子「 .jar 」に関連付けられた ProgID(ここでは「jar_auto_file」)に、どのようなコマンドが設定されているかということです。この例では、"javaw.exe" -jar "%1" %* というコマンドが設定されています。従って .jar がダブルクリックされると、そのファイルに対して > "javaw.exe" -jar "%1" %* が実行される状態であるということです。(※ProgIDには「jarfile」など環境によって「jar_auto_file」と異なる名称が設定されている可能性があります。後述

前述 の実行可能JARの説明では、例としてjava.exeを使用していました。しかし実際には、実行可能JARを起動する場合はjavaw.exeを使用するのが一般的です。両者の違いは、コンソールウィンドウを表示するか否かのみで、それ以外に機能の差はありません。従って、javaコマンドの例と同様にjarオプションを使用することで実行可能JARを起動することができます。

# javaコマンドで実行(-jarオプションで実行可能JARを指定)
> java -jar app-1.0.0.jar

# javawコマンドでも同様に実行可能(機能面での違いはない)
> javaw -jar app-1.0.0.jar

javawコマンドは、javaと同じです。ただし、javawにはコンソール・ウィンドウが関連付けられていない点が異なります。 コマンド・プロンプト・ウィンドウが表示されないようにする場合は、javawを使用します。

javaコマンド > 説明 > javaw

実行可能JARをダブルクリックで起動する際、アプリケーションと一緒にコンソールウィンドウも開いてしまうのを抑制できるため、多くの場合javaw.exeが使用されます。

引数の形式については、ftypeコマンドのページに同様の説明があります。

"javaw.exe" -jar "%1" %* の場合、初めにダブルクリックされたJARファイルが引数に渡され、それ以降は複数のコマンドライン引数を受け入れる設定ということになります。

VariableReplacement value
%0 または %1関連付けを通じて起動されるファイル名に置き換えられる値を取得します。
%*すべてのパラメーターを取得します。
%2、 %3、 …最初のパラメーター (%2)、2 番目のパラメーター (%3) などを取得します。
%~<n>n番目のパラメータから始まる残りのすべてのパラメータを取得します (n は 2 から 9 までの任意の数値にすることができます)。

Windows コマンド > ftype > Remarks

なお、本記事でレジストリエディタを例示しながら説明しているファイル拡張子の関連付けと実行コマンドの設定は、HKEY_LOCAL_MACHINEレジストリの説明 )にある場合に限り、assocftype の二つのコマンドで同じことを実現できます。

ダブルクリックによる起動ができないデフォルト設定

前述 のファイル関連付け設定を行っても上手くいかない場合、デフォルトでここに次のようなコマンドが登録されている可能性があります。( デフォルト状態の参考

例)ProgID が「jar_auto_file」
HKEY_CLASSES_ROOT
   .jar
      (既定) = jar_auto_file
   jar_auto_file
      shell
         open
            command
               (既定) = "C:\Users\xxx\jdk\bin\java.exe" "%1"

これはオブジェクト動詞の構文の通り、アプリケーション起動の “open” が設定されて HKEY_CLASSES_ROOT\jar_auto_file\shell\open\command となり、ショートカットメニューの動詞 は実行コマンドに対して引数が一つだけ設定された "xxx.exe" "%1" がデフォルトの状態であるためと考えられます。

通常は指定したプログラムファイルに引数が一つ指定される形式で問題にならないことが多いかもしれません。しかしjavaコマンドで実行可能JARを起動する場合に関して言えば、この点が問題になります。前述 の通り、-jarオプションを使用する必要があるためです。

# 実行可能JARは -jar オプションで起動する
> java -jar app-1.0.0.jar
Person01 has been created!

# javaコマンドの引数には通常メインメソッドが定義されたクラスを指定するため
# 実行可能JARを直接引数に指定するとエラーになる
> java app-1.0.0.jar
エラー: メイン・クラスapp-1.0.0.jarを検出およびロードできませんでした
原因: java.lang.ClassNotFoundException: app-1.0.0.jar

デフォルトでは、javaコマンドのオプションではない最初の引数は、コールされるクラスの完全修飾名です。 -jarが指定されている場合、その引数は、アプリケーションのクラスおよびリソース・ファイルを含むJARファイルの名前です。 起動クラスは、マニフェスト・ファイルのMain-Classマニフェスト・ヘッダーで指定する必要があります。

クラス・ファイル名またはJARファイル名の後にある引数は、main()メソッドに渡されます。

javaコマンド > 説明

ファイルの関連付け で問題が解消しない場合、このようにレジストリへ "java.exe" "%1" が登録されており、実行時にエラーが発生して起動できない状況ということになります。(前述 の通りjavaw.exeはそもそもコンソールウィンドウが表示されず、また仮にjava.exeが設定されていた場合でも、エラーによるプログラム終了後はすぐにコンソールウィンドウが閉じてしまうため、エラーの発生に気付けず、ダブルクリックしても何も起きていないように見えてしまうことが、問題の原因を分かりにくくしている一因かもしれません。)

登録されたコマンドを修正する方法

従って、この設定を変更すれば解消することができます。前述 した通り、まずはファイル拡張子.jar」に関連付けられた ProgID を確認します(この例では「jar_auto_file」)。そして、そこに設定されたコマンドを、-jarオプションを使用した正しいものに修正することで、正常に実行可能JARを起動できるようになります。

ここまでの例では、ProgID に「jar_auto_file」が設定されているものとして説明を進めてきました。これは、事前に設定が行われていなかった際、ファイルの関連付け の手順によって自動で定義された時の名称がこの形式になるためです。Windowsではデフォルトで「{拡張子名}_auto_file」の形式で ProgID の命名が決定されるようです。

一方で、ファイル拡張子「.jar」の ProgID には、しばしば「jarfile」という名前で登録されることがあります。これは、Javaのインストーラによって登録される際の名称です。(これはドキュメントで明言されていることではありませんが、バグレポートからjarfileという名称が使用されていることを確認できます。)この場合でも同様にコマンドとその引数の設定を正しく修正することで対応が可能です。

しかしOracleのJavaインストーラを使用してローカル環境にJavaを導入している場合、併せてレジストリ設定も行われるため、そもそもダブルクリックで実行可能JARを実行できないというトラブルが発生することは少ないと考えられます。そのためここでは「jar_auto_file」を例に使用しています。

インストーラ版では自動で設定が行われるため、ダブルクリックで実行可能JARを起動できないというトラブルは、手動設定が必要なZIP版のJavaを使用している環境で起こりやすいとも言えます。

ここでは引数の設定を "javaw.exe" -jar "%1" %* とすることで、実行可能JARに加え、Javaプログラムに渡すコマンドライン引数も指定できるようにしています。(%を用いた引数の意味は 前述 の通りです。)また、実行可能JARの起動には通常java.exeでなくjavaw.exe前述 )が使用されます。

javaw.exe までの絶対パスや %1 に入るJARファイルにはスペースが含まれる可能性があるため、それぞれ二重引用符で囲み「"javaw.exe" -jar "%1" %*」としておくのが安全です。

コマンド文字列のいずれかの要素にスペースが含まれている場合、またはスペースを含む可能性がある場合は、引用符で囲む必要があります。

文字列にスペースが含まれていないことを確信できないため、Shellによって文字列に展開される “%1” などの引数には、常に引用符を使用する必要があります。

動詞とファイルの関連付け > ショートカット メニューの動詞