解决no main manifest attribute错误

0. 背景

在开发Spring boot项目的时候,有时候会需要使用java -jar test-1.0-SNAPSHOT.jar指令来运行开发的java应用,但是很不幸,会遇到这样的错误

no main manifest attribute, in test-1.0-SNAPSHOT.jar

为什么会产生这样的错误呢?如何解决呢?

1. java程序如何运行

在接触java开发的第一天,我们就知道,在编写完Java程序之后

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

需要使用指令将.java文件编译成class文件

javac Hello.java

然后就可以使用命令就可以执行这个Java程序

java Hello                          
Hello World         

程序运行的入口是main方法,当我们使用java Hello命令,虚拟机就可以根据Hello.class文件中的main方法,来运行程序。但是使用的 java -jar 指令是如何使程序运行起来的呢?

2. jar是什么

JAR(Java Archive)文件是一种打包文件格式,它允许你将多个 Java 类文件、相关的元数据和资源(如文本、图片等)打包到一个单一的文件中,以便于分发和部署。

JAR中包含了类文件,元数据和资源。类文件和资源文件很清楚,那元数据是什么呢?
元数据主要指的是清单文件(MANIFEST.MF) ,这是一个可选文件,用来提供关于jar文件的额外信息。清单文件的主要功能:

    1. 指定主类:在清单文件中,可以指定包含main方法的类,这是Java应用程序的入口点。这允许用户通过java -jar命令直接运行JAR文件。
    1. 定义属性:清单文件可以包含属性,这些属性可以是键值对的形式,用于存储关于JAR文件的额外信息,比如版本号、作者信息等。
    1. 指定类路径:在清单文件中可以定义类路径(Class-Path)属性,指定在运行JAR文件时需要包含的其他JAR文件或目录。
    1. 安全设置:清单文件可以包含安全相关的设置,比如指定需要哪些权限。
    1. 扩展名映射:可以定义文件扩展名到类名的映射,这样当运行具有特定扩展名的文件时,JAR文件中的特定类将被用来处理这些文件。
    1. 其他自定义信息:开发者可以根据需要在清单文件中添加自定义的元数据。

这里可以解压一个jar来看一下:
这里解压一下spring-core-5.3.27.jar来看一下,jar中有什么内容:
在这里插入图片描述

这里可以看到,org目录下,放的就是类文件,META-INF放的就是资源文件:
在这里插入图片描述
这里再看一下MANIFEST. MF里的内容

Manifest-Version: 1.0
Implementation-Title: spring-core
Automatic-Module-Name: spring.core
Implementation-Version: 5.3.27
Created-By: 1.8.0_345 (Oracle Corporation)
Dependencies: jdk.unsupported

Manifest-Version 表示清单文件的版本。
Created-By 表示创建JAR文件的Java版本和提供者。
Permissions 指定了JAR文件的权限。

这个文件中没有包含指定main的方法,一般这样添加:

Main-Class: com.example.MainApp

3. java -jar test-1.0-SNAPSHOT.jar:

这样已经可以知道,java -jar就是去找指定jar包里的main方法来执行,如何找main方法?根据MANIFEST.MF中的Main-Class类来找。

遇到的错误是没有no main manifest attribute,那就打开看一下。

Manifest-Version: 1.0  
Implementation-Title: test  
Implementation-Version: 1.0-SNAPSHOT  
Build-Jdk-Spec: 1.8  
Created-By: Maven JAR Plugin 3.2.2  

这里没有这个main attribute,那如何添加这个attribute呢?
以上面的Hello.java为例,来手动打一个jar包。先编写这个MANIFEST. MF

Manifest-Version: 1.0     
Build-Jdk-Spec: 1.8     
Main-Class: Hello  

这样再使用这个文件打一个jar包:

jar cvfm test-hello.jar MANIFEST.MF .  

这里的参数作用是

  • c:创建新的 JAR 文件。
  • v:在打包过程中显示详细输出。
  • f:后面跟着的是要创建的 JAR 文件的名称。
  • m:指定清单文件的名称。

这个时候就可以使用java -jar愉快的玩耍了。
那上面Springboot程序如何添加这个程序执行入口呢?

4. 添加执行入口

这里的程序打包是使用的maven,那就使用maven的插件来完成就好了!
在pom文件中添加如下插件:

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

        <executions> 
          <execution> 
            <goals> 
              <goal>repackage</goal> 
            </goals> 
          </execution> 
        </executions> 
      </plugin> 
    </plugins> 
  </build> 

这个时候,再使用mvn package指令,就可以得到一个可以正确执行的jar包了。直接java -jar test-1.0-SNAPSHOT.jar愉快玩耍。

你遇到的错误是: ``` no main manifest attribute, in app.jar ``` 这个错误的意思是:你尝试运行的 `app.jar` 文件中没有定义 `Main-Class` 属性,Java 无法知道应该从哪个类的 `main` 方法开始运行这个 JAR 文件。 --- ## 🧨 错误原因分析 ### 1. **JAR 文件没有 Main-Class 配置** JAR 包的 `MANIFEST.MF` 文件中没有指定 `Main-Class`,即没有告诉 JVM 哪个类包含 `public static void main(String[] args)` 方法。 ### 2. **Maven 构建的 JAR 默认不包含 Main-Class** 如果你使用的是 Maven 默认的 `maven-jar-plugin`,它不会自动设置 `Main-Class`,除非你在 `pom.xml` 中明确配置。 --- ## ✅ 解决方案 ### ✅ 方法一:使用 Maven 插件配置 `Main-Class` 在 `pom.xml` 中添加或修改 `maven-jar-plugin`,指定主类: ```xml <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.6.2</version> <configuration> <archive> <manifest> <mainClass>com.example.Main</mainClass> <!-- 替换为你的主类 --> </manifest> </archive> </configuration> </plugin> </plugins> </build> ``` 然后重新构建 JAR: ```bash mvn clean package ``` --- ### ✅ 方法二:使用 `spring-boot-maven-plugin`(适用于 Spring Boot 项目) 如果你使用的是 Spring Boot,应该使用 `spring-boot-maven-plugin` 来构建可执行 JAR: ```xml <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> ``` 然后运行: ```bash mvn clean package ``` 这会生成一个包含完整依赖和 `Main-Class` 的可执行 JAR。 --- ### ✅ 方法三:手动创建带有 Main-Class 的 MANIFEST 文件(不推荐) 你可以手动创建一个 `MANIFEST.MF` 文件: ``` Main-Class: com.example.Main ``` 然后使用如下命令打包: ```bash jar cfm app.jar MANIFEST.MF -C classes/ . ``` --- ## 🔍 如何查看 JAR 文件中的 Main-Class 你可以使用以下命令查看 JAR 文件的 MANIFEST: ```bash jar xf app.jar META-INF/MANIFEST.MF cat META-INF/MANIFEST.MF ``` 你应该能看到类似如下内容: ``` Manifest-Version: 1.0 Main-Class: com.example.Main ``` --- ## 🧪 示例:完整 Maven 配置 + 构建流程 ### `pom.xml` 示例 ```xml <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.example.Main</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> ``` ### 构建命令 ```bash mvn clean package java -jar target/your-app.jar ``` --- ## ✅ 总结 | 问题 | 原因 | 解决方法 | |------|------|----------| | `no main manifest attribute` | JAR 文件没有指定 Main-Class | 配置 `maven-jar-plugin` 或使用 `spring-boot-maven-plugin` | | Java 无法启动 JAR | 缺少主类信息 | 修改 MANIFEST 文件或使用插件自动配置 | --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值