GradleUp / shadow

Gradle plugin to create fat/uber JARs, apply file transforms, and relocate packages for applications and libraries. Gradle version of Maven's Shade plugin.
https://www.gradleup.com/shadow/
Apache License 2.0
3.77k stars 395 forks source link

Publishing a shaded JAR #986

Open ansman opened 1 month ago

ansman commented 1 month ago

Describe your use-case which is not covered by existing documentation.

I need to shade a specific library that does not maintain binary compatibility, I thus want to publish a JAR that has shadowed and relocated a specific library, while all other libraries are exposes in the POM like normal.

This worked fine until 8.3.1 when #904 was merged.

The issue is that the shadowJar task uses the all classifier by default which isn't supported by non Gradle clients. You can manually set the classifier to null or '' but then it conflicts with the jar task.

It would be great to call this specific use case out in the docs as it's quite common.

Reference any relevant documentation, other materials or issues/pull requests that can be used for inspiration.

My current solution can be found in my auto-dagger project.

Here is the relevant snippet:

pluginManager.withPlugin("com.gradleup.shadow") {
    val compileShaded: Configuration by configurations.creating
    configurations.named("compileOnly") { extendsFrom(compileShaded) }
    configurations.named("testRuntimeOnly") { extendsFrom(compileShaded) }
    // Since we use a custom configuration we make the shadow configuration extend the implementation
    // configuration to correctly include dependencies in the POM
    configurations.named("shadow") { extendsFrom(configurations["implementation"]) }

    // Since we change the classifier of the shadowJar we need to disable the default jar task or we'll get two
    // artifacts that have the same classifier
    tasks.named<Jar>("jar") {
        archiveClassifier.set("ignored")
    }

    tasks.named<ShadowJar>("shadowJar") {
        archiveClassifier.set("")
        configurations = listOf(compileShaded)
        isEnableRelocation = true
        relocationPrefix = "se.ansman.dagger.auto${project.path.replace(':', '.').replace('-', '_')}"
        mergeServiceFiles()
    }

    pluginManager.withPlugin("org.gradle.java-test-fixtures") {
        configurations.named("testFixturesImplementation") { extendsFrom(compileShaded) }
        configurations.named("testFixturesImplementation") { extendsFrom(configurations["implementation"]) }
        configurations.named("testFixturesApi") { extendsFrom(configurations["api"]) }
    }
}

The main downside of this is that other projects that depend on this would have to depend on the shadow configuration which in my case isn't an issue since none of these dependant modules are published but I can imagine it would be an issue if they were.

Are you interested in contributing to the documentation?

No response