For a few months, there's a heated discussion ongoing in Guava's issues (#3302, #3320) about having introduced several internal dependencies, namely "failureaccess" and "listenablefuture".

Some of the introduced dependencies are empty, as evidenced by their version-name: com.google.guava:listenablefuture:jar:9999.0-empty-to-avoid-conflict-with-guava:compile.

The Guava developers tried to explain their reasoning several times, but I just don't understand their argument (I can read the words, I'm missing something to properly understand the rationale), while I understand the opponents' arguments. So I feel a bit biaised, but I try to stay open, hence this question.

So why did the Guava team go this route? And why do other people think it's a bad idea? What would be other, viable alternatives?


Companies who want to legally use open source libraries must account for each dependency in their product, even transitive dependencies. This is especially true if your product is not itself open source. There are legal obligations to be met. Several licenses require user-visible notices, for example.

So companies often have some sort of spreadsheet or database or document somewhere that lists out every dependency and its license and legal obligations. Smaller companies without a lot of resources want this list to be as short as possible. Guava developers are trying to accommodate them by cramming everything into one jar file.

What they missed is companies often don't do this audit by jar file, but by some automated tool based on a dependencies.lock file or similar, because we need to know why the dependency is there. So we suddenly get this weird empty listenablefuture dependency and have to spend a ton of time understanding and explaining it, and a bunch of builds get broken and have to have it explicitly excluded, where a regular listenablefuture package would have barely been noticed.

In other words, in attempting a compromise, they managed to get the worst of both worlds. They created an extra dependency people must still account for, without actually gaining the modularity benefits of physically removing the code from guava. The only people happy with this change are those who have been wanting to just use listenablefuture without pulling in the massive, incohesive guava library.


Hmm hard to untangle but I guess I would sum it up as follows

Google has a class


This class is used, literally copied, in two places

  1. Guava : "Guava is a set of core libraries that includes new collection types..."

  2. Android

So when you compile programs which use both you get an error.

The solution they have implemented is to split the class out into a library. Which can then be used by both.

But this is unconventional for a "set of core libraries" which arguably should not depend on anything. (although .net seems to be happy moving stuff into nugets and back again)

Alternate solutions:

  • Remove the class from one of the places and have the place without it depend on the place with it

    Problematic because both libraries are large and non-optional for their target audience.

  • Change Guava to be a Framework, a collection of libraries where you can pick and choose what you want but the compiler ensures that a minimun set are present

    Kind of like .net framework / portable class libs / standard / core etc. But it comes with a different set of problems and also, it looks like people like Guava because it doesn't do this and simply provides a single library with all the functions in.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.