我有一个Java项目,有多个依赖项,我想用Kotlin DSL将其打包到Gradle的fat jar中。
当我运行./gradlew jar
时,构建成功,但当我试图运行它时,它找不到主类:
$ ./gradlew jar
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed
$ java -jar build/libs/myapp-0.0.1-SNAPSHOT.jar
Error: Could not find or load main class mypackage.Hello
Caused by: java.lang.ClassNotFoundException: mypackage.Hello
$ jar xf build/libs/myapp-0.0.1-SNAPSHOT.jar META-INF/MANIFEST.MF
$ cat META-INF/MANIFEST.MF
Manifest-Version: 1.0
Main-Class: mypackage.Hello
$ jar -tf build/libs/myapp-0.0.1-SNAPSHOT.jar | grep mypackage 1
mypackage/
mypackage/Hello.class
以下是完整的build.gradle.kts
文件:
group = "myapp"
version = "0.0.1-SNAPSHOT"
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
withSourcesJar()
}
plugins {
java
}
repositories {
mavenCentral()
maven {
url = uri("https://mvnrepository.com/artifact/com.microsoft.azure/azure-storage")
}
}
dependencies {
implementation("com.azure:azure-storage-blob:12.12.0")
}
val mainClassName = "mypackage.Hello"
tasks.jar {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
manifest.attributes.apply {
put("Class-Path", configurations.runtimeClasspath.get().asPath)
put("Main-Class", mainClassName)
}
from(configurations.compileClasspath.get().map { if (it.isDirectory) it else zipTree(it) })
}
tasks.test {
useJUnitPlatform()
}
和一个链接到我的repo: https://github.com/darkasphalt/myapp
检查jar的内容。问题是,您包含了库中的所有内容。这也增加了来自java模块系统的文件,如module-info.class
。这可能会隐藏你的Main类。
简单修复
你的主要作品,如果你:
)删除导入implementation("com.azure:azure-storage-blob:12.12.0")
或
b)删除类路径配置:from(configurations.compileClasspath.get().map { if (it.isDirectory) it else zipTree(it) })
那么简单的java -jar myapp-0.0.1-SNAPSHOT.jar
将打印出:
你好
安装ShadowJar
要解决以正确的方式打包一个fat jar的问题,你可以使用ShadowJar插件。有了这样的设置,绑定的jar就可以工作了:
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
group = "myapp"
version = "0.0.1-SNAPSHOT"
plugins {
java
application
id("com.github.johnrengelman.shadow").version("7.0.0")
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
withSourcesJar()
}
repositories {
mavenCentral()
maven {
url = uri("https://mvnrepository.com/artifact/com.microsoft.azure/azure-storage")
}
}
application() {
mainClass.set("mypackage.Hello")
}
dependencies {
implementation("com.azure:azure-storage-blob:12.12.0")
}
// Configure Shadow to output with normal jar file name:
tasks.named<ShadowJar>("shadowJar").configure {
minimize()
}
tasks {
build {
dependsOn(shadowJar)
}
}
tasks.test {
useJUnitPlatform()
}