在Java开发中,将项目打包成可执行的JAR文件是部署和分发应用程序的重要环节,JAR(Java Archive)文件不仅能够将.class文件、资源文件、配置文件等整合到一个压缩包中,还支持通过清单文件配置启动入口,实现“一次编写,到处运行”的跨平台特性,本文将详细介绍使用Java原生工具、Maven、Gradle三种主流方式打JAR包的完整流程,并涵盖常见问题的解决方案。

使用Java原生工具打JAR包
Java开发工具包(JDK)提供了jar命令,这是最基础的打包方式,适合小型项目或需要精细控制打包过程的场景。
1 创建简单的JAR文件
假设有一个简单的Java项目,结构如下:
MyProject/
├── src/
│ └── com/
│ └── example/
│ └── Main.java
└── lib/
└── dependency.jar
首先编译Java源码:
javac -d target src/com/example/Main.java -cp lib/dependency.jar
编译完成后,使用jar命令打包:
jar -cvf myapp.jar -C target . -C lib dependency.jar
参数说明:
c:创建新的JAR文件;v:生成详细输出;f:指定JAR文件名;-C target .:切换到target目录并将所有.class文件打包;-C lib dependency.jar:将依赖的JAR文件加入包中。
2 创建可执行的JAR文件(带Main-Class)
若要让JAR文件直接通过java -jar myapp.jar运行,需在META-INF/MANIFEST.MF中指定Main-Class。
手动创建清单文件:
创建MANIFEST.MF如下:
Manifest-Version: 1.0 Main-Class: com.example.Main Class-Path: lib/dependency.jar
注意:Class-Path用于依赖的JAR文件,路径需相对于JAR文件的位置。
打包时指定清单文件:
jar -cvfm myapp.jar MANIFEST.MF -C target . -C lib dependency.jar
使用jar命令自动生成清单:
jar -cfe myapp.jar com.example.Main -C target .
e参数用于直接指定主类,但这种方式无法自动添加依赖,需手动将依赖JAR解压到目录或通过类路径加载。
使用Maven打JAR包
Maven作为主流的Java项目管理工具,通过插件可以自动化打包流程,尤其适合中大型项目。

1 标准Maven项目打包
Maven默认会生成一个可执行的“胖JAR”(包含所有依赖),无需手动管理依赖路径。
项目结构示例:
MyProject/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/Main.java
│ │ └── resources/
│ └── test/
pom.xml配置:
无需额外配置,Maven会使用maven-jar-plugin打包,执行命令:
mvn clean package
生成的JAR文件位于target/目录下,默认名称为${project.artifactId}-${version}.jar。
2 打包成可执行的胖JAR
使用maven-shade-plugin或maven-assembly-plugin可将依赖JAR合并到最终文件中。
使用maven-shade-plugin:
在pom.xml中添加插件配置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
执行mvn clean package后,生成的JAR将包含所有依赖,可直接运行。
3 排除依赖或过滤资源
若需排除某些依赖或过滤资源文件,可在插件配置中添加:
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
使用Gradle打JAR包
Gradle以灵活的配置和高效的构建速度受到开发者青睐,其java插件提供了丰富的打包能力。
1 基础打包配置
项目结构:
MyProject/
├── build.gradle
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/Main.java
│ │ └── resources/
build.gradle配置:
plugins {
id 'java'
id 'application'
}
mainClassName = 'com.example.Main'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.apache.commons:commons-lang3:3.12.0'
}
执行命令:

gradle build
生成的JAR文件位于build/libs/目录,默认为项目名-版本.jar。
2 打包成可执行的胖JAR
Gradle默认生成的JAR不包含依赖,需使用shadow插件(推荐)或application插件。
使用shadow插件:
在build.gradle中添加:
plugins {
id 'com.github.johnrengelman.shadow' version '7.1.2'
}
shadowJar {
mergeServiceFiles()
manifest {
attributes 'Main-Class': 'com.example.Main'
}
}
执行gradle shadowJar,生成的胖JAR位于build/libs/,文件名后缀为-all.jar。
3 自定义JAR内容
可通过jar任务自定义排除或包含文件:
jar {
exclude '**/*.log'
from('src/main/resources') {
include '*.properties'
}
}
常见问题与解决方案
1 “找不到主清单属性”错误
原因:JAR文件中未正确配置Main-Class。
解决:检查META-INF/MANIFEST.MF是否存在且包含Main-Class,或通过插件明确指定(如Maven的maven-jar-plugin、Gradle的application插件)。
2 依赖冲突或找不到依赖
原因:依赖未正确打包或类路径配置错误。
解决:
- Maven:确保依赖在
pom.xml中声明,使用mvn dependency:copy-dependencies复制到lib目录; - Gradle:通过
gradle dependencies查看依赖树,使用shadow插件合并依赖。
3 资源文件未被打包
原因:资源文件未放在src/main/resources目录或路径未正确配置。
解决:
- Maven:默认会包含
src/main/resources下的所有文件; - Gradle:检查
sourceSets配置,确保资源目录正确映射。
4 JAR文件过大
原因:包含不必要的依赖或资源文件。
解决:
- 使用
maven-shade-plugin的filters排除无用文件; - Gradle中通过
shadowJar的minimize()启用依赖优化。
无论是Java原生的jar命令,还是Maven、Gradle等构建工具,打JAR包的核心均围绕“源码编译、资源整合、依赖管理、入口配置”展开,对于小型项目,原生工具足够灵活;对于中大型项目,Maven和Gradle的自动化能力能显著提升效率,选择合适的方式,并注意配置清单文件、依赖路径和资源文件,即可成功生成可执行的JAR包,实现Java应用的便捷部署。


















