Spring Boot 启动时 “jar中没有主清单属性” 异常

1、概览

当我们在执行 Spring Boot JAR 文件时候,可能会遇到 “jar中没有主清单属性”(no main manifest attribute)错误。这是因为我们在 MANIFEST.MF 文件中缺少了 Main-Class 元数据属性的声明,该文件位于 META-INF 文件夹下。

在本教程中,我们将重点介绍造成这一问题的原因以及如何解决。

TL;DR

出现这个问题的原因,八成是你忘记在 pom.xml 中添加 spring-boot-maven-plugin 插件了,添加即可。如下:

<build>
   <plugins>
       <plugin>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-maven-plugin</artifactId>
       </plugin>
   </plugins>
</build>

2、问题的出现

一般来说,从 Spring Initializr 获取 pom.xml 不会有任何问题。不过,如果我们是手动创建项目,自己在 pom.xml 中添加 spring-boot-starter-parent 依赖,可能会遇到这个问题。

我们可以尝试以 mvn clean package 的方式来构建应用,以重现这个问题:

$ mvn clean package

运行 jar 时,我们会遇到错误:

$ java -jar target\spring-boot-artifacts-2.jar
no main manifest attribute, in target\spring-boot-artifacts-2.jar

在此示例中,MANIFEST.MF 文件的内容为:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.6.3
Built-By: Baeldung
Build-Jdk: 11.0.13

3、使用 Maven Plugin 修复

3.1、添加插件

在这种情况下,最常见的问题是我们没有在 pom.xml 文件中添加 spring-boot-maven-plugin 声明。

在 pom.xml 中添加 plugin 标签,并在 plugin 下声明 Main-Class

<plugins>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <mainClass>com.baeldung.demo.DemoApplication</mainClass>
            <layout>JAR</layout>
        </configuration>
    </plugin>
</plugins>

不过,这可能还不足以解决问题。重新构建,运行 jar 后,仍可能然会遇到 “no main manifest attribute” 问题。

让我们看看还有哪些配置和替代方案可以解决这个问题。

3.2、Maven Plugin Execution Goal

spring-boot-maven-pluginconfiguration 标签下添加 repackage goal:

<executions>
    <execution>
        <goals>
            <goal>repackage</goal>
        </goals>
    </execution>
</executions>

3.3、Maven properties 和内联命令 Execution Goal

pom.xml 文件的 properties 标签中添加 start-class 属性,可以让构建过程更加灵活:

<properties>
    <start-class>com.baeldung.demo.DemoApplication</start-class>
</properties>

现在,我们需要使用 Maven 内联命令 spring-boot:repackage 来构建 jar:

$ mvn package spring-boot:repackage

4、查看 MANIFEST.MF 文件内容

应用此解决方案后,构建 jar,然后查看 MANIFEST.MF 文件。

其中已经有 Main-ClassStart-Class 属性了:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.6.3
Built-By: Baeldung
Build-Jdk: 11.0.13
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.baeldung.demo.DemoApplication
Spring-Boot-Version: 2.7.5
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx

现在执行 jar,“no main manifest attribute” 异常不再出现,应用程序能正常运行。

5、总结

在本文中,我们学习了如何解决在执行 Spring Boot jar 时出现 “no main manifest attribute” 异常的问题。

我们还了解了导致这一问题的原因,以及如何添加和配置 Spring Maven Plugin 来解决这一问题。


参考:https://www.baeldung.com/spring-boot-fix-the-no-main-manifest-attribute