概要
「スッキリわかる Java入門 実践編 第2版」13章 練習13-2,練習13−3に取り組んでいた際に、
パッケージに所属したclassファイルのJarファイル生成とJarファイル実行でつまづいたので、
その際に行ったことを本記事にて紹介したします。
*クラス名、パッケージ名は書籍とは別の名称、ソースコードは書籍よりも簡素なものを例として取り上げております。
環境
OS: macOS Catalina 10.15.6
JDK:14.0.1
状況
ターミナルにて実行
①パッケージ「hoge」に格納した「Main.java」のJarファイルを生成
//カレントディレクトリを設定
HIrokinoMacBook-Pro:~ user$ cd /Users/user/src/Java/sukiri1/Chapter6/hoge
//jarを生成
HIrokinoMacBook-Pro:hoge user$ jar -cvfm test.jar manifest.txt Main.class
マニフェストが追加されました
Main.classを追加中です(入=417)(出=284)(31%収縮されました)
/Users/user/src/Java/sukiri1/Chapter6/hogeに「test.jar」が作成されました。
②生成したJarが実行できない
//jarファイル実行
HIrokinoMacBook-Pro:hoge user$ java -jar test.jar
エラー: メイン・クラスhoge.Mainを検出およびロードできませんでした
原因: java.lang.ClassNotFoundException: hoge.Main
各ファイルの内容
●Main.java
hogeパッケージにMainクラスを格納
package hoge;
public class Main {
public static void main(String[] args) {
System.out.println("hello.java");
}
}
下記ディレクトリに格納
/Users/user/src/Java/sukiri1/Chapter6/hoge/Main.java
●マニフェスト内容
Manfest-Version: 1.0
Main-Class: hoge.Main
※manifest.textを作成する際は、「Main-Class: パッケージ名.クラス名」の後に改行がないと、
実行時に**「〇〇.jarにメイン・マニフェスト属性がありません」**というエラーが出てしまいます。
↓参考
https://ameblo.jp/syosinsyaprogram/entry-11775802006.html
http://daiad.webcrow.jp/java/jar.html
対処法
###①パッケージが格納されている階層をカレントディレクトリに設定する
当初、カレントディレクトリを「cd /Users/user/src/Java/sukiri1/Chapter6/hoge」に設定していたが、
「cd /Users/user/src/Java/sukiri1/Chapter6」へ変更する(一階層上に設定)
HIrokinoMacBook-Pro:hoge user$ cd /Users/user/src/Java/sukiri1/Chapter6
HIrokinoMacBook-Pro:Chapter6 user$
###②jar生成のコマンドに含まれるマニフェストのtxtファイルとクラスファイルがパッケージに含まれていることを明記する
当初、「jar -cvfm test.jar manifest.txt Main.class」としていたが、「manifest.txt」と「Main.class」が「hoge」パッケージに含まれていることを、「hoge/」を加え以下のように明記しターミナルで実行する。
jar -cvfm test.jar hoge/manifest.txt hoge/Main.class
/Users/user/src/Java/sukiri1/Chapter6に「test.jar」が作成される。
①②について、
カレントディレクトリをパッケージに設定(今回の場合「hoge」)した状態で、jarファイルを生成すると、
jarファイル内にそのパッケージが存在しないjarが生成されてしまいます。(今回の場合パッケージ「hoge」がないjar)
そのため、「java -jar」でjarを実行した時に、マニフェストの「Main-Class:」 には「hoge.Main」と指定されているのに、
実際生成されたjarファイルには「hoge」パッケージに格納された「Main.class」がなく、
今回のように「エラー: メイン・クラスhoge.Mainを検出およびロードできませんでした」と表示され、
「hoge.mainなんてクラス見つかりませんでしたよ?」と指摘されてしまったのです。
それではjarを実行してみます。
HIrokinoMacBook-Pro:Chapter6 user$ java -jar test.jar
hello.java
成功しました。
終わりに
もしマニフェストを利用したjarファイルの生成と実行で同様のエラーに見舞われた場合は、
カレントディレクトリが適切か、jar生成のコマンドにおいてパッケージの構成が適切か、
マニフェストの「Main.class」はどのように記述されているかを見直してみるといいと思います!