使用 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 時,它會自行下載相應版本
參考資料:
沒有留言 :
張貼留言