辛苦所得,轉載還請注明: https://www.cnblogs.com/applerosa/p/9739007.html
得空整理了關於java 開發中,所有打包方式的 一個操作方法, 有基於IDE的,有基於構建工具的.
這里還是比較建議新手朋友盡快習慣 maven 和 gradle 等構建工具自帶的打包方式. 不是說逼格高,的確是因為不依賴 IDE, 配置好 一兩行命令就搞定. 離開IDE 照樣出包.
大概分為這幾個步驟
一. 關於Jar 包(example.jar) 的 結構/作用/使用 說明
二. 不依賴IDE和構建工具生成一個簡單的 Jar 包
依賴編譯器
三. 基於IDE( Eclipse /IDEA)生成 jar 包
四. 基於IDE( Eclipse /IDEA)生成可執行 jar 包
只依賴構建工具
五. 基於Maven 生成 Jar 包[第三方依賴包和代碼文件放在一起, 為一個包] [fat-jar]
六. 基於Maven 生成 Jar 包[分離第三方依賴包, 獨立存放在 *_libs 中][推薦]
七. 基於Gradle 生成 Jar 包 [第三方依賴包和代碼文件放在一起, 為一個包] [fat-jar]
八. 基於Gradle 生成 Jar 包 [分離第三方依賴包, 獨立存放在 *_libs 中]
注意事項:
- 項目均為簡單項目,不存在不懂得情況,代碼相關廢話不說;
- 第三條中的項目,是一個簡單的工具類集合.(就是把工具類打成一個JAR 包,方便其他項目使用,如我們使用的大多數第三方類庫)
- 第四五六七八條 中的項目均為同一個簡單的SpringBoot項目,構建方式不同而已\
本文用的jar包查看工具: JD-GUI.jar
使用方式:右鍵>打開方式> Java(TM) ...
官網: http://jd.benow.ca/ (JD-GUI的Tab欄有Download,里面提供獨立版本,eclispe/idea插件版本)
一. 關於Jar 包(example.jar) 的詳細說明
JAR(Java Archive File),Java 檔案文件.通常jar 為壓縮文件, 與 ZIP/RAR 壓縮文件 一樣的概念,區別在於 jar 文件中存在一個名為META-INF/MANIFEST.MF 的清單文件,
關於JAR包的描述信息、啟動時的配置信息和安全性信息等均保存在其中,可以理解為 jar 的一個'配置說明文件'
以spring-boot-starter-2.0.5.RELEASE.jar為例,用工具打開
一般都會存在一些屬性,某些屬性只是為了說明jar的信息,還有一些屬性,時為能夠讓jar正常的執行里面類的功能,比如mysql 的 jar 包 :mysql-connector-java-8.0.11.jar 里面就一堆屬性.
下面選幾個用的到屬性說一下,沒有的參照官方文檔: https://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html
基礎屬性:
Manifest-Version: 用來定義 manifest文件 的版本,例如:Manifest-Version: 1.0 Created-By: 該文件的生成者,一般該屬性是由jar命令行工具生成的,例如:Created-By: Apache Ant 1.8 .2 Signature-Version: 簽名版本 Class-Path: 依賴項列表,若存在多個依賴項時則采用空格分隔。依賴項路徑為以JAR包路徑為參考系的相對路徑, 有個小細節就是, 如果自己生成這個文件,在引用了所有的以來后, 后面還有一個 '.', 對,一個點;
可執行屬性:
Main-Class: main函數所在的全限定類名,該類必須是一個可執行的類,可以俠義理解為存在 main()函數的類
一旦定義了此屬性,即可通過 java -jar example.jar 來運行此jar包
無關緊要的屬性,看看就行,用到了再找:
還有關於其他的jar的相關的: JAR包結構,META-INF/MANIFEST.MF文件詳細說明[全部屬性][打包][JDK]
說了這么多,意思就是這個文件挺重要的,有時候不能運行的時候,可以考慮檢查一下jar包.
二. 不依賴IDE和構建工具生成一個簡單的 Jar 包
這里我們以簡單的demo做例子.
我們知道在所有的 *.java 文件都會經由JDK編譯后生成一個相應的 *.class文件, 通常我們所使用的第三方類庫,和我們所發布的代碼一般都是 *.class文件.
示例1: ExampleMain.java
Example.java
進入文件所在文件夾, 鼠標不選中文件,位於空白處, Shift+鼠標右鍵, 在此處打開CMD/PowerShell 窗口.(進入cmd , cd 命令切換到目錄都可以)
在命令行中執行: javac 文件名.java 即可將 *.java 編譯為 *.class文件,如下圖:
下面我們來說打包.
關於JDK中的打包命令在CMD中輸入jar即可查看,如下圖:
以我們上面創建的Example.* ExampleMain.* 為例:
切回上級 cn 目錄,執行命令: jar cf example01.jar cn
我們來看一眼這個example01.jar 里面的東西:
cn中文件很好理解,因為我們編譯完成本身就有4個文件,關於這個META-INF , 是打包時jdk自動加入進去的,里面保存了一些基礎屬性,關於這個文件有疑問可以去看上面那個寫介紹jar包結構的.
一個很簡單的jar就完成了. 正常情況打包的時候,我們會刪除 *.java , 用的是編譯出的*.class 文件.
上面這個例子打出的jar包為"類庫"概念的包,就是你可以導入使用,導入后,可以直接調用Example中的someMethod() 方法;
下面說可運行jar包
我們的ExampleMain 中包含了一個main()函數,即有一個程序入口. 我們知道關於jar包的META-INF文件夾jdk會自己生成,當然也可以自己指定.
在某個位置(只要你找得到)下新建一個mainfest 的文件(名字隨你起),里面輸入相關的屬性信息:
這里指定了一個程序入口,就是我們說的Example.java 中的 main() 方法. 這里就需要用到jar 參數中的 -m 參數,指定清單屬性信息;
打包語句: jar cmf [mainfese文件] example02.jar [指定的*.class 目錄]
然后就可使用 java-jar example02.jar 執行這個jar包,會輸出我們前面編寫的打印語句
請格外關注這個Class-Path: 這個屬性是依賴環境選項,最基礎的可運行jar包 都會存在這個屬性,就好比運行程序需要JRE 環境一樣.
比如我們的一個web應用, 會在這個地方引入所有的引用的第三方jar包.
另外,請格外注意這個 "點",就是Class-Path 后面這個點(".") .
三. 基於IDE ( Eclipse / IDEA) 生成 jar 包
四. 基於IDE ( Eclipse / IDEA) 生成可執行 jar 包
這兩條放在一起說吧,因為都是依賴IDE的功能生成的,很方便,也不需要手動配置清單文件.
jar 包現在我們大致分為兩類,一類為之提供"類庫"的功能型包, 一類為可運行的包(大多數情況的需求);
下面我們新建一個簡單的springboot項目,因為是demo, 就利用springboot官網提供的在線快速生成工具了,當然也可以自己創建項目.
工具地址: https://start.spring.io/
下面是具體的打包教程:
補充一點,如果打包時不需要把配置文件/靜態文件打入jar包,Eclipse下可以把src/main/resources 右鍵Build Path> Remove 就可以,IDEA 下在選擇編譯輸出目錄時取消resources 的勾選即可
導入之后的文件目錄結構:
他會自動生成程相關demo文件和配置文件,配置文件需要自行添加配置
我們簡單寫個配置和controller 測試
啟動項目,瀏覽器訪問:localhost:8080/demo, (缺省端口為8080) 瀏覽器會返回我們的測試數據,程序demo通過.
下面打包:
Eclipse:
方法:
項目上右鍵 > Export > 選擇需要到處的jar包類型 (JAR file/ Runnable JAR file) > 填寫相關信息 > Finish “類庫”型的選擇: JAR file 可運行的選擇 : Runnable JAR file
我們分別導出兩種包做比較
第一種:無法啟動,類似於”類庫型的”
第二種:導出我們的可運行的jar 包 .(大多數情況是這種,用於項目發布部署等)
在到處界面選擇 Runnable JAR file (絕大多數的選擇)
下面對比一下兩個jar包
第一種”類庫”方式導出的程序,只能提供給哦其他程序通過引用來使用相關的類功能,不能作為程序啟動
第二種 Runnable JAR file 方式的, 可以看見在清單文件中,Claa-Type:中引用所有依賴的jar 包,同時擁有Main-Class 程序入口,可以在當前目錄進入cmd 命令行,使用 java -jar *.jar 來啟動
附上第二種jar包的啟動結果
IDEA:
利用項目的 Artifacts (構建,蠻好用的功能)可以輕易實現這個功能, 他里面更多的是手動定制,比如指定mainfest 清單文件/輸出的*.class 文件等.
我們的兩種jar都是基於這種方式.這里詳細介紹可運行的方式,”類庫”工具類性的一個道理,甚至更簡單,取消一些的導出文件即可
方法:
菜單欄File > Project Structure(也可以使用快捷鍵 Ctrl+ Shift +Alt +S) > 配置好Artifacts 保存> 菜單欄Build > Build Artifacts > 然后點擊操作
選擇 項目設置 Project Setting 下面的 構建 Artifacts , 點擊+號新建一個Artifacts
然后配置相關的構建屬性
這里如果只是構建”類庫”型的jar包,大可以選擇第一種JAR包方式還簡單一些
中途在配置相關屬性的時候,需要注意兩個問題:
1. IDEA的版本問題: 選擇other 類型的構建時,導致不能在jar 包添加mainfest文件
2. 關於mainfest 文件的配置中 class-type: 他是不會添加文件夾前綴,可能需要手條件一下
配置好大概是這么個樣子:
添加完成以后,就可以點擊確定了;
執行構建,輸出jar包
然后選擇我們相關 Artifac > build 即可.
然后就會在配置的輸出目錄內看到這個example-runnable.jar 文件了
結果如下:
下面4個方法,其實也是依賴工具的構建功能
五. 基於Maven 生成 Jar 包 [第三方依賴包和代碼文件放在一起, 為一個包] [fat-jar]
優點: 簡單,無腦
缺點: 包體積過於大,包含所有第三方依賴包和配置文件,每次更新內容過大
這個過於簡單,不提供操作截圖
方法: 在項目文件夾下進入命令行 執行下面兩條mvn 命令即可
mvn compile
mvn pakage
執行完畢之后會在 target 文件夾下生成一個 jar ,這個jar包含了所有的第三方依賴包,清單文件,我們的項目內容,用JD-GUI.jar 工具打開,就能看見所有結果文件,一目了然
六. 基於Maven 生成 Jar 包 [分離第三方依賴包, 獨立存放在 *_libs 中][推薦]
優點: 只需要在pom.xml配置, 然后 配置文件/靜態文件分離,主程序代碼單獨為一個jar包,更新方便推薦方式
缺點: 需要pom.xml 的maven 配置
關於pom.xml配置如下,需要點開+號查看
配置完成之后, 項目目錄下執行,即可輸出: mvn compile mvn pakage

<build> <sourceDirectory>src/main/java</sourceDirectory> <finalName>example</finalName> <resources> <resource> <directory>src/main/resources</directory> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> <include>**/*.jar</include> </includes> </resource> </resources> <plugins> <!--編譯--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <fork>true</fork> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!--用以生成jar包的--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> <configuration> <!--區別於maven本身生成的構件,加上相關后綴--> <classifier>release</classifier> <!--排除的文件以及目錄,這個是以class為當前目錄的--> <excludes> <exclude>picture/**</exclude> <exclude>mapper/**</exclude> <exclude>**.yml</exclude> <exclude>**.xml</exclude> </excludes> <archive> <!--這里是添加當前目錄到classpath的依賴--> <manifestEntries> <class-path>.</class-path> </manifestEntries> <manifest> <addClasspath>true</addClasspath> <!--這個就是清單文件中classpath的前綴配置,比如你把所有jar包放入example_lib文件夾中,這里就配置example_lib--> <classpathPrefix>example_lib/</classpathPrefix> <!--程序入口,main()所在文件的全限定類名--> <mainClass>cn.lnexin.demo.ExampleApplication</mainClass> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal> copy-dependencies </goal> </goals> <configuration> <!--第三方將jar要導出的文件路徑--> <outputDirectory>${project.build.directory}/toufang_lib</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>
關於Gradle的兩種操作新開一篇文章,更新了會貼上鏈接
七. 基於Gradle 生成 Jar 包 [第三方依賴包和代碼文件放在一起, 為一個包] [fat-jar]
八. 基於Gradle 生成 Jar 包 [分離第三方依賴包, 獨立存放在 *_libs 中]