Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not use mapToOptional() in the shadowRuntimeElements configuration variant #693

Open
netvl opened this issue Jul 16, 2021 · 3 comments
Open

Comments

@netvl
Copy link

netvl commented Jul 16, 2021

Shadow Version

6.1.0, 7.0.0

Gradle Version

6.9

Actual Behavior

The shadowRuntimeElements configuration variant is marked with mapToOptional() here: https://github.com/johnrengelman/shadow/blob/7eaffb78a020e024a3618b9c6f9c54730b8f23c0/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy#L55

I'm not sure if this makes sense. If the user excludes the default apiElements and runtimeElements configurations from being published, ensuring that only the shadowRuntimeElements configuration is published, the POM descriptor is populated with dependencies from the shadow configuration (due to shadowRuntimeElements extending shadow), but they are all marked as optional, which totally does not make sense as they are most definitely not optional.

Expected Behavior

The shadowRuntimeElements variant is not marked as optional.

Gradle Build Script(s)

// Disable apiElements/runtimeElements from being published

components.named<AdhocComponentWithVariants>("java") {
    withVariantsFromConfiguration(configurations.runtimeElements.get()) {
        skip()
    }
    // This one is only needed if the project applies the `java-library` plugin
    withVariantsFromConfiguration(configurations.apiElements.get()) {
        skip()
    }
}

publishing.publications {
    register<MavenPublication>("library") {
        // Will publish the `shadowJar` output only, due to the above configuration
        // But dependencies in the POM descriptor will have the unexpected <optional>true</optional> flag
        from(components["java"])
    }
}

Content of Shadow JAR (jar tf <jar file> - post link to GIST if too long)

N/A

@netvl
Copy link
Author

netvl commented Jul 16, 2021

BTW, I wonder if it makes sense to make the shadowApiElements configuration if the java-library-plugin is applied, and provide two configurations instead of shadow: shadowImplementation which would map to the runtime Maven scope, and shadowApi which would map to the compile Maven scope, and make the shadowApiElements and shadowApi configurations available only with the java-library project.

Also, the shadow.component hacky method would be made completely redundant this way, because it would be sufficient to exclude runtimeElements and apiElements from publishing to publish the shadow jar only, and due to the suggested setup of shadowApiElements/shadowRuntimeElements the semantics of compile/runtime elements would mirror the "regular" artifact.

@netvl
Copy link
Author

netvl commented Jul 16, 2021

To be more formal and detailed with my proposal:

  • Instead of the single shadow configuration, the plugin would provide shadowImplementation (with the java plugin) and shadowApi (with the java-library plugin).
  • For publishing, the plugin would provide shadowRuntimeElements (with the java plugin) and shadowApiElements (with the java-library plugin). The former will extend shadowImplementation, the latter will extend shadowApi. This is similar to how the regular runtimeElements and apiElements configurations behave.
  • Instead of the shadow.component method (whose name is actually confusing because it has no relation to the components mechanism of Gradle at all), provide a method which could be called on the java component and turn off publishing of the variants corresponding to the runtimeElements and apiElements variants. Or maybe make it like a flip switch, to allow choosing between publishing of shadowRuntimeElements/shadowApiElements or runtimeElements/apiElements.
  • Optionally, add a shortcut for the following shadowJar configuration
    tasks.shadowJar {
        archiveClassifier.set("")
        archiveAppendix.set("all")
    }
    This is very useful when publishing the shadow jar instead of the regular JAR file. This will ensure that both the regular and the shadow jar files do not conflict in the build/libs directory, and that the shadow jar is published without a classifier. This of course should only be configured only when publishing of the regualar JAR file is disabled.

@mskopp
Copy link

mskopp commented Oct 27, 2021

"Publishing the shadow jar instead of the regular JAR file" is also a (not very frequent but still existing) use-case for me.
This task includes the necessity to declare dependencies for the published java-library (as usually done with api declaration) as well as completely replace the regular JAR with the shadowJAR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants