目录
- 准备工作:确保项目结构正确
- 使用 Eclipse 的 "Export" 功能(最常用)
- 步骤详解
- 生成可执行 JAR(带 Main Class)
- 生成包含依赖库的 JAR(推荐)
- 使用 Maven 插件(专业、自动化)
- 准备
pom.xml - 使用
maven-assembly-plugin或maven-shade-plugin
- 准备
- 使用 Gradle 插件(现代化、灵活)
- 准备
build.gradle - 使用
shadow或jar任务
- 准备
- 常见问题与解决方案
NoClassDefFoundError: 找不到依赖的类Could not find the main class: 找不到主类- JAR 文件过大,不想包含所有依赖
- 总结与推荐
准备工作:确保项目结构正确
在打包之前,请确保你的项目结构清晰,一个标准的 Java 项目通常包含:

src(源代码目录): 存放你的.java文件。bin或target(输出目录): 存放编译后的.class文件,Eclipse 通常会自动创建一个bin目录。- 外部依赖库 (JARs): 如果你的项目使用了外部的 JAR 包(如
mysql-connector-java.jar),你需要将它们添加到项目的构建路径中。
如何添加外部 JAR?
- 右键点击你的项目 -> Build Path -> Configure Build Path...
- 在 Libraries 标签页,点击 Add External JARs...
- 选择你的 JAR 文件并确定。
方法一:使用 Eclipse 的 "Export" 功能(最常用)
这是最直接、最不需要额外配置的方法,适合快速打包。
步骤详解
-
编译项目:
- 确保你的代码没有编译错误,右键点击项目 -> Build Project,或者直接按
Ctrl + B。
- 确保你的代码没有编译错误,右键点击项目 -> Build Project,或者直接按
-
导出 JAR:
(图片来源网络,侵删)- 右键点击你的项目 -> Export...。
- 在弹出的窗口中,展开 Java 文件夹,选择 JAR file,然后点击 Next >。
-
配置导出选项:
- Select the export destination: 选择一个保存 JAR 文件的位置和文件名(
C:\my-app.jar)。 - Export generated class files into JAR: 这通常是默认选中的,确保你的
.class文件会被打包进去。 - Export source files: 可选,如果你想将源代码也打包进 JAR,勾选此项。
- Export resources: 可选,如果你的项目有非
.java的资源文件(如.properties,.xml, 图片等),并且需要它们,请勾选此项。
- Select the export destination: 选择一个保存 JAR 文件的位置和文件名(
-
选择要导出的内容:
- 默认情况下,Eclipse 会选择整个项目,确保你只想打包必要的部分。
- 重要: 取消勾选
.project、.settings、.classpath等 Eclipse 项目配置文件,它们不应该被打包进最终的 JAR。
-
点击 Finish。
你就在指定位置得到了一个 JAR 文件。
(图片来源网络,侵删)
生成可执行 JAR(带 Main Class)
如果你的 JAR 包含一个带有 public static void main(String[] args) 方法的类,你可以将它设置为可执行的。
- 在 Export 窗口中,点击 Next > 直到看到 JAR Manifest 的选项。
- 在 "Select the class of the application entry point" 下拉框中,选择你的主类(
com.example.MyApp)。 - (可选) 你也可以勾选 "Generate the manifest file",Eclipse 会自动创建一个
META-INF/MANIFEST.MF文件,并指定Main-Class。 - 完成后,你可以通过命令行
java -jar my-app.jar来运行它。
生成包含依赖库的 JAR(推荐)
问题: 使用 Export 功能生成的 JAR 不包含 你通过 Build Path 添加的外部依赖库,当你运行它时,很可能会因为找不到依赖类而报 NoClassDefFoundError。
解决方案: Eclipse 的 Export 功能本身不直接支持打包依赖库,但我们可以通过以下变通方法实现:
-
方法 A: 手动复制依赖库
- 在导出 JAR 后,将所有依赖的 JAR 文件和你的主 JAR 文件放在同一个文件夹里。
- 运行时,需要使用
Classpath参数:java -cp "my-app.jar;mysql-connector-java.jar;other-lib.jar" com.example.MyApp
注意:Windows 系统使用分号 分隔,Linux/macOS 使用冒号 。
-
方法 B: 使用 Eclipse 的 "Build Path" -> "Configure Build Path" -> "Order and Export" (不推荐,易出错)
这个方法有时会生效,但非常不稳定,强烈不推荐,它可能会导致类路径冲突。
-
方法 C: 使用 Maven/Gradle (强烈推荐)
这是处理依赖库最专业、最可靠的方法,将在下面详细介绍。
方法二:使用 Maven 插件(专业、自动化)
如果你的项目使用 Maven(或可以转换为 Maven 项目),这是最佳实践。
准备 pom.xml
确保你的项目根目录下有 pom.xml 文件,如果还没有,可以右键项目 -> Configure -> Convert to Maven Project。
在 pom.xml 中,你需要添加一个插件来创建包含所有依赖的 "Fat JAR" 或 "Uber JAR"。maven-shade-plugin 是最常用的选择。
<project ...>
...
<build>
<plugins>
<!-- 使用 maven-shade-plugin 来创建包含所有依赖的 JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version> <!-- 使用较新版本 -->
<executions>
<execution>
<phase>package</phase> <!-- 在 package 阶段执行 -->
<goals>
<goal>shade</goal>
</goals>
<configuration>
<!-- 指定主类 -->
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.MyApp</mainClass>
</transformer>
</transformers>
<!-- (可选) 解决不同依赖中同名文件冲突 -->
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
使用 Maven 打包
- 右键点击
pom.xml文件。 - 选择 Run As -> Maven build...。
- 在 Goals 输入框中,输入
clean package。clean: 清理之前的构建文件。package: 编译项目并打包。
- 点击 Run。
构建成功后,你可以在 target 目录下找到一个类似 my-app-1.0-SNAPSHOT.jar 的文件,这就是一个包含所有依赖的可执行 JAR。
方法三:使用 Gradle 插件(现代化、灵活)
与 Maven 类似,Gradle 也能很好地处理依赖打包。
准备 build.gradle
在项目根目录下创建 build.gradle 文件。
plugins {
id 'java'
// 使用 shadow 插件来创建 "Fat JAR"
id 'com.github.johnrengelman.shadow' version '8.1.1'
}
group = 'com.example'
version = '1.0'
repositories {
mavenCentral()
}
dependencies {
// 声明你的项目依赖
// implementation 'org.slf4j:slf4j-api:1.7.36'
// testImplementation 'junit:junit:4.13.2'
}
// shadowJar 任务会创建一个包含所有依赖的 JAR
shadowJar {
archiveBaseName.set('my-app') // 生成的 JAR 文件名
archiveVersion.set('1.0') // 版本号
archiveClassifier.set('all') // 分类器,最终文件名为 my-app-1.0-all.jar
// 指定主类
manifest {
attributes 'Main-Class': 'com.example.MyApp'
}
}
// 默认的 jar 任务
jar {
manifest {
attributes 'Main-Class': 'com.example.MyApp'
}
}
// 将 shadowJar 设为默认的 build 任务
tasks.named('build') {
dependsOn(shadowJar)
}
使用 Gradle 打包
- 右键点击
build.gradle文件。 - 选择 Run As -> Gradle Build。
- 在右侧的 Gradle Tasks 视图中,展开你的项目,找到
build任务并双击运行。
构建完成后,你可以在 build/libs 目录下找到 my-app-1.0-all.jar,它是一个可执行且包含所有依赖的 JAR。
常见问题与解决方案
NoClassDefFoundError: 找不到依赖的类
- 原因: JAR 文件中没有包含它所依赖的其他类的
.class文件。 - 解决方案:
- 首选: 使用 Maven (
maven-shade-plugin) 或 Gradle (shadow插件) 来生成包含所有依赖的 "Fat JAR"。 - 备选: 手动将所有依赖的 JAR 文件与你的主 JAR 放在同一个目录,然后使用
-cp参数指定所有 JAR 的路径。
- 首选: 使用 Maven (
Could not find the main class: 找不到主类
- 原因:
- MANIFEST.MF 文件中的
Main-Class属性不正确或缺失。 - 指定的类名格式错误(缺少包名
com.example.MyApp而不是MyApp)。 - JAR 文件本身已损坏。
- MANIFEST.MF 文件中的
- 解决方案:
- 使用解压工具(如 WinRAR, 7-Zip)打开你的 JAR 文件,检查
META-INF/MANIFEST.MF文件,确认Main-Class的值是否正确。 - 重新检查你在 Eclipse 或构建工具中配置的主类名。
- 尝试重新打包。
- 使用解压工具(如 WinRAR, 7-Zip)打开你的 JAR 文件,检查
JAR 文件过大,不想包含所有依赖
- 场景: 你希望将依赖库作为单独的文件分发,而不是打包进一个大 JAR。
- 解决方案:
- 使用
Export功能生成一个不包含依赖的 JAR。 - 将所有依赖的 JAR 文件一起分发给用户。
- 编写一个启动脚本(
.bat或.sh),在脚本中使用-cp来设置正确的类路径。
- 示例 (
run.baton Windows):@echo off java -cp "my-app.jar;lib/*" com.example.MyApp
- 这里假设所有依赖库都放在
lib目录下, 会匹配lib下的所有 JAR。*
- 这里假设所有依赖库都放在
- 使用
总结与推荐
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Eclipse Export | 简单快捷,无需额外工具 | 无法处理依赖库,配置选项少,不稳定 | 快速测试、小型无依赖项目、临时打包 |
| Maven (shade) | 行业标准,自动化依赖管理,可靠,功能强大 | 需要学习 Maven,项目需转换为 Maven 结构 | 中大型项目、需要持续集成/部署的项目 |
| Gradle (shadow) | 灵活,配置更简洁,性能通常优于 Maven | 需要学习 Gradle,项目需配置 Gradle | 现代化项目、Android 开发、需要高度定制构建流程的项目 |
最终建议:
- 对于初学者或一次性任务: 使用 Eclipse Export 功能,但必须手动处理依赖(复制 JAR 并使用
-cp)。 - 对于任何严肃的、长期维护的项目: 强烈推荐使用 Maven 或 Gradle,它们是 Java 生态系统的标准,能彻底解决依赖和打包的烦恼,让你的构建过程自动化、可重复、可信赖,从长远来看,学习它们是绝对值得的。
