1. 程式人生 > >Gradle基礎:8:使用plugin進行jar檔案打包

Gradle基礎:8:使用plugin進行jar檔案打包

這篇文章主要目的是用來介紹plugin,為了對本身非常枯燥的內容進行說明,這裡特意跟前面的文章一樣,準備了一個更加枯燥的例子(如何使用gradle的java plugin來打出一個jar檔案),在枯燥的的gradle的學習的旅程中新增一絲不那麼煩躁的情緒。

gradle的plugin是什麼

回答是什麼的定義往往比較複雜,現在我們知道gradle是什麼了,一個自動構建工具,但是它是如何支援java和groovy的編譯構建呢?這是一個很好的問題,因為答案就是plugin。
不同的plugin提供了不同的功能,從這個角度上來說,gradle就是一個框架,而具體實現則是通過plugin來實現的,從某種意義上來說,maven的設計思路也是如出一轍。
我們不再談論容易引起爭執的設計思路是否一致的問題,至少下面的內容可以使得我們對於gradle的plugin的理解有一個開始:

gradle提供了一個用於構建的框架結構,具體的實際的構建通過不同的plugin來實現。

gradle有哪些plugin

相較於是什麼的問題,有什麼就沒有任何分歧了,在當前穩定的gradle的4.10.2版本,gradle官方提供的plugin主要有如下這些:

用途 Plugin名稱 功能說明
JVM語言和框架 Java 提供java專案的構建支援
JVM語言和框架 Java Library 提供java庫的構建支援
JVM語言和框架 Groovy 提供groovy專案的構建支援
JVM語言和框架 Scala 提供scala專案的構建支援
JVM語言和框架 Play 提供playframework應用的構建支援
JVM語言和框架 ANTLR 提供使用ANTLR生成詞法分析器的支援
打包與釋出 Application 提供構建基於JVM的可執行的應用程式的支援
打包與釋出 WAR 提供WAR檔案結構的打包支援
打包與釋出 EAR 提供EAR結構的J2EE應用的打包支援
打包與釋出 OSGi 提供建立OSGi包的支援
打包與釋出 Maven Publish 提供Maven相容的倉庫的釋出支援
打包與釋出 Ivy Publish 提供Ivy相容的倉庫的釋出支援
打包與釋出 Legacy Maven Plugin 對使用了legacy機制的製品釋出到Maven相容的倉庫的支援
打包與釋出 Distribution 提供ZIP或者tar檔案釋出方式的支援
打包與釋出 Java Library Distribution 提供建立包含執行依賴的java庫的zip檔案的支援
程式碼分析 Checkstyle 可整合使用checkstyle進行程式碼檢查
程式碼分析 FindBugs 可整合使用FindBugs用於程式碼檢查
程式碼分析 PMD 可整合使用PMD用於程式碼檢查
程式碼分析 JDepend 可整合JDepend用於程式碼檢查
程式碼分析 JaCoCo 可整合JaCoCo用於覆蓋率資料提供
程式碼分析 CodeNarc 可整合CodeNarc用於groovy程式碼檢查
IDE整合 Eclipse 用於建立可以被Eclipse的IDE開啟的專案等
IDE整合 IntelliJ IDEA 用於建立可以被IntelliJ IDEA的IDE開啟的專案
Utility Base 提供生命週期的常用task,比如clean等
Utility Build init 用於在新專案建立gradle骨架結構或者從maven等進行遷移是提供guide
Utility Signing 提供對於生成的檔案和製品的數字化簽名的支援
Utility Plugin Development 提供更方便的方式用於開發Gradle Plugin

試驗示例

這篇文章將通過使用java plugin來對一個簡單的java應用進行jar的打包,來說明在gradle中plugin的使用方式。

事前準備

做一個簡單的HelloWorld的java類,然後將其打成一個jar檔案,具體的檔案結構如下所示

liumiaocn:plugin liumiao$ ls
build.gradle    settings.gradle src
liumiaocn:plugin liumiao$ tree .
.
├── build.gradle
├── settings.gradle
└── src
    └── main
        ├── java
        │   └── com
        │       └── liumiaocn
        │           └── HelloPlugin.java
        └── resources
            └── com
                └── liumiaocn
                    └── resource.xml

8 directories, 4 files
liumiaocn:plugin liumiao$ 

settings.gradle

liumiaocn:plugin liumiao$ cat settings.gradle 
rootProject.name = 'jarPluginSample'
liumiaocn:plugin liumiao$ 
  • rootProject.name在建立jar檔案時根據約定會被使用。

build.gradle

liumiaocn:plugin liumiao$ cat build.gradle 
apply plugin: 'java'
version = '1.0'

jar {
    manifest {
        attributes 'Implementation-Title': 'Gradle plugin sample: create jar distribution',
                   'Implementation-Version': version,
                   'Created-By': 'liumiaocn'
    }
}
liumiaocn:plugin liumiao$ 
  • apply plugin: ‘java’:是引入java plugin支援唯一需要做的事情
  • version:在生成的jar檔案中會按照約定生成在jar檔名中
  • jar{}: jar是java plugin所實現的task之一,這裡使用它直接用來生成jar檔案
  • manifest{}:用於設定MANIFEST.MF的內容

resource檔案

liumiaocn:plugin liumiao$ cat src/main/resources/com/liumiaocn/resource.xml 
<?xml version="1.0" encoding="UTF-8"?>
liumiaocn:plugin liumiao$ 
  • 僅僅是一個示例,用於演示在jar檔案中資原始檔也被打包的過程

HelloWorld類

liumiaocn:plugin liumiao$ cat src/main/java/com/liumiaocn/HelloPlugin.java 
package com.liumiaocn;

public class HelloPlugin {
    private final String pluginName;

    public HelloPlugin(String name) {
        this.pluginName= name;
    }

    public void grettings() {
      System.out.println("Hello, " + this.pluginName);
    } 
}
liumiaocn:plugin liumiao$

確認project資訊

liumiaocn:plugin liumiao$ gradle projects

> Task :projects

------------------------------------------------------------
Root project
------------------------------------------------------------

Root project 'jarPluginSample'
No sub-projects

To see a list of the tasks of a project, run gradle <project-path>:tasks
For example, try running gradle :tasks

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
liumiaocn:plugin liumiao$ 

打包過程

使用普通方式的jar檔案打包,過程繁瑣的多,而這裡,只需要gradle jar即可

liumiaocn:plugin liumiao$ ls
build.gradle    settings.gradle src
liumiaocn:plugin liumiao$ gradle jar

BUILD SUCCESSFUL in 0s
3 actionable tasks: 3 executed
liumiaocn:plugin liumiao$
  • 結果確認
    可以看到jar檔案已經生成在lib下了
liumiaocn:plugin liumiao$ ls
build           build.gradle    settings.gradle src
liumiaocn:plugin liumiao$ tree build
build
├── classes
│   └── java
│       └── main
│           └── com
│               └── liumiaocn
│                   └── HelloPlugin.class
├── libs
│   └── jarPluginSample-1.0.jar
├── resources
│   └── main
│       └── com
│           └── liumiaocn
│               └── resource.xml
└── tmp
    ├── compileJava
    └── jar
        └── MANIFEST.MF

13 directories, 4 files
liumiaocn:plugin liumiao$
  • 確認jar檔案內容
liumiaocn:plugin liumiao$ zipinfo build/libs/jarPluginSample-1.0.jar 
Archive:  build/libs/jarPluginSample-1.0.jar
Zip file size: 1292 bytes, number of entries: 6
drwxr-xr-x  2.0 unx        0 b- defN 18-Nov-24 06:49 META-INF/
-rw-r--r--  2.0 unx      146 b- defN 18-Nov-24 06:49 META-INF/MANIFEST.MF
drwxr-xr-x  2.0 unx        0 b- defN 18-Nov-24 06:49 com/
drwxr-xr-x  2.0 unx        0 b- defN 18-Nov-24 06:49 com/liumiaocn/
-rw-r--r--  2.0 unx      758 b- defN 18-Nov-24 06:49 com/liumiaocn/HelloPlugin.class
-rw-rw-r--  2.0 unx       39 b- defN 18-Nov-24 06:49 com/liumiaocn/resource.xml
6 files, 943 bytes uncompressed, 606 bytes compressed:  35.7%
liumiaocn:plugin liumiao$ 

注:jar就是一個壓縮檔案,沒有zipinfo,你可以使用大部分解壓軟體均可看到內部內容

  • 確認MANIFEST.MF
liumiaocn:plugin liumiao$ cat build/tmp/jar/MANIFEST.MF 
Manifest-Version: 1.0
Implementation-Title: Gradle plugin sample: create jar distribution
Implementation-Version: 1.0
Created-By: liumiaocn

liumiaocn:plugin liumiao$ 

其他task

除了jar之外,比如gradle clean的task也被實現了,其實就是刪除約定方式申城的構建目錄build等。

liumiaocn:plugin liumiao$ ls
build           build.gradle    settings.gradle src
liumiaocn:plugin liumiao$ gradle clean

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
liumiaocn:plugin liumiao$ ls
build.gradle    settings.gradle src
liumiaocn:plugin liumiao$

除此之外其他的task以及其關聯關係,這篇文章不再說明,在後續進一步介紹之後再行展開。

liumiaocn:plugin liumiao$ gradle tasks

> Task :tasks

------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles test classes.

Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.

Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'jarPluginSample'.
components - Displays the components produced by root project 'jarPluginSample'. [incubating]
dependencies - Displays all dependencies declared in root project 'jarPluginSample'.
dependencyInsight - Displays the insight into a specific dependency in root project 'jarPluginSample'.
dependentComponents - Displays the dependent components of components in root project 'jarPluginSample'. [incubating]
help - Displays a help message.
model - Displays the configuration model of root project 'jarPluginSample'. [incubating]
projects - Displays the sub-projects of root project 'jarPluginSample'.
properties - Displays the properties of root project 'jarPluginSample'.
tasks - Displays the tasks runnable from root project 'jarPluginSample'.

Verification tasks
------------------
check - Runs all checks.
test - Runs the unit tests.

Rules
-----
Pattern: clean<TaskName>: Cleans the output files of a task.
Pattern: build<ConfigurationName>: Assembles the artifacts of a configuration.
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.

To see all tasks and more detail, run gradle tasks --all

To see more detail about a task, run gradle help --task <task>

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
liumiaocn:plugin liumiao$ 

總結

plugin在gradle中是一個非常重要的概念,正是使用了這種方式,才使得gradle有了更好的靈活性,這篇文章通過一個簡單的例子介紹了plugin的使用方式,使得我們對其有了一個大體上的認識,詳細的說明,後面會進一步展開。

參考文章

https://docs.gradle.org/current/userguide/plugin_reference.html
https://www.playframework.com/
https://www.antlr.org/
https://guides.gradle.org/migrating-from-maven/
https://docs.gradle.org/current/userguide/java_plugin.html