-
-
Notifications
You must be signed in to change notification settings - Fork 341
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
Shade third-party dependencies in the plugin classpath #1117
Shade third-party dependencies in the plugin classpath #1117
Conversation
fcf76c7
to
f334366
Compare
Can you send me a PR with all the non shadow stuff? So I don't like this because it defeats the purpose of using a dependency manager. For example, before this change people could include versions of libraries we use in their builds as a way to update us without having to get a new version of GPP. Similarly, I don't know if this is actually how the shadow plugin works, but I'm guessing it won't show any of our dependencies in the POM which means security scanning tools also won't work. We're basically opting out of the ecosystem. Maybe that's fine? I need to think about it a bit more. Have you filed a ticket with Firebase support? They really should be the ones to upgrade. |
Will do.
I completely agree. The problem is on the Gradle side, though; plugins run without classpath isolation, so shading dependencies is the recommended approach by upstream (and why they built support for the Shadow plugin in There is another approach you could take, which is done by the Android Lint plugin: split the plugin into API and implementation artifacts, and have the API code construct a semi-isolated "embedded" classpath loader which loads runtime dependencies, making them available via reflection. This is less simple than shading, and arguably should be performed by Gradle itself, but at least it preserves the dependency information in the POM. You're already halfway there, having a separate Reading up on this: as you're using the Worker API, we could configure workers to use classLoaderIsolation and include Google API dependencies in a separate dependency configuration. This might be the cleanest way to avoid classpath conflicts, and it seems at least to be the most supported method.
Yes, as-is this PR will remove the dependency information from the POM/Gradle-module metadata.
Ticket was filed in July; no response just yet, though it was assigned. I think I will investigate Worker classpath isolation, unless you have objections. There is probably a bit of API leakage into the plugin currently. |
See below.
Alright, that works for me! I want this to be an isolated change so I can easily revert it if the pitchforks show up on the other side of this debate, but separate commits will suffice. So just pull out the unrelated changes in a separate commit and we're good.
Classic google lol.
If you'd like to, go for it! It does sound like the right thing to do. That said, it also sounds like a lot of work 😅, so I'm ok going with the shadow approach until someone complains about it. |
f334366
to
6556415
Compare
I investigated using classLoaderIsolation() for the worker tasks, similar to what SQLDelight is doing here: https://github.com/cashapp/sqldelight/blob/a188d6afb52afce9a736047206ed08405bd8cc3d/sqldelight-gradle-plugin/src/main/kotlin/app/cash/sqldelight/gradle/SqlDelightWorkerTask.kt#L25 It is sort of hacky, because So I cleaned up this change instead. |
Yeah, trying to accumulate changes to an edit in parallel and then commit the edit at the end has been the bane of this project's existence lol. |
configurations["compileOnly"].extendsFrom(shadowImplementation) | ||
configurations["testImplementation"].extendsFrom(shadowImplementation) | ||
|
||
tasks.withType<ShadowJar> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tasks.withType<ShadowJar> { | |
tasks.withType<ShadowJar>().configureEach { |
} | ||
|
||
// Needed to preserve JAR hash for testapp build | ||
tasks.withType<AbstractArchiveTask> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tasks.withType<AbstractArchiveTask> { | |
tasks.withType<AbstractArchiveTask>().configureEach { |
This PR has been automatically marked as stale because it has not had recent activity. |
Feel free to reopen once you're ready. |
Fixes #1091
At least one other Android-related plugin also puts Google API client libraries on the classpath with conflicting versions; see the linked issue.
android-publisher
andplay-publisher
.shadowImplementation
configuration, for which dependency classes will be relocated to a package undercom.github.triplet.gradle.shaded
. Move all non-project dependencies fromimplementation
toshadowImplementation
.com.gradle.plugin-publish
. Asandroid-publisher
is not a plugin itself and doesn't apply that plugin in its build, applyPublishTaskShadowAction
asplugin-publish
does.testapp
: BumpcompileSdk
andtargetSdk
to 34 so it builds with AGP 8.2.0.Tested locally by publishing to
mavenLocal
and using it in another project, by runningcheck
tasks, and by runningtestapp:publishBundle
(which fails due to an auth token issue, but otherwise applies the plugin fine).