shadow
shadow copied to clipboard
Shadow is not working with Kotlin Multiplatform plugin
Please check the User Guide before submitting "how do I do 'x'?" questions!
Shadow Version
5.0.0
Gradle Version
5.3.1
Expected Behavior
The shadowJar
task should appear and work.
Actual Behavior
Only the knows
task appears and the shadow task don't appear and don't work.
Gradle Build Script(s)
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
...
plugins {
kotlin("multiplatform")
id("com.github.johnrengelman.shadow") version "5.0.0"
}
...
tasks.withType<ShadowJar> {
baseName = "app"
classifier = ""
version = ""
}
//// This works but do not really creat the fatJar, java -jar myFatJar.jar doesn't run and inside of this jar we have just a MANIFEST.MF with a single line of information.
//tasks.create("shadowJar", ShadowJar::class.java) {
// baseName = "my_project"
// classifier = ""
// version = ""
//}
Content of Shadow JAR (jar tf <jar file>
- post link to GIST if too long)
None.
I was able to have something working with:
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
...
plugins {
kotlin("multiplatform")
id("com.github.johnrengelman.shadow") version "5.0.0"
id("java")
}
...
tasks.withType<ShadowJar> {
manifest {
attributes.put("Main-Class", "com.example.ExampleKt")
}
val target = kotlin.targets.jvm("myTarget")
from(target.compilations["main"].output)
val runtimeClasspath = target.compilations["main"].compileDependencyFiles as Configuration
configurations = mutableListOf(runtimeClasspath)
}
But I need to be checking the other options available.
Your workaround didn't work for me, I had to modify it a little bit, maybe it helps someone :)
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
kotlin("multiplatform") version "1.3.50"
id("com.github.johnrengelman.shadow") version "5.1.0"
}
val ktor_version: String by project
val kotlin_version: String by project
val logback_version: String by project
repositories {
mavenCentral()
mavenLocal()
jcenter()
maven { url = uri("https://kotlin.bintray.com/ktor") }
}
group = "<group>"
kotlin {
jvm {
compilations["main"].defaultSourceSet {
dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation("io.ktor:ktor-server-netty:$ktor_version")
implementation("ch.qos.logback:logback-classic:$logback_version")
implementation("io.ktor:ktor-server-core:$ktor_version")
implementation("io.ktor:ktor-server-host-common:$ktor_version")
implementation("io.ktor:ktor-metrics:$ktor_version")
implementation("io.ktor:ktor-auth:$ktor_version")
implementation("com.pi4j:pi4j-core:1.2")
}
}
compilations["test"].defaultSourceSet {
dependencies {
implementation("io.ktor:ktor-server-tests:$ktor_version")
}
}
}
js().compilations["main"].defaultSourceSet {
dependencies {
implementation(kotlin("stdlib-js"))
}
}
}
tasks {
val shadowCreate by creating(ShadowJar::class) {
manifest {
attributes["Main-Class"] = "<mainfullyqualified>"
}
archiveClassifier.set("all")
from(kotlin.jvm().compilations.getByName("main").output)
configurations =
mutableListOf(kotlin.jvm().compilations.getByName("main").compileDependencyFiles as Configuration)
}
val build by existing {
dependsOn(shadowCreate)
}
}
You actually need also runtime dependencies imo, so the valid full configuration (with Kotlin idiomatic syntax) would contain
tasks.withType<ShadowJar> {
manifest {
attributes("Main-Class" to "main.fully.qualified.Class")
}
archiveClassifier.set("all")
val main by kotlin.jvm().compilations
from(main.output)
configurations += main.compileDependencyFiles as Configuration
configurations += main.runtimeDependencyFiles as Configuration
}
Is there a plan to support this feature? As I see, Kotlin is moving towards "multiplatform with single target" instead of the platform-specific Kotlin plugins (e.g. js will be deprecated, or it is already).
The previous mentioned tasks wouldn't compile on my end. Fixed it by doing:
tasks.withType<ShadowJar> {
manifest {
attributes.put("Main-Class", "MainKt") // "MainKt" or w/e your main class is
}
val target = kotlin.targets.named("desktop").get() //"desktop" or w/e name your jvm target is
from(target.compilations["main"].output)
val runtimeClasspath = target.compilations["main"].compileDependencyFiles
configurations = mutableListOf(runtimeClasspath)
}
EDIT: The above works on a sample project but doesnt work on my main project. The shadowJar
task is not in the tasks. Trying to figure this out.
EDIT 2: Figured it out. Needed to add id("java")
in the plugins. Without it, the shadowJar
task doesnt appear in tasks. Not sure how this will work as my multiplatform project is targeting Android too, and Android complains that you can't use java
with libs.plugins.androidApplication
but I'll figure it out.
@alexstyl did you manage to come up with a solution for the Android target?