使用 Gradle 將專案做成 Fat Jar 型式的 build.gradle 範列:
Note:
Fat Jar 為把所有 Dependency 都包在一起的一種 Jar 包。有幾種不同的實現,其中 Unshaded 的方式為把依賴的 jar 都解開來,
並一起包進最後的 Jar 包中。
Note:
以下 build.gradle 範例使用了 Gradle Shadow plugin 來打包,但非必須,只使用 Gradle 自帶的 jar task 也可以打包 fat jar,
只是此範例因依賴了 log4j2,因為 log4j2 在打包 fat jar 時會有
多個 Log4j2Plugins.dat 檔被不正常合併的問題
(每個 log4j plugin 的 Log4j2Plugins.dat 被合成一個檔,但內容互相蓋掉而沒有將內容正確合併),
所以使用了 Gradle Shadow plugin 的 Log4j2PluginsCacheFileTransformer 來解決。
此範例使用了 Gradle 7.3.3 版,建立 Fat Jar 的指令為:
./gradlew clean shadowJar
bundle.gradle :
plugins { // Apply the java-library plugin to add support for Java Library id 'java-library' id 'application' id 'com.github.johnrengelman.shadow' version '7.1.2' } java { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } mainClassName = "main.Main" repositories { mavenCentral() } configurations { externalLibs } dependencies { // This dependency is exported to consumers, that is to say found on their compile classpath. api 'org.apache.commons:commons-math3:3.6.1' // This dependency is used internally, and not exposed to consumers on their own compile classpath. implementation 'com.google.guava:guava:28.0-jre' // Use JUnit test framework testImplementation 'junit:junit:4.12' // https://mvnrepository.com/artifact/javax.mail/javax.mail-api implementation group: 'javax.mail', name: 'javax.mail-api', version: '1.6.2' // https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.17.1' // https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.17.1' // https://mvnrepository.com/artifact/org.slf4j/slf4j-api implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' // https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.17.1' //external libs, for example: xxx.dll externalLibs files('xxxExternalLib1, xxxExternalLib2') } shadowJar{ transform(com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer) archiveFileName = "${baseName}.${extension}" } jar { manifest { attributes( 'Main-Class': 'main.Main', "Multi-Release": true ) } from configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } from configurations.externalLibs.collect { it } }
--------------------------------------------------------------
上列 Fat Jar 的 bundle.gradle 內容中,Gradle Shadow plugin 會讀取 jar task 裡的配置。
在 jar task 中,需要加入以下兩條設定來將依賴放到最終的 Jar 檔裡,
否則會只有專案本身的程式被編譯而已:
from configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } from configurations.externalLibs.collect { it }
編譯後的 Jar 檔會被放在專案的
/build/lib 資料夾中,名稱可以用如以下的設定自行修改:
archiveFileName = "${baseName}.${extension}"
Note:
還有其他各種參數值可以使用,例如:${baseName}, ${appendix}, ${version}, ${classifier}, ${extension} 等--------------------------------------------------------------
執行 Gradle 指令除了用自己在電腦上安裝的 Gradle 以外 (可能會跟專案用的版本不同),
也可使用專案中自帶的 Gradle Wrapper 來執行 Gradle 指令,
好處是可以使用跟專案開發時一樣本的 Gradle,
並且就算自己電腦上沒有安裝 Gradle 也可以執行,例如:
./gradlew clean build
如果想更改專案用的 Gradle 版本,可執行以下指令,例如要更改成 7.3.3 版:
./gradlew wrapper --gradle-version 7.3.3
可以查看專案目錄中的
/gradle/wrapper/gradle-wrapper.properties
,其中 distributionUrl 屬性值會有此專案用的 Gradle 資訊,
當電腦中沒有相應版本的 Gradle 時,它會自行下載相應版本
參考資料:
沒有留言 :
張貼留言