Java?JAR文件的打包與運行過程
在 Java 開發(fā)中,JAR(Java Archive)文件是一種核心的分發(fā)格式,用于將多個類文件、元數(shù)據(jù)和資源打包成一個壓縮文件。JAR 文件不僅便于應用程序的部署,還可以通過配置清單文件(manifest)使其成為可執(zhí)行文件。本文將深入探討如何使用 JDK 的 jar 工具手動創(chuàng)建 JAR 文件,以及如何利用 Maven 自動化這一過程。我們將通過清晰的示例和步驟,確保內(nèi)容深入淺出,為技術人員提供實用的指導。
本文的目標是幫助您:
- 理解 JAR 文件的作用和結(jié)構(gòu)。
- 掌握使用
jar工具創(chuàng)建可執(zhí)行 JAR 文件的方法。 - 學習如何配置 Maven 以生成包含依賴的 JAR 文件。
- 了解高級工具(如
jpackage)的潛在用途。
什么是 JAR 文件?
JAR 文件是基于 ZIP 和 ZLIB 壓縮格式的歸檔文件,主要用于打包 Java 應用程序或庫的組件,包括:
- 類文件:編譯后的
.class文件,包含 Java 程序的字節(jié)碼。 - 資源文件:如圖片、配置文件或音頻文件。
- 清單文件:位于
META-INF/MANIFEST.MF,包含文件的元數(shù)據(jù)和屬性。
JAR 文件的主要優(yōu)勢包括:
- 高效分發(fā):將所有相關文件打包為單一文件,便于傳輸。
- 壓縮:減少文件大小,加快下載速度。
- 可執(zhí)行性:通過指定
Main-Class屬性,JAR 文件可以直接運行。 - 模塊化:自 JDK 9 起,JAR 文件支持模塊化打包(模塊化 JAR)。
使用 jar 命令創(chuàng)建 JAR 文件
JDK 提供的 jar 工具是創(chuàng)建和操作 JAR 文件的標準工具。以下是通過命令行創(chuàng)建可執(zhí)行 JAR 文件的步驟。
步驟 1:編寫并編譯 Java 代碼
假設我們有一個簡單的 Java 程序 HelloWorld.java,位于 com.somedomainhere 包中:
package com.somedomainhere;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World of Java");
}
}在命令行中,編譯該文件:
javac com/somedomainhere/HelloWorld.java
這將在 com/somedomainhere 目錄下生成 HelloWorld.class 文件。
步驟 2:創(chuàng)建清單文件
要使 JAR 文件可執(zhí)行,需要一個清單文件來指定主類。創(chuàng)建一個名為 manifest.stub 的文本文件,內(nèi)容如下:
Main-Class: com.somedomainhere.HelloWorld
注意:
Main-Class屬性區(qū)分大小寫,且冒號后必須有一個空格。- 文件必須以換行符結(jié)尾,否則可能導致解析錯誤。
步驟 3:創(chuàng)建 JAR 文件
假設當前目錄結(jié)構(gòu)如下:
.
└── com
└── somedomainhere
└── HelloWorld.class在包含 com 目錄的根目錄下,運行以下命令:
jar cvmf manifest.stub hello.jar com/somedomainhere/HelloWorld.class
命令參數(shù)說明:
c:創(chuàng)建新的歸檔文件。v:顯示詳細輸出(verbose)。m:包含指定的清單文件(manifest.stub)。f:指定輸出文件名(hello.jar)。
執(zhí)行后,將生成 hello.jar,其中包含正確的包結(jié)構(gòu)(com/somedomainhere/HelloWorld.class)和清單文件。
步驟 4:驗證 JAR 文件內(nèi)容
您可以使用以下命令查看 JAR 文件的內(nèi)容:
jar tf hello.jar
輸出示例:
META-INF/
META-INF/MANIFEST.MF
com/
com/somedomainhere/
com/somedomainhere/HelloWorld.class
運行 JAR 文件
創(chuàng)建 JAR 文件后,可以通過以下命令運行:
java -jar hello.jar
java -jar 命令會讀取清單文件中的 Main-Class 屬性,并執(zhí)行指定的主類。運行上述命令將輸出:
Hello, World of Java
在支持的 GUI 平臺(如 Windows、macOS 或某些 Linux 桌面環(huán)境)上,您可以雙擊 JAR 文件運行,前提是系統(tǒng)已將 .jar 文件關聯(lián)到 Java 運行時環(huán)境(JRE)。
注意:
- 確保已安裝 Java 運行時環(huán)境(JRE)或 JDK。
- 如果 JAR 文件缺少
Main-Class屬性或主類不存在,將拋出異常。
使用 Maven 創(chuàng)建 JAR 文件
對于大型項目,手動創(chuàng)建 JAR 文件可能效率低下。Maven 是一種流行的構(gòu)建工具,可以自動化編譯、打包和依賴管理。以下是如何使用 Maven 創(chuàng)建可執(zhí)行 JAR 文件的步驟。
步驟 1:設置 Maven 項目
創(chuàng)建一個標準的 Maven 項目,目錄結(jié)構(gòu)如下:
hello-world/
├── pom.xml
└── src
└── main
└── java
└── com
└── somedomainhere
└── HelloWorld.javaHelloWorld.java 的內(nèi)容與之前相同。
步驟 2:配置 pom.xml
在 pom.xml 中,指定項目的基本信息和插件配置。以下是一個基本的配置,用于生成可執(zhí)行 JAR 文件:
<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>
<groupId>com.somedomainhere</groupId>
<artifactId>hello-world</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.somedomainhere.HelloWorld</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>說明:
<packaging>jar</packaging>:指定項目打包為 JAR 文件。maven-compiler-plugin:設置 Java 編譯版本(這里使用 Java 8)。maven-jar-plugin:配置清單文件,指定主類。
運行以下命令生成 JAR 文件:
mvn clean package
這將在 target 目錄下生成 hello-world-1.0-SNAPSHOT.jar。您可以運行:
java -jar target/hello-world-1.0-SNAPSHOT.jar
步驟 3:包含依賴項(創(chuàng)建胖 JAR)
如果您的項目有外部依賴(如第三方庫),上述 JAR 文件不包含這些依賴,運行時可能拋出 ClassNotFoundException。要創(chuàng)建包含所有依賴的“胖 JAR”,可以使用 maven-assembly-plugin。
在 pom.xml 中添加以下插件配置:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.somedomainhere.HelloWorld</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>運行以下命令:
mvn clean package
這將生成兩個 JAR 文件:
target/hello-world-1.0-SNAPSHOT.jar:不包含依賴的普通 JAR。target/hello-world-1.0-SNAPSHOT-jar-with-dependencies.jar:包含所有依賴的胖 JAR。
運行胖 JAR:
java -jar target/hello-world-1.0-SNAPSHOT-jar-with-dependencies.jar
優(yōu)點:
- 胖 JAR 是自包含的,可以在任何安裝了 Java 的環(huán)境中運行,無需額外配置類路徑。
- 便于分發(fā),適合獨立應用程序。
注意:
- 胖 JAR 可能顯著增加文件大小,因為它包含所有依賴。
- 確保依賴的許可證允許這種打包方式。
示例:添加依賴
假設您的程序使用 Apache Commons Lang 庫。更新 pom.xml 添加依賴:
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>修改 HelloWorld.java 使用該庫:
package com.somedomainhere;
import org.apache.commons.lang3.StringUtils;
public class HelloWorld {
public static void main(String[] args) {
String message = "hello, world of java";
System.out.println(StringUtils.capitalize(message));
}
}重新運行 mvn clean package,生成的胖 JAR 將包含 Commons Lang 庫,運行時將輸出:
Hello, world of java
高級主題
使用 Maven Shade 插件
雖然 maven-assembly-plugin 適用于大多數(shù)場景,但 maven-shade-plugin 提供了更高級的功能,如包重命名(shading)以避免類沖突。配置示例:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.somedomainhere.HelloWorld</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>運行 mvn clean package 將生成包含所有依賴的 JAR 文件。Shade 插件特別適合需要處理復雜依賴沖突的項目。
使用 jpackage 工具
自 Java 14 起,JDK 引入了 jpackage 工具,可創(chuàng)建平臺特定的安裝程序(如 Windows 的 .exe 或 macOS 的 .dmg)。它將應用程序和 JRE 打包在一起,適合分發(fā)給非技術用戶。
示例命令:
jpackage --input target --name HelloWorld --main-jar hello-world-1.0-SNAPSHOT.jar --main-class com.somedomainhere.HelloWorld
由于 jpackage 超出了 JAR 文件的范圍,建議有興趣的讀者參考 Oracle 文檔。
常見問題與注意事項
| 問題 | 解決方案 |
|---|---|
| java -jar 拋出 no main manifest attribute | 確保清單文件中包含 Main-Class 屬性,或在 jar 命令中使用 -e 選項指定主類。 |
| 運行胖 JAR 時出現(xiàn) ClassNotFoundException | 確認 maven-assembly-plugin 已正確配置,且所有依賴都包含在 JAR 中。 |
| JAR 文件過大 | 考慮使用普通 JAR 并通過類路徑管理依賴,或檢查是否有不必要的依賴。 |
| 雙擊 JAR 文件無法運行 | 確保系統(tǒng)安裝了 JRE,并將 .jar 文件關聯(lián)到 javaw.exe。 |
總結(jié)
打包和運行 JAR 文件是 Java 開發(fā)中的核心技能。通過 jar 工具,您可以手動創(chuàng)建簡單的 JAR 文件,適合小型項目或?qū)W習目的。而 Maven 提供了強大的自動化功能,能夠處理復雜的依賴管理和構(gòu)建流程,使其成為現(xiàn)代 Java 開發(fā)的首選工具。本文通過詳細的示例和配置,展示了從基礎到高級的 JAR 文件管理方法。
無論您是初學者還是經(jīng)驗豐富的開發(fā)者,掌握這些技術將顯著提高您的開發(fā)效率。建議進一步探索 Maven 的其他插件(如 maven-shade-plugin)或 jpackage 工具,以滿足更復雜的部署需求。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Java class文件格式之屬性詳解_動力節(jié)點java學院整理
這篇文章主要介紹了Java class文件格式之屬性詳解,需要的朋友可以參考下2017-06-06
詳解使用spring boot admin監(jiān)控spring cloud應用程序
本篇文章主要介紹了詳解使用spring boot admin監(jiān)控spring cloud應用程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11
Spring Bean創(chuàng)建和循環(huán)依賴
這篇文章主要介紹了Spring Bean創(chuàng)建和循環(huán)依賴,講述了Spring容器中?Bean?的創(chuàng)建過程已經(jīng)主要的方法,另外也著重分析了循環(huán)依賴的問題,需要的小伙伴可以參考一下2022-05-05
關于spring 掃描不到jar中class文件的原因分析及解決
這篇文章主要介紹了關于spring 掃描不到jar中class文件的原因分析及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08

