Java で'no main manifest attribute'エラーを修正する方法

JavaBeginner
オンラインで実践に進む

はじめに

Java アプリケーションを JAR (Java Archive) ファイルとしてパッケージ化し実行する際、開発者はしばしば「no main manifest attribute」エラーに遭遇します。このエラーは、JAR ファイルを実行しようとした際に、Java Virtual Machine (JVM) がアプリケーションを開始するための main メソッドを含むクラスを特定できない場合に発生します。

この実験(Lab)では、この一般的なエラーの理解、診断、および解決方法を案内します。このチュートリアルを終える頃には、main クラスを正しく指定するマニフェストファイルを使用して、JAR ファイルを適切に構成する方法を習得しているでしょう。

簡単な Java アプリケーションの作成

JAR ファイルにパッケージ化する簡単な Java アプリケーションを作成することから始めましょう。これにより、「no main manifest attribute」エラーを実演し、後で修正することができます。

Java クラスの作成

まず、Java ソースファイルのディレクトリを作成し、そこに移動します。

cd ~/project/src/com/example

次に、エディタを開き、このディレクトリにHelloWorld.javaという名前の新しいファイルを作成します。

  1. WebIDE の左側のサイドバーにある「Explorer」アイコンをクリックします。
  2. /home/labex/project/src/com/exampleに移動します。
  3. 右クリックして「New File」を選択します。
  4. ファイル名をHelloWorld.javaとします。

HelloWorld.javaファイルに以下のコードを追加します。

package com.example;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

これは、実行時にコンソールに「Hello, World!」と出力するmainメソッドを持つ基本的な Java プログラムです。

Java クラスのコンパイル

次に、Java クラスをコンパイルしましょう。ターミナルに戻り、プロジェクトのルートディレクトリに移動します。

cd ~/project

javacコマンドを使用して Java ファイルをコンパイルします。

javac -d . src/com/example/HelloWorld.java

このコマンドは、Java ソースファイルをコンパイルし、パッケージ名に基づいてコンパイルされたクラスファイルを適切なディレクトリ構造に配置します。

これで、~/project/com/example/HelloWorld.classにコンパイルされたクラスファイルが作成されます。以下で確認できます。

ls -l com/example/

出力には、HelloWorld.classファイルが表示されます。

total 4
-rw-r--r-- 1 labex labex 426 [date] HelloWorld.class

マニフェストなしの基本的な JAR ファイルの作成

次に、マニフェストで main クラスを指定せずに JAR ファイルを作成しましょう。これにより、「no main manifest attribute」エラーを再現できます。

jar cf HelloWorld.jar com/

このコマンドは、コンパイルされたクラスファイルを含むHelloWorld.jarという名前の JAR ファイルを作成します。

JAR ファイルの実行を試す

JAR ファイルを作成したので、実行してみましょう。

java -jar HelloWorld.jar

次のエラーメッセージが表示されます。

no main manifest attribute, in HelloWorld.jar

これが、私たちが修正しようとしているエラーです。JAR のマニフェストで main クラスを指定しなかったため、JVM は実行する main クラスを見つけることができません。

「no main manifest attribute」エラーの理解

このステップでは、「no main manifest attribute」エラーの原因を探り、JAR ファイルの manifest の仕組みを理解します。

マニフェストファイルとは?

JAR ファイルには、META-INFディレクトリにMANIFEST.MFと呼ばれる特別なファイルが含まれています。このマニフェストファイルには、JAR とその内容に関するメタデータが含まれています。マニフェストが含めることができる重要な情報の 1 つは、Main-Class属性です。これは、JAR が実行されたときに実行する main メソッドを含むクラスを JVM に指示します。

現在の JAR ファイルのマニフェストを調べてみましょう。

mkdir -p temp_dir
cd temp_dir
jar xf ../HelloWorld.jar META-INF/MANIFEST.MF
cat META-INF/MANIFEST.MF

次のような最小限のマニフェストが表示されます。

Manifest-Version: 1.0
Created-By: 1.8.0_XXX (Oracle Corporation)

このマニフェストにはMain-Class属性がないことに注意してください。これが、JAR を実行しようとしたときに「no main manifest attribute」エラーが発生する理由です。

JAR ファイルの内容を表示する方法

JAR ファイルをよりよく理解するために、その内容を見てみましょう。

cd ~/project
jar tf HelloWorld.jar

このコマンドは、JAR 内のすべてのファイルを一覧表示します。出力は次のようになります。

META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/HelloWorld.class

ご覧のとおり、JAR には期待どおりコンパイルされたクラスファイルが含まれていますが、マニフェストには main クラスを識別するために必要な情報がありません。

このエラーはいつ発生しますか?

「no main manifest attribute」エラーは、通常、次のような状況で発生します。

  1. マニフェストで main クラスを指定せずに JAR ファイルが作成された場合
  2. java -jarを使用して JAR ファイルを実行しようとしたが、JAR が実行可能になるように意図されていない場合
  3. マニフェストファイルが存在するが、Main-Class属性が含まれていない場合

今回のケースでは、エラーを実演するために、意図的に main クラスを指定せずに JAR を作成しました。

一時ディレクトリをクリーンアップしましょう。

cd ~/project
rm -rf temp_dir

エラーの原因を理解したので、次のステップでは、適切なマニフェストファイルを作成して修正します。

マニフェストファイルの作成

問題点を理解したので、main クラスを指定する適切なマニフェストファイルを作成して修正しましょう。

マニフェストファイルの作成

まず、プロジェクトディレクトリに戻ります。

cd ~/project

次に、manifest.txtというテキストファイルを作成します。

  1. WebIDE の左側のサイドバーにある「Explorer」アイコンをクリックします。
  2. /home/labex/projectに移動します。
  3. 右クリックして「New File」を選択します。
  4. ファイル名をmanifest.txtとします。

manifest.txtファイルに次の内容を追加します。

Main-Class: com.example.HelloWorld

ファイルの最後に改行を追加してください(マニフェスト形式では、ファイルが改行で終わる必要があります)。WebIDE では、上記の行を入力した後、Enter キーを押すだけです。

このシンプルなマニフェストファイルは、com.example.HelloWorldクラスに、JAR の実行時に実行される main メソッドが含まれていることを指定します。

マニフェストを使用して新しい JAR ファイルを作成する

次に、新しい JAR ファイルを作成します。今回は、カスタムマニフェストを含めます。

jar cfm HelloWorldWithManifest.jar manifest.txt com/

このコマンドは、コンパイルされたクラスファイルを含み、カスタムマニフェストファイルを使用する、HelloWorldWithManifest.jarという名前の新しい JAR ファイルを作成します。

このコマンドで使用されるオプションは次のとおりです。

  • c: 新しいアーカイブを作成します
  • f: アーカイブファイル名を指定します
  • m: 指定されたマニフェストファイルからマニフェスト情報を含めます
  • 残りの引数は、JAR に含めるファイル/ディレクトリです

新しい JAR のマニフェストを確認する

マニフェストが JAR に正しく含まれているかどうかを確認しましょう。

mkdir -p temp_check
cd temp_check
jar xf ../HelloWorldWithManifest.jar META-INF/MANIFEST.MF
cat META-INF/MANIFEST.MF

マニフェストにMain-Class属性が含まれるようになったことがわかります。

Manifest-Version: 1.0
Created-By: [Java version info]
Main-Class: com.example.HelloWorld

次に、一時ディレクトリをクリーンアップしましょう。

cd ~/project
rm -rf temp_check

修正された JAR ファイルの実行

main クラスを指定する適切なマニフェストファイルを使用して JAR ファイルを作成したので、それを実行し、正しく動作することを確認しましょう。

JAR ファイルの実行

プロジェクトディレクトリにいることを確認してください。

cd ~/project

次に、java -jarコマンドを使用して JAR ファイルを実行します。

java -jar HelloWorldWithManifest.jar

今回は、「no main manifest attribute」エラーではなく、プログラムからの出力が表示されるはずです。

Hello, World!

おめでとうございます。main クラスを指定する適切なマニフェストファイルを作成することにより、「no main manifest attribute」エラーを正常に修正しました。

修正内容の理解

エラーを修正するために何をしたのかを理解するために、少し時間をかけましょう。

  1. Main-Class属性を含むマニフェストファイルを作成し、実行する main メソッドを含むクラスを JVM に指示しました。
  2. このマニフェスト情報を組み込んだ新しい JAR ファイルを作成しました。
  3. java -jarコマンドを使用して JAR を実行し、JVM は main メソッドを見つけて実行することができました。

main クラスを指定する別の方法

JAR ファイルを操作する際に、main クラスを指定する他の方法がいくつかあります。

方法 1:JAR 作成時に main クラスを指定する

別のマニフェストファイルを作成する代わりに、eオプションを使用して、JAR の作成時に main クラスを直接指定できます。

jar cfe HelloWorldDirect.jar com.example.HelloWorld com/

これにより、main クラスがcom.example.HelloWorldとして指定された、HelloWorldDirect.jarという名前の新しい JAR ファイルが作成されます。

これが動作することを確認するために、この JAR を実行しましょう。

java -jar HelloWorldDirect.jar

出力が表示されるはずです。

Hello, World!

方法 2:マニフェストを使用せずに JAR を実行する

適切なマニフェストがない JAR ファイルがある場合でも、javaコマンドで main クラスを直接指定することで実行できます。

java -cp HelloWorld.jar com.example.HelloWorld

このコマンドは、JVM にクラスパス(-cp)でHelloWorld.jarを使用し、com.example.HelloWorldクラスを実行するように指示します。

出力が表示されるはずです。

Hello, World!

このアプローチは、実行するクラスを JVM に明示的に指示することにより、マニフェストの必要性を回避します。

まとめ

この実験では、Java の「no main manifest attribute」エラーとその解決方法について学びました。これまでの内容を振り返ってみましょう。

  1. エラーの理解: 「no main manifest attribute」エラーは、JAR ファイル内の実行する main クラスがマニフェストで指定されていないため、JVM がそれを見つけられない場合に発生します。

  2. 適切なマニフェストの作成: Main-Class属性を使用して main クラスを指定するマニフェストファイルの作成方法を学びました。

  3. マニフェストを使用した JAR ファイルの構築: マニフェスト情報を含む JAR ファイルの作成方法を学びました。

    • 別のマニフェストファイルを使用する(jar cfm ...
    • JAR 作成時に main クラスを直接指定する(jar cfe ...
  4. JAR ファイルの実行: JAR ファイルとしてパッケージ化された Java アプリケーションを実行するさまざまな方法を学びました。

    • 適切に設定されたマニフェストを使用してjava -jarを使用する
    • クラスパスと main クラスを明示的に指定するためにjava -cpを使用する

これらのスキルは、アプリケーションを JAR ファイルとしてパッケージ化して配布する必要がある Java 開発者にとって不可欠です。マニフェストの役割と、それを正しく設定する方法を理解することで、「no main manifest attribute」エラーを回避し、Java アプリケーションがスムーズに実行されるようにすることができます。

適切なパッケージングは、優れたコードを書くことと同じくらい重要であることを忘れないでください。ビルドとパッケージングを正しく設定する時間をかけることで、後であなたとユーザーのフラストレーションを回避できます。