Spring Boot jarにメイン・マニフェスト属性がありませんを解決する方法

Spring Bootで開発したアプリケーションを jar 起動した場合、「アプリ名.jarにメイン・マニフェスト属性がありません」というエラーが出た場合に解決する方法です。

Spring Boot jarにメイン・マニフェスト属性がありませんを解決する方法

これは作成された jar ファイル内の META-INF/MANIFEST.MF に、Main-Class の指定がないことで起こるエラーです。エラー自体は Spring Boot に特化したものではありませんが、Spring Boot でパッケージしたときに発生したので、こんなタイトルになっています。

実は Spring Boot で開発したアプリを jar で起動できるようにするには、pom.xml に色々書かないといけません。

ここでは Spring Boot で開発したアプリケーションを jar 起動できるところまで紹介します。


環境

MANIFEST.MFにMain-Class指定を追加

pom.xml の plugins に下記を追加します。


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
  <archive>
    <manifest>
      <addClasspath>true</addClasspath>
      <addExtensions>true</addExtensions>
      <mainClass>springbootapp.App</mainClass>
      <classpathPrefix>lib</classpathPrefix>
    </manifest>
  </archive>
</configuration>
</plugin>

mainClass に「@SpringBootApplication」アノテーションを付与したクラス名を書きます。

このままビルドして jar 実行しても次のエラーが出ます。


Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication
        at springbootapp.App.main(App.java:11)
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 1 more

これは Spring 関係のクラスが見つからないために発生しているエラーです。jar を解凍してみるとわかりますが、Spring 関係のライブラリはパッケージされていないのです。

解決するには pom.xml に下記を追加します。


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
</plugin>

maven-shade-plugin を利用することで、依存するライブラリも含んだ jar を作成することができます。

pom.xml の全文はこうです。


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>helloworldboot</groupId>
  <artifactId>springbootapp</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>springbootapp</name>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.1.RELEASE</version>
  </parent>
  <properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.0.5</thymeleaf-layout-dialect.version>
    <thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.version>
    <thymeleaf-extras-data-attribute.version>2.0.5</thymeleaf-extras-data-attribute.version>
    <thymeleaf-extras-java8time.version>3.0.0.RELEASE</thymeleaf-extras-java8time.version>
  </properties>
  <build>
    <finalName>springbootapp</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>${java.version}</source>
          <target>${java.version}</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <addExtensions>true</addExtensions>
              <mainClass>springbootapp.App</mainClass>
              <classpathPrefix>lib</classpathPrefix>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
  </dependencies>
</project>

再度 jar を起動してみると・・・


C:/Eclipse/4.6/workspace/springbootapp>java -jar target/springbootapp.jar

  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _    
( ( )___ | '_ | '_| | '_ / _` |    
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |___, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v0.0.1-SNAPSHOT)

2016-11-22 13:39:36.339  INFO 6468 --- [           main] springbootapp.App

おおお、無事起動できましたね^^

参考サイト

まとめ

Spring Bootで開発したアプリケーションを jar 起動した場合、「アプリ名.jarにメイン・マニフェスト属性がありません」というエラーが出た場合に解決する方法を紹介しました。

Eclipse 上でアプリを動かしている際には全然気が付かなかったのですが、いざ jar に固めて実行してみると動かず・・・。ちょっと焦りましたよ^^;

まぁ、よく考えれば当たり前のことなんですけど。開発中は気が付けないものですね。

同じ現象で困った方のお役にたてればうれしいです。

おつかれさまでした。

この記事がお役に立ちましたら シェア をお願いいたします。