惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
U
Unit 42
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
S
SegmentFault 最新的问题
阮一峰的网络日志
阮一峰的网络日志
雷峰网
雷峰网
Microsoft Security Blog
Microsoft Security Blog
爱范儿
爱范儿
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
罗磊的独立博客
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
Martin Fowler
Martin Fowler
宝玉的分享
宝玉的分享
L
LangChain Blog
Engineering at Meta
Engineering at Meta
量子位
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
A
About on SuperTechFans
Y
Y Combinator Blog

博客园 - JackYang

I walk alone句子结构中 alone 后置的原因及同类用法解析 《用了3个月Cursor后,我删掉了自己写了10年的工具库》:从“造轮子自豪”到“承认AI写得更好”的心理崩塌与重建 2026年AI Agent时代下如何打造新一代研发体系:从熵增困境到智能工厂的范式重构(基于2025年底文章重写) AgentScope-Java 深度实践:构建企业级生产就绪的智能体应用 传统软件的AI重生:大模型时代下的系统重构与智能升级(2026实践指南)——从代码理解到数据交互,构建安全、高效、可落地的企业级AI集成架构 浅析英文复合名词“X Recording / X Logging”的翻译逻辑与本地化策略——兼论“How + 复合名词 + Works”句式的处理 浅析英文句式“How + 名词 + Works”的翻译逻辑与应用场景 会员契约论新观察:从身份标签到价值博弈——解构与评估现代会员体系 深度剖析akshare-data:OpenClaw生态中的金融数据Skill构建之道——手把手教你用akshare-data搭建个人AI量化系统 DeepSeek-V4:中国大模型的新范式革命—— 万字深度技术全景解析 深入 Java I/O 核心:BufferedInputStream 全景式源码解析与工程实践——2026 高并发时代下的性能基石,从 JDK 源码到虚拟线程(Project Loom)的协同优化 2026年前端工程化的新纪元:从Rust工具链革命到AI Agent原生架构演进 万字详文:解构 SessionBindingService —— AI智能体的“会话粘合剂” Windows 本地部署 Hermes Agent 安装教程 + 飞书接入,会自我进化AI Agent 智能体(全程避坑,亲测有效) 2026年最新、最全、可用的Docker 国内镜像源加速(截至 2026 年 4月14日 亲测可用) Java 中Jar包冲突问题及解决方案 如何自定义Spring Boot的错误页面显示? Spring Boot的全局异常处理器如何配置? This application has no explicit mapping for /error 深度拆解三大 AI 核心协议:MCP、ACP、A2A,读懂智能代理全域通信底层逻辑—— 从技术原理、架构设计、落地场景到生态未来,全面揭秘 AI 智能体协作的底层标准 The Java® Virtual Machine Specification Java SE 26 Edition 中文版简介第二小节:The Java Virtual Machine The Java® Virtual Machine Specification Java SE 26 Edition 中文版简介第一小节:A Bit of History Java 中 “Error: Could not find or load main class” 错误详解与全面解决方案 云原生时代,Docker和虚拟机谁才是王者?K8s架构下的终极选型指南 2026年全网最新、最全、最好用的Excel快捷键大全:提升工作效率的必备技巧 2026年全网最新、最全的Word快捷键大全:从入门到精通 WPS快捷键大全及使用技巧 2026年最新版IntelliJ IDEA 2026.1下载、安装与配置教程: IDEA 2026.1新手使用教程(万字详解) OpenClaw源码大揭秘:WhatsApp登录工具如何用50行代码破解AI智能体的移动端困局? 2026AI Agent:AI Agent从“工具箱”到“操作系统”——深度解构AI聚合化(Aggregation)、自动化(Automation)与普惠化(Democratization
“no main manifest attribute, in app.jar” 错误详解与解决方案
JackYang · 2026-04-13 · via 博客园 - JackYang

当你尝试使用 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 部署问题。记住,预防胜于治疗——在开发阶段就建立正确的构建和测试流程,可以避免在生产环境中遇到此类问题。