• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
思想人生从关注生活开始
博客园    首页    新随笔    联系   管理    订阅  订阅

“no main manifest attribute, in app.jar” 错误详解与解决方案

当你尝试使用 java -jar app.jar 命令运行一个 JAR 文件时,如果看到错误信息 “no main manifest attribute, in app.jar”,这意味着该 JAR 文件的清单文件(MANIFEST.MF)中缺少了 Main-Class 属性。JVM 无法确定程序的入口点,因此无法启动应用程序。

本文将全面解析此问题的原因,并提供针对不同构建工具和开发环境的详细解决方案。

一、问题本质分析

1.1 JAR 文件的 MANIFEST.MF 文件

每个 JAR 文件都包含一个特殊的清单文件:META-INF/MANIFEST.MF。这个文件包含了关于 JAR 包的元数据信息。

可执行 JAR 文件的 MANIFEST.MF 应该包含:
Manifest-Version: 1.0
Main-Class: com.example.DemoApplication

普通 JAR 文件的 MANIFEST.MF(缺少 Main-Class):
Manifest-Version: 1.0

当使用 java -jar 命令时,JVM 会:
1. 解压 JAR 文件
2. 查找 META-INF/MANIFEST.MF 文件
3. 在清单文件中寻找 Main-Class 属性
4. 如果找不到,就会抛出 "no main manifest attribute" 错误

1.2 为什么会出现这个问题?

- 构建配置缺失:Maven/Gradle 配置中没有正确指定主类
- 使用了错误的打包方式:直接使用 jar 命令打包,而不是使用构建工具的可执行 JAR 功能
- Spring Boot 项目配置问题:未正确配置 spring-boot-maven-plugin
- IDE 导出设置错误:在 IDE 中导出 JAR 时未选择 "Runnable JAR" 选项

二、Maven 项目解决方案

2.1 Spring Boot 项目

对于 Spring Boot 项目,必须使用 spring-boot-maven-plugin 来生成可执行的 JAR 文件。

正确的 pom.xml 配置:

<?xml version="1.0" encoding="UTF-8"?>
<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>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>demo-application</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    
    <properties>
        <java.version>11</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!-- 显式指定主类(可选,Spring Boot 通常能自动检测) -->
                    <mainClass>com.example.DemoApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

 

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.2.0</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>com.example.DemoApplication</mainClass>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

关键要点:
- 确保 设置为 jar(不是 pom)
- 必须包含 spring-boot-maven-plugin
- 不要设置 true 或类似的跳过配置

2.2 普通 Maven 项目

对于非 Spring Boot 的普通 Maven 项目,需要配置 maven-jar-plugin:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.2.0</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>com.example.DemoApplication</mainClass>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

 

2.3 Maven 构建命令

确保使用正确的构建命令:

清理并重新构建
mvn clean package

或者直接构建可执行 JAR
mvn clean install

构建完成后,检查生成的 JAR 文件:

查看 MANIFEST.MF 内容
jar -tf target/app.jar | grep MANIFEST.MF
jar -xf target/app.jar META-INF/MANIFEST.MF
cat META-INF/MANIFEST.MF

三、Gradle 项目解决方案

3.1 Spring Boot 项目

build.gradle 配置:

plugins {
id 'org.springframework.boot' version '2.7.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}

group = 'com.example'
version = '1.0.0'
sourceCompatibility = '11'

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

// 显式指定主类(可选)
springBoot {
mainClass = 'com.example.DemoApplication'
}

tasks.named('test') {
useJUnitPlatform()
}

3.2 普通 Gradle 项目

jar {
manifest {
attributes(
'Main-Class': 'com.example.DemoApplication'
)
}
}

3.3 Gradle 构建命令

构建项目
./gradlew clean build

对于 Spring Boot 项目,生成的可执行 JAR 在 build/libs/ 目录下
java -jar build/libs/app.jar

四、IDE 环境解决方案

4.1 IntelliJ IDEA

Spring Boot 项目:
1. 确保使用 Maven/Gradle 构建,而不是 IDEA 的内置打包功能
2. 如果必须使用 IDEA 导出:
- File → Project Structure → Artifacts
- 添加 JAR → from modules with dependencies
- 选择主类
- 勾选 "Include in project build"

普通 Java 项目:
1. File → Project Structure → Artifacts
2. 点击 + → JAR → from modules with dependencies
3. 选择包含 main 方法的模块
4. 指定主类
5. 选择 "Extract to the target JAR" 选项

4.2 Eclipse

1. 右键项目 → Export
2. 选择 Java → Runnable JAR file
3. 选择启动配置(Launch configuration)
4. 指定导出位置
5. 选择库处理方式(推荐 "Package required libraries into generated JAR")

五、手动创建可执行 JAR

如果你需要手动创建可执行 JAR 文件,可以按照以下步骤:

5.1 创建 MANIFEST.MF 文件

创建一个名为 MANIFEST.MF 的文件,内容如下:

Manifest-Version: 1.0
Main-Class: com.example.DemoApplication

注意: 文件末尾必须有一个空行!

5.2 使用 jar 命令打包

编译源代码
javac -d out src/com/example/DemoApplication.java

创建可执行 JAR
jar cfm app.jar MANIFEST.MF -C out .

运行
java -jar app.jar

六、Docker 和容器化部署

在 Docker 容器中遇到此问题通常是由于构建过程不正确导致的。

6.1 正确的 Dockerfile

对于 Spring Boot 应用:

FROM openjdk:11-jre-slim

设置工作目录
WORKDIR /app

复制 JAR 文件
COPY target/app.jar app.jar

暴露端口(如果需要)
EXPOSE 8080

运行应用
ENTRYPOINT ["java", "-jar", "app.jar"]

构建和运行命令:

先在本地正确构建 JAR
mvn clean package

构建 Docker 镜像
docker build -t my-app .

运行容器
docker run --rm my-app

6.2 多阶段构建 Dockerfile

构建阶段
FROM maven:3.8.4-openjdk-11 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

运行阶段
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=build /app/target/app.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

七、常见错误排查

7.1 检查 JAR 文件内容

列出 JAR 文件内容
jar -tf app.jar

提取并查看 MANIFEST.MF
jar -xf app.jar META-INF/MANIFEST.MF
cat META-INF/MANIFEST.MF

或者直接查看
unzip -p app.jar META-INF/MANIFEST.MF

7.2 验证主类存在

检查主类是否在 JAR 中
jar -tf app.jar | grep DemoApplication.class

7.3 使用替代运行方式

如果暂时无法修复 JAR 文件,可以使用以下方式运行:

不使用 -jar 参数,而是指定 classpath
java -cp app.jar com.example.DemoApplication

7.4 检查构建输出

确保构建过程中没有警告或错误:

Maven 构建时的正常输出应该包含 repackage 步骤
[INFO] --- spring-boot-maven-plugin:2.7.0:repackage (repackage) @ demo-application ---
[INFO] Replacing main artifact with repackaged archive

如果看到类似 [INFO] Skipping repackaging 的消息,说明配置有问题。

八、特殊情况处理

8.1 多模块 Maven 项目

在多模块项目中,确保在包含主类的模块中配置了 spring-boot-maven-plugin

<!-- 在子模块的 pom.xml 中 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

8.2 自定义主类名称

如果主类名称不标准,需要显式指定:

com.example.custom.CustomStartup

// Gradle
springBoot {
mainClass = 'com.example.custom.CustomStartup'
}

8.3 处理依赖冲突

有时依赖冲突会导致插件无法正常工作。可以尝试:

清理本地 Maven 仓库中的相关依赖
rm -rf ~/.m2/repository/org/springframework/boot/
mvn clean package

九、最佳实践建议

9.1 项目初始化

- 使用 Spring Initializr 创建 Spring Boot 项目,确保基础配置正确
- 选择合适的构建工具(Maven 或 Gradle)

9.2 开发阶段

- 定期验证构建过程:mvn clean package 或 ./gradlew build
- 在本地测试 JAR 文件:java -jar target/app.jar
- 使用版本控制系统跟踪构建配置文件

9.3 部署阶段

- 在 CI/CD 流程中包含 JAR 文件验证步骤
- 使用容器化部署确保环境一致性
- 记录和文档化构建和部署过程

9.4 调试技巧

- 启用详细日志:mvn clean package -X
- 比较工作正常的 JAR 和有问题的 JAR 的 MANIFEST.MF 文件
- 使用 jar -tvf app.jar 查看详细的 JAR 内容列表

十、总结

“no main manifest attribute, in app.jar” 错误的根本原因是 JAR 文件缺少必要的 Main-Class 清单属性。解决这个问题的关键在于:

1. 正确配置构建工具:确保 Maven 或 Gradle 配置中包含了生成可执行 JAR 的必要插件和配置
2. 使用正确的构建命令:使用 mvn package 或 ./gradlew build 而不是简单的编译命令
3. 验证构建结果:在部署前检查生成的 JAR 文件是否包含正确的 MANIFEST.MF
4. 遵循最佳实践:使用标准的项目结构和构建配置

通过本文提供的系统性解决方案,你应该能够快速诊断和解决这个常见的 Java 部署问题。记住,预防胜于治疗——在开发阶段就建立正确的构建和测试流程,可以避免在生产环境中遇到此类问题。

posted @ 2026-04-13 09:49  JackYang  阅读(4)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3