実行可能なJARファイル

問題

Mavenプロジェクトで生成されたJARファイルが'java -jar'コマンドで実行できないときの話。

$ java -jar your_app.jar
no main manifest attribute, in your_app.jar

原因

your_app.jarファイルを展開してみるとMANIFEST.MFにMain-Classの指定がない。

$ cat META-INF/MANIFEST.MF 
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: xxxxxxxxxx
Build-Jdk: 1.8.0_101

JARファイルの仕様についてはこちら。 JAR File Specification

対策

このような場合には、pom.xmlに以下のプラグインを追加することで、MANIFEST.MFの設定を行う。

<plugins>      
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.5.2</version>
    <configuration>
      <finalName>executable_app</finalName>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <appendAssemblyId>false</appendAssemblyId>
      <archive>
        <manifest>
          <mainClass>com.mypackage.MyClass</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <id>make-assembly</id>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>

結果

出力されたexecutable_app.jar内のMETA-INF/MANIFEST.MFにはmainClassタグの指定に従ってMain-Classが追加されている。

$ cat MANIFEST.MF 
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: xxxxxxxxxx
Created-By: Apache Maven 3.0.5
Build-Jdk: 1.8.0_101
Main-Class: com.mypackage.MyClass

executable_app.jarはコマンドラインから次の通り実行可能となる。

$ java -jar executable_app.jar