JAVA生成(可執行)Jar包的全面詳解說明 [打包][SpringBoot][Eclipse][IDEA][Maven][Gradle][分離][可執行]


辛苦所得,轉載還請注明: 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 中]

 

注意事項:

  1. 項目均為簡單項目,不存在不懂得情況,代碼相關廢話不說;
  2. 第三條中的項目,是一個簡單的工具類集合.(就是把工具類打成一個JAR 包,方便其他項目使用,如我們使用的大多數第三方類庫)
  3. 第四五六七八條 中的項目均為同一個簡單的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>
詳細的pom.xml 配置

 

 

關於Gradle的兩種操作新開一篇文章,更新了會貼上鏈接

七.  基於Gradle 生成 Jar 包  [第三方依賴包和代碼文件放在一起, 為一個包] [fat-jar]

八.  基於Gradle 生成 Jar 包  [分離第三方依賴包, 獨立存放在 *_libs 中]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM