-
Notifications
You must be signed in to change notification settings - Fork 10.9k
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
guava:32.1.1-jre conflicts with google-cloud-datastore:2.16.0 #6642
Comments
Do you have any "capability" configuration in your build script? That looks like what's emitting those errors. Alternatively, are you using the Google Cloud Libraries Bill of Materials (BOM)? That should help you use compatible versions of libraries. |
@brettkail-wk The BOM should help you https://cloud.google.com/java/docs/bom#gradle (the same document as David shared above) Declaring Guava version explicitly may help too. I remember @lqiu96 did that in one of our repositories. |
I think I saw a similar error message here: googleapis/sdk-platform-java#1832 (comment) I ended up specifying the guava version, which I believe I see you also do above. Can you see if the comments above help by using the latest libraries-bom ( |
Does the suggestion at https://github.com/google/guava/releases/tag/v32.1.0#user-content-overlap work? I don't know enough about Gradle to say how it compares to the exclusion solution above. |
I used the workaround from this bug implementation("com.google.cloud:google-cloud-datastore:2.16.1") {
modules {
module("com.google.guava:listenablefuture") {
replacedBy("com.google.guava:guava", "listenablefuture is part of guava")
}
}
} that worked for me. |
Thanks. I'm in over my head a bit here. https://github.com/google/guava/releases/tag/v32.1.0#user-content-overlap would still be the first thing I would try. In case that fails, I've added a link to what I'm hoping is a more general version of the |
I am going to look at backing out the handling of The good news is that the (@jjohannes FYI) |
…y `listenablefuture-9999....jar` instead of making Gradle report a conflict that users need to [resolve](https://github.com/google/guava/releases/tag/v32.1.0#user-content-overlap). See discussion in #6642: The Gradle module metadata does multiple things, most of which bring clear benefits but one of which (the `listenablefuture` part) may bring more costs than benefits at this point. (Accordingly, this CL rolls back one tiny fragment of the larger cl/544108700.) Fixes #6642 RELNOTES=Removed the section of our Gradle metadata that caused Gradle to report conflicts with `listenablefuture`. PiperOrigin-RevId: 551959012
The "right" way to solve the conflict would be to add this resolution strategy as suggested in the release notes:
What I am surprised about is that you get a It would be very sad to add the dependency to an empty Jar back to Guava. From my perspective, this is bad practice as everyone using Guava ends up with an empty Jar polluting there runtime classpath – shipping as part of their application in many cases - until they explicitly remove it. I consider removing these unneeded runtime dependencies one of the main advantages with the Gradle metadata. If we make these compromises, we could IMO almost roll back the whole thing. I wonder if it is still worth the extra maintenance effort. Which I can understand if that is what you like to do. The dependencies setup in the Java ecosystem is broken in so many places. Many folks publishing to Maven Central don't seem to understand the consequences of the dependency information they publish. But of course you get all the reports here, because users do a Guava update and then something does not seem to work anymore that worked before. For me issues like this show that what we did is right. Issues with metadata in other libraries are now revealed instead of silently hidden. But of course I also understand that many users won't care about that. |
These Google Java libraries use flatten Maven plugin when publishing pom.xml. https://www.mojohaus.org/flatten-maven-plugin/ This increases the likelihood of library users getting the same transitive dependency versions as the library was built with. Do you know Why redeclaring the transitive dependency, the same version as Guava's, causes Gradle's capability problem (meaning that Gradle considers the redeclaration of dependency, the same version, harmful)? |
I am not very familiar with the flatten-maven-plugin, but I think the flattening does not mean that it re-lists all transitive dependencies. At least that does not sound like a useful default behaviour to me. I think it is about flattening the parent POM hierarchy. Can you point me at the source repo for 'grpc-google-cloud-datastore-admin-v1'? I would be interested in what is going on, but wasn't able to find the sources. The problem right now ist that the dependency was removed from Guava completely for Gradle users. Because we don't need it anymore to avoid potential problems. Instead we use Gradle's capability concept (see also https://blog.gradle.org/guava). 'grpc-google-cloud-datastore-admin-v1' now adds this dependency back that we do not want to have anymore. And the new capability-based solution then reports the conflict. |
Thanks to you both for the information. My vague memory (as someone who occasionally poked my head in on conversations years ago) is that Google Cloud (like, e.g., Spring) wants to use the same version of all dependencies across all the artifacts that it releases. They do that with a BOM. But a BOM uses Perhaps each Google Cloud project could exclude the listenablefuture dependency and then set some |
The source of grpc-google-cloud-datastore-admin-v1 is https://github.com/googleapis/java-datastore/blob/main/grpc-google-cloud-datastore-admin-v1/pom.xml. Its parent is google-cloud-shared-config https://github.com/googleapis/java-shared-config/blob/main/pom.xml#L238, which uses flatten-maven-plugin with
That's new information to me. Thank you. I was only looking at its pom.xml where it shows: cpovirk has shared https://github.com/google/guava/blob/347ef4ec219fed3b2801c094d800af1dd5be1a76/guava/module.json to me. (A
For future releases, it might work. But I have concern about the restriction that Gradle users cannot use the latest Guava and Google Cloud libraries prior to August 2023 together. |
One other thing I might try to look into: Would it be better if Guava claimed to serve as an implementation of version 9999... of listenablefuture instead of version 1? |
Thank you for the explanations. I don't understand though why You can't expect a tool like Gradle or Maven to keep doing good automatic conflict resolution if you feed it wrong metadata. This is a general problem with the flattenDependencyMode setup in google-cloud-shared-config. This issue is just one of the things that can happen (and now happened). If Guava would make other changes to its dependencies, you can run into different trouble - with Gradle or Maven alike. The fix for me is clearly to not do As for the current situation: There is nothing broken from my perspective. Users can address the capability conflicts as described further up. I think changing something in the Guava metadata in the next release would be the wrong thing to do. If you do that as a reaction to the discussion here, you admit that you cannot change anything in the dependencies ever, because upstream consumers decided to blindly copy your dependencies at a point in the past and now you are "locked in" because of them. This should be fixed in |
…y `listenablefuture-9999....jar` instead of making Gradle report a conflict that users need to [resolve](https://github.com/google/guava/releases/tag/v32.1.0#user-content-overlap). See discussion in #6642: The Gradle module metadata does multiple things, most of which bring clear benefits but one of which (the `listenablefuture` part) may bring more costs than benefits at this point. (Accordingly, this CL rolls back one tiny fragment of the larger cl/544108700.) Fixes #6642 RELNOTES=Removed the section of our Gradle metadata that caused Gradle to report conflicts with `listenablefuture`. PiperOrigin-RevId: 551959012
(I had that commit set up to auto-merge when I sent it for review on Friday; I didn't think about the fact that it might end up silently auto-closing this issue in the middle of the discussion.) I think there are two things that The Maven problem comes up if google-cloud-foo depends on google-cloud-bar, which in turn uses an API added in (say) guava-32.1.0. A Maven user of google-cloud-foo might get guava-32.1.0. But if the user also depends on ancientlib, which depends on guava-10.0, then Maven picks guava-10.0 because of the "closest wins" policy. (I am not telling you anything you don't know here, nor anything that Guava users don't know from bitter experience....) By using The other part of the story is the meaning of "having a dependency": If some Guava developer introduces a bug into The downside that I would not have predicted is what we're seeing here. (I do recall some thought to a related downside: If a user wants to exclude (say) Guava's
The good news is here is that we already despair of changing anything :-P I exaggerate, but there are reasons that we almost never remove even To close, I do still want to emphasize that I expect the handling of the jre/android variants to be a big win for users, and so the metadata as a whole will be, too. (Plus, as you say, it will shake out some existing strange project setups, hopefully most of which are more easily changed than this one.) We still hear about variant issues regularly (e.g., #6567, google/compile-testing#363—both from Gradle users who should be in good shape once they pick up a recent Guava version). |
Thanks for explaining the relationship between Mavens "closes win" strategy and the |
Using gradlew 7.4, this
build.gradle
file:...fails like this:
It succeeds with 32.0.1-jre or if excluding the transitive listenablefuture dependency from datastore:
The text was updated successfully, but these errors were encountered: