33.4.1
Today, we are releasing Guava 33.4.1 and a few other 33.4.x releases. All the releases maintain binary compatibility, but they include changes to nullness and the module system that may be disruptive to some users.
Most users can jump straight to 33.4.6 to pick up a few small improvements with no disruption.
If you encounter trouble with 33.4.6, then read on.
Module-system trouble
First, use Guava 33.4.6, not Guava 33.4.5. 33.4.5 was our first attempt to modularize Guava, but we misconfigured our build, so it:
- contains an extra copy of each of its classes
- does not declare its dependencies on artifacts of annotations
These issues are fixed in release 33.4.6. Sorry for the trouble.
Guava 33.4.6 (after a false start in Guava 33.4.5) changes Guava to be a Java module. You can still use Guava without using the module system yourself. However, if your build system automatically recognizes Guava as a module, then you may see errors. As a temporary fix, you can upgrade only to 33.4.4 while you investigate the module problems.
If you see build errors (such as package com.google.common.collect is not visible
), try modifying your module-info.java
to include requires com.google.common;
.
If you see runtime errors, then you may be performing reflection on Guava internals. We recommend not doing this, since Guava internals change frequently, potentially breaking such code. The module system is designed to call attention to this situation, but you can always silence it with --add-opens
, passing the module name (com.google.common
) and package name from your error message along with the name of the module that is accessing Guava's internals (which is also shown in the error message).
Nullness trouble
Nullness annotations have no effect on Java itself, but they do affect nullness checkers, such as NullAway, the Checker Framework, and Kotlin.
If you encounter only a modest number of nullness errors, we recommend upgrading straight to 33.4.5 or higher, suppressing or fixing the errors to prepare for the change.
For build errors from a Java nullness checker, you can generally silence them with @SuppressWarnings
(docs: NullAway, the Checker Framework, Error Prone). Of course, we recommend inspecting at least a few new errors so that you can judge whether the errors are worth fixing instead of just suppressing.
For build errors from Kotlin, there is no supported way to suppress. (If, after reading the instructions here, you believe that one would be valuable, please share your experiences with the Kotlin developers.) You'll instead need to change your code, often in one of the following ways:
- To insert a null value into a collection, you may need to change the collection's type, like from
Multiset<Foo>
toMultiset<Foo?>
.- The same kind of change can be useful for other generic types, like in changing a
FutureCallback<Foo>
to aFutureCallback<Foo?>
so that itsonSuccess
method can still be declared to accept aFoo?
.
- The same kind of change can be useful for other generic types, like in changing a
- When using our immutable collections or other null-hostile types, you may need to make the opposite change, like by using
ImmutableList<Foo>
instead ofImmutableList<Foo?>
.- If you are writing your own generic API, you may need to restrict your type argument to non-null types. For example, for
ImmutableList<T>
to be valid, you may need to change your type-parameter declaration from<T>
to<T: Any>
. Occasionally, you may want to keep the type-parameter declaration as it is but change to usingImmutableList<T & Any>
.
- If you are writing your own generic API, you may need to restrict your type argument to non-null types. For example, for
- You can change the nullness of a type by using
!!
or a cast. These operators sometimes introduce a runtime check where there was not one before. - Or there may be better fixes, such as changing the types of your own parameters to forbid
null
.
Gradual migration
If you encounter a large number of errors when upgrading, then you may wish to upgrade your Guava version incrementally. Guava 33.4.1, 33.4.2, 33.4.3, and 33.4.4 are each one step toward improving Guava's nullness annotations. You may find it easier to upgrade one version at a time. By doing so, you can handle all problems of a particular "kind" at once. Then, once you submit the upgrade, you prevent backsliding of that kind. (Almost all problems should surface in the upgrade to 33.4.1 or the upgrade to 33.4.2.)
If you take this path, you may wish to set -Xjsr305=strict
before even the first Guava upgrade. That flag may identify a subset of problems ahead of the Guava changes. Note, however, that it may also cause Kotlin to detect nullness errors in your usages of any other libraries that use custom nullness annotations. If so, the flag would cause you to have to perform a larger cleanup that the Guava upgrade requires, so you'll have to judge whether that flag would be helpful on net.
Temporary emergency fallback option: Disabling current and future checking of Java APIs
In the worst case, it is possible to tell Kotlin not to produce errors for any usages of JSpecify annotations, both those in Guava and those in other libraries (such as Caffeine and the forthcoming Spring Framework 7). You can do this by setting -Xjspecify-annotations=warn
. If you are considering this, we recommend instead deferring your upgrade of Guava to give yourself time to work through the nullness errors. We are making an effort not to publish a release with new APIs in the near future, so you should be able to safely defer upgrading for a while. If you do still choose to set the flag, we recommend working to remove it in the future, since it will hide more and more errors as time goes by.
For more help
We monitor for Guava questions on StackOverflow. If you believe that you are seeing a bug in a nullness checker, you can report it to the tool owners (e.g., NullAway, the Checker Framework). If you believe that you are seeing a problem with these instructions or with Guava's nullness annotations, report a bug to us.
Maven
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.4.1-jre</version>
<!-- or, for Android: -->
<version>33.4.1-android</version>
</dependency>
Jar files
Guava requires one runtime dependency, which you can download here:
Javadoc
JDiff
Changelog
- Replaced our custom
@ElementTypesAreNonnullByDefault
annotations with the JSpecify@NullMarked
annotation. (8ebb375)