I’m trying to use the Gradle shadow plugin to build a fat jar that only includes those dependencies that are specified with “implementation” scope.
Relevant portion of build.gradle.kts:
dependencies {
implementation("org.apache.velocity:velocity-engine-core:2.3")
compileOnly(platform("org.springframework:spring-framework-bom:6.1.1"))
compileOnly("org.springframework:spring-context")
compileOnly("org.springframework:spring-webflux")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
testImplementation(platform("org.junit:junit-bom:5.10.1"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("io.mockk:mockk:1.13.8")
}
tasks {
shadowJar {
// How do I include **only** "implementation" dependencies, transitively?
// That would be only org.apache.velocity:velocity-engine-core:2.3 and its dependencies in this example
this.isEnableRelocation = true
this.relocationPrefix = "myprefix"
this.archiveClassifier = ""
}
}
I’ve been spinning my wheels for a while now and can’t figure out the magic incantation.
Well, you do not want only implementation, you want runtimeClasspath, otherwise you for example might miss runtimeOnly dependencies.
And runtimeClasspath is, what is used by default, which you can also see in its documentation: Configuring Shadowed Dependencies
@Vampire No, I actually want implementation dependencies only, as I’m in a rather unique situation and all runtime dependencies are being supplied by the environment. Please advise.
I did advise, I linked you to the docs where it is documented how to configure what is packed.
But I don’t really get your point.
The “runtime dependencies being supplied by the environment” should not be runtimeOnly but compileOnly.
And thus they would not be in the runtimeClasspath. runtimeOnly is for things that are not supplied at runtime and are not needed at compile-time, but still are needed at runtime.
If that is really not the case for you, it might be a better idea to fix your dependency declarations so that the runtimeClasspath only contains the right things.
My use case is that I need to build a fat library jar that is dynamically loaded by a Spring Boot application. All dependencies listed as compileOnly are provided by the Spring Boot application’s classpath. Those listed in the fat jar library’s implementation scope are the only libraries I want transitively included in the library’s fat jar.
I think this is more of a gradle question than a shadow plugin question. If I could get the magic gradle kotlin source code to get the implementation dependencies and provide those to the shadow plugin, I’d be golden. Just using runtimeClasspath would result in redundant dependencies.
Not really.
Because as I said, compileOnly are compile-only.
They are not part of runtimeClasspath.
So if your goal is to not have compileOnly, you do not need to do anything, as that is the default.
Well, runtime classpath is including elements beyond what I’ve listed as implementation dependencies, some of which are transitive dependencies of implementation dependencies, which of course are fine, and some of which are required by the fact that the library is written in kotlin (several kotlin-stdlib-* libs).
I guess I’ll just leave the redundant dependencies.
I’m not sure I can fully follow.
To make it clearer, can you please provide an MCVE that shows a situation where something you do not want included is included and what?