Java言語でプログラム開発を行う際、意識していなくてもjarファイルを利用している機会は多いものです。
一方で、jarファイルの操作方法が曖昧なまま利用している方も多いのが実状です。
本記事では、基本に立ち返ってコマンドからjarファイルを実行する方法についてご紹介していきます。
jarファイルの作成方法など基本情報と合わせてご紹介しますので、コマンド操作に不慣れな方もぜひご確認ください。
目次
jarファイルの仕組みを理解しよう
Java開発で利用されるjarファイルは、「Java Archive」の略称で、複数のファイルを圧縮してまとめることが出来るアーカイブファイルです。
jarファイルは、ただ圧縮したファイルというわけではなく、アプリケーションとして実行可能なファイルです。
jarファイルにはコンパイル済みのJavaファイルを含める
jarファイルを作成する際、Javaのソースコードやシステムで必要な画像ファイルなどをまとめて圧縮し、1つのアーカイブファイルとします。
Javaは拡張子「.java」の状態ではプログラムを実行することが出来ないため、コンパイルした「.class」拡張子のファイルを作成後、jarファイルに圧縮する必要があります。
Javaのコンパイル方法に関しては、「Mac環境でJavaファイルをコンパイルして実行する方法とは!?」の記事で解説しています。
jarファイルは圧縮したままの状態で実行可能
jarファイルは、圧縮したままの状態でJavaの実行環境で動かすことが出来るため、HTTPコネクションの数を減らし、ウェブサーバーの負荷を減らすことが可能となっています。
圧縮してファイル容量を減らせるだけでなく、手軽に実行可能なファイルであることから、Javaアプリケーションやライブラリの配布形式として頻繁に利用されています。
jarファイルを作成してJavaプログラムを実行してみよう
実際にサンプルを通してjarファイルの作成から実行までの方法を確認していきましょう。
サンプル
今回のサンプルでは「Main.java」と「Sub.java」のファイルを用意して、コンパイルしたクラスファイルを「Document」配下の「sample」フォルダに格納した状態で実施しています。
sample $ ls Main.class Main.java Sub.class Sub.java
Main.javaの内容
import java.io.*; public class Main { public static void main(String[] args) throws Exception { Sub sub = new Sub(); System.out.println(sub.content); } }
Sub.javaの内容
public class Sub { String content = "Subクラスからの出力です。"; }
マニフェストファイルの作成
jarファイルを実行するには、マニフェストファイルと呼ばれる定義ファイルが必要となりますので、あらかじめ作成しておきましょう。
保存するファイル名は拡張子が「.mf」であれば自由に指定出来ますが、今回は「app.mf」と指定して作成していきます。
ファイル内部の記述方法は、Mainメソッドが記述されたクラス名を「Main-Class:クラス名」の方式で設定します。
Main-Class: Main
今回はMain.javaにMainメソッドが記述されているため、クラス名には「Main」を指定しています。
jarファイルの作成
jarファイルを作成するコマンドは下記のように記述します。
jar [-オプション] [jarファイル名] [マニフェスト名] [圧縮したいファイルを指定]
オプションで指定した内容により、オプション以降の記述内容は異なります。
ではもう少し具体的にサンプルで確認してみましょう。
jar -cvfm test.jar app.mf *.class
サンプルの場合、新規で「test.jar」を作成し、圧縮するファイルには「.class」が拡張子のファイルを指定しています。
マニフェストファイルには「app.mf」を指定しており、ターミナルに処理内容を表示するオプションも合わせて記述しています。
実行して表示内容を確認してみましょう。
sample $ jar -cvfm test.jar app.mf *.class マニフェストが追加されました Main.classを追加中です(入=513)(出=338)(34%収縮されました) Sub.classを追加中です(入=281)(出=243)(13%収縮されました)
lsコマンドでjarファイルが作成されていることを確認しておきましょう。
sample $ ls Main.class Sub.class app.mf Main.java Sub.java test.jar
jarファイルの実行
jarファイルの実行は「java」コマンドにjarオプションを付与する形式でコマンドを入力します。
java -jar jarファイル名
サンプルで実行すると下記のように出力されます。
sample $ java -jar test.jar Subクラスからの出力です。
今回のサンプルでは、Main.javaからSub.javaに記述された内容の文字列をターミナルに出力するという簡単なサンプルを作成していましたので、きちんと実行されていることが確認出来ます。
jarファイル実行後の表示内容は、作成したプログラムにより異なります。
外部jarファイルを連携させてJavaプログラムを実行する方法
Javaシステムを開発する上で、利用するjarファイルが1つとは限りません。
jarファイルから外部のjarファイルを呼び出して実行したいようなケースも存在するため確認しておきましょう。
サンプル
上記でご紹介した「Main.java」と「Sub.java」をそれぞれ別々のjarファイルとして下記のコマンドで作成してみましょう。
まずは「Sub.java」をコンパイルした「Sub.class」だけのjarファイルを作成します。
sample $ jar -cvf sub.jar Sub.class マニフェストが追加されました Sub.classを追加中です(入=281)(出=243)(13%収縮されました)
次に「Main.java」をコンパイルした「Main.class」だけのjarファイルを作成します。
sample $ jar -cvfm main.jar app.mf Main.class マニフェストが追加されました Main.classを追加中です(入=513)(出=338)(34%収縮されました)
この状態でmain.jarを実行しても下記のようにエラーとなり動かすことが出来ません。
sample $ java -jar main.jar Exception in thread "main" java.lang.NoClassDefFoundError: Sub
マニフェストファイルを変更する
jarファイルから外部jarファイルの処理を実行するには、マニフェストファイルにパスを通すことで実現することが可能です。
app.mfファイルを下記のように変更してみましょう。
Class-Path: sub.jar Main-Class: Main
1行目に記述した「Class-Path」で、同一階層の「sub.jar」を読み込むように設定しました。
では再度下記のコマンドでmain.jarを作成しなおし実行してみましょう。
jar -cvfm main.jar app.mf Main.class
実行した結果が下記の通りです。
sample $ java -jar main.jar Subクラスからの出力です。
異なるjarファイルの処理を呼び出して、実行出来ていることをご確認頂けます。
さいごに: jarファイルを利用したJavaプログラム実行方法の基本を理解しておこう
本記事では、コマンドからjarファイルのJavaプログラムを実行する方法についてご紹介してきました。
現在IDEを活用した開発が主流の中、コマンドでの操作方法を知らない方も増えてきているようですが、基本を抑えておくことはとても重要です。
仕組みを理解することはもちろん、IDEを利用出来ず、コマンドからプログラムを実行する機会というのもまだまだ存在するため、基本的な使い方は最低限理解しておくようにしましょう。
注意点として、「Main-Class:」の後ろに半角スペースを入れることと、文末で改行した上保存するようにしてください。
半角スペースや文末で改行されていない場合、正常に動作しないケースがあるようです。