$ ./gradlew --version
------------------------------------------------------------
Gradle 7.1.1
------------------------------------------------------------
Build time: 2021-07-02 12:16:43 UTC
Revision: 774525a055494e0ece39f522ac7ad17498ce032c
Kotlin: 1.4.31
Groovy: 3.0.7
Ant: Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM: 11.0.11 (Amazon.com Inc. 11.0.11+9-LTS)
OS: Mac OS X 11.4 x86_64
I have defined tasks.jar
like so:
tasks.jar {
manifest {
attributes(mapOf("Main-Class" to mainClassName))
}
configurations["compileClasspath"].forEach { file: File ->
from(zipTree(file.absoluteFile))
}
}
I have other dependencies in the project that I would like to package into a fat jar.
When I run ./gradlew jar
, the build succeeds but it cannot find the main class:
$ ./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
If I remove this section:
configurations["compileClasspath"].forEach { file: File ->
from(zipTree(file.absoluteFile))
}
then it can find the main class, but the other dependencies are no longer packaged into the fat jar.
$ java -jar build/libs/myapp-0.0.1-SNAPSHOT.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
at mypackage.Hello.<clinit>(Hello.java:8)
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.LogManager
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 1 more
Here is the full build.gradle.kts
file:
group = "mypackage"
version = "0.0.1-SNAPSHOT"
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
withSourcesJar()
}
plugins {
`java-library`
}
repositories {
mavenCentral()
maven {
url = uri("https://mvnrepository.com/artifact/com.microsoft.azure/azure-storage")
}
}
dependencies {
val azureStorageVersion = "12.12.0"
val log4jCoreVersion = "2.14.1"
val log4jSlf4jImplVersion = "2.14.1"
implementation("com.azure:azure-storage-blob:$azureStorageVersion")
implementation("org.apache.logging.log4j:log4j-core:$log4jCoreVersion")
implementation("org.apache.logging.log4j:log4j-slf4j-impl:$log4jSlf4jImplVersion")
val junitVersion = "5.7.1"
testImplementation("org.junit.jupiter:junit-jupiter:$junitVersion")
}
val mainClassName = "mypackage.Hello"
tasks.jar {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
manifest {
attributes(mapOf("Main-Class" to mainClassName))
}
from(configurations.compileClasspath.get().map { if (it.isDirectory) it else zipTree(it) })
}
tasks.test {
useJUnitPlatform()
}