2880 Commits
Author SHA1 Message Date
cpovirk 89eb04b66e Bump Error Prone, and remove ReferenceEquality suppressions for Thread comparisons.
The suppressions are no longer necessary as of cl/937358981, which is [part of Error Prone 2.51.0](https://github.com/google/error-prone/commit/1259c50f8f164fb021dbdde08651602964ae6fd8).

RELNOTES=n/a
PiperOrigin-RevId: 1008358244
2026-10-27 14:02:13 -07:00
cpovirk c5e32cfaa9 Remove protected from test helpers, which are necessarily used only within the package.
Then, where appropriate, make them `private`, or even inline them.

(I guess that I've set aside my "Why even write '`private`' in a test class at all?" perspective, at least for the moment :))

RELNOTES=n/a
PiperOrigin-RevId: 1008110306
2026-10-27 08:09:24 -07:00
cpovirk 0229d325e6 Use MIN_POSITIVE_VALUE.
RELNOTES=n/a
PiperOrigin-RevId: 1008090972
2026-10-27 07:39:47 -07:00
cpovirk 9d36284ff4 Use @GuardedBy more.
(prompted by cl/1002439657)

RELNOTES=n/a
PiperOrigin-RevId: 1008086513
2026-10-27 07:32:38 -07:00
cpovirk 0b93bfbf68 Introduce and use a package-private SimpleForwardingCollection.
(prompted by a review comment in https://github.com/google/guava/commit/37535d73f0416f30e0301efe61a8eb8ede44c1b7)

We should easily make this available publicly, but we've had reservations around our `Forwarding*` classes in general (b/5231423), so I'm reluctant to expose more there without further thought.

RELNOTES=n/a
PiperOrigin-RevId: 1008047203
2026-10-27 06:17:03 -07:00
Tanishq Choudhary 37535d73f0 Check the predicate on setValue calls from filtered Multimap entries.
Compare https://github.com/google/guava/commit/b157643c41f9ee6a38732b4fa1a590ba187912d9.

Fixes https://github.com/google/guava/pull/8781
Fixes https://github.com/google/guava/pull/8785

RELNOTES=n/a
PiperOrigin-RevId: 1007326886
2026-10-26 09:14:36 -07:00
huang 5ae56d77e6 Make rotate a no-op on an empty range.
`rotate(array, distance, fromIndex, toIndex)` computed `length` and `-distance % length` without guarding an empty range, so a call with `fromIndex == toIndex` threw `ArithmeticException`. Return early when the range has fewer than two elements.

Fixes https://github.com/google/guava/pull/8772
Fixes https://github.com/google/guava/pull/8774

RELNOTES=`primitives`: Fixed `ArithmeticException` when calling `rotate` on an empty subrange of a multi-element array.
PiperOrigin-RevId: 1006325060
2026-10-24 09:23:31 -07:00
cpovirk 1b1d120f9c Improve testing of ForwardingMultiset.StandardElementSet:
- More clearly document that `StandardElementSet` is the class that we're testing _and_ where the list of legal methods is documented.
- Make methods throw by default (by virtue of calling `delegate()`), tightening the restrictions on which methods can be called.

(further evidence for https://github.com/google/guava/issues/1575)

RELNOTES=n/a
PiperOrigin-RevId: 1005714075
2026-10-23 10:51:29 -07:00
cpovirk d6e1fd3840 Document more JDK alternatives to Guava methods.
RELNOTES=n/a
PiperOrigin-RevId: 1005640167
2026-10-23 09:03:20 -07:00
cpovirk 7caa334327 Make some methods static.
...by using http://errorprone.info/bugpattern/MethodCanBeStatic.

RELNOTES=n/a
PiperOrigin-RevId: 1005209034
2026-10-22 18:34:06 -07:00
cpovirk d194bb3b0a Improve skipFully docs:
- Recommend `InputStream.skipNBytes` where available.
- Document behavior for negative requested skip values. The behavior matches that of [`InputStream.skipNBytes`](https://docs.oracle.com/en/java/javase/27/docs/api/java.base/java/io/InputStream.html#skipNBytes(long)) in practice, even though the contract of `skipNBytes` leaves open the possibility of different behavior in subclasses.

(relevant to https://github.com/google/guava/pull/8760, where it was suggested by arshsmith1)

RELNOTES=n/a
PiperOrigin-RevId: 1004997792
2026-10-22 13:10:57 -07:00
cpovirk ad73fbb9be Fix behavior of replaceAll in AbstractBiMap and HashBiMap when the given function throws.
Currently:

- `AbstractBiMap` runs `replaceAll` on its forward map first, so if that throws in the middle, its inverse is never updated. (Additionally, if it detects a value conflict while populating the inverse later, it likewise ends up in an inconsistent state.)

- `HashBiMap` clears itself at the beginning, so if it throws in the middle, it ends up missing entries.

Fixes https://github.com/google/guava/pull/8766 (by arshsmith), which proposed a fix for the specific case of `filterValues`.

RELNOTES=n/a
PiperOrigin-RevId: 1004886559
2026-10-22 10:42:01 -07:00
Chaoren Lin 2a18700ca0 Document that MediaType parameter values disallow ASCII control characters other than \t.
[Commit 5e82f2f](https://github.com/google/guava/commit/5e82f2f528fbbd970e00748025b48e3eb42ed702) restricted parameter values to printable ASCII and `\t` (matching [RFC 9110 Section 5.6.4](https://datatracker.ietf.org/doc/html/rfc9110#section-5.6.4)), whereas the class Javadoc still stated without qualification that all values follow RFCs 2045 and 2046.

RELNOTES=n/a
PiperOrigin-RevId: 1004800398
2026-10-22 08:38:15 -07:00
cpovirk b157643c41 Check the predicate on new values in filtered BiMap.replaceAll.
This change is prompted by https://github.com/google/guava/pull/8766 by arshsmith1. It is not a fix for _all_ the problems in this area, just incremental progress.

(The tests here touch on [the lack of a `ForwardingBiMap`](https://github.com/google/guava/issues/3906). But given the recent [additional evidence](https://github.com/google/guava/pull/8758) of [the dangers of forwarding collections](https://github.com/google/guava/issues/1575), I'm not in any rush to add one.)

RELNOTES=n/a
PiperOrigin-RevId: 1004410771
2026-10-21 19:24:01 -07:00
Lubaba Khalid 7b64964048 Treat leading, trailing, and consecutive $ in a class name as part of a top-level class name.
`ClassInfo.isTopLevel()` (and so `ClassPath.getTopLevelClasses()`) assumed that any `$` in a class name marks a nested class, so generated top-level classes like `$AutoValue_Foo` were silently dropped. `getSimpleName()` had the same problem, returning `AutoValue_Foo`.

_Consecutive_ `$` characters generally appear in runtime-generated classes, in which case they are outside the domain of `ClassPath`. However, they can appear at compile time, too, such as in desugared Android code—though, in the specific example of Android, `ClassPath` may well not work anyway. In any case, such classes don't represent true nested classes.

This new logic is all still based on heuristics, but it handles the common cases of generated class names.

Fixes https://github.com/google/guava/pull/8740
Fixes https://github.com/google/guava/issues/3349 well enough in practice.

RELNOTES=n/a
PiperOrigin-RevId: 1004273644
2026-10-21 15:22:57 -07:00
Colin Decker e641f0717a Change the streams returned by BaseEncoding's encodingStream and
`decodingStream` methods to synchronize their methods as typical of
`InputStream` and `OutputStream` implementations.

RELNOTES=n/a
PiperOrigin-RevId: 1004050756
2026-10-21 10:36:29 -07:00
Kurt Alfred Kluever adf5554e7e Add Doubles.MIN_POSITIVE_VALUE and Floats.MIN_POSITIVE_VALUE, aliases of the MIN_VALUE constants for those types.
`Double.MIN_VALUE` and `Float.MIN_VALUE` represent the smallest positive nonzero values (`2^-1074` and `2^-149`) rather than the most negative finite values, unlike `Integer.MIN_VALUE` and `Long.MIN_VALUE`.

RELNOTES=`primitives`: Added `Doubles.MIN_POSITIVE_VALUE` and `Floats.MIN_POSITIVE_VALUE` as more clearly named aliases for `Double.MIN_VALUE` and `Float.MIN_VALUE`.
PiperOrigin-RevId: 1004024484
2026-10-21 10:04:34 -07:00
Divyansh fa64cc7c2b Make BaseEncoding.encodingStream().close() idempotent.
Fixes https://github.com/google/guava/issues/5284
Fixes https://github.com/google/guava/pull/8642

RELNOTES=n/a
PiperOrigin-RevId: 1003397953
2026-10-20 14:31:51 -07:00
cpovirk fb2cb389a4 Make TODOs more stylish.
RELNOTES=n/a
PiperOrigin-RevId: 1003327482
2026-10-20 12:58:13 -07:00
cpovirk e07dfd2d8a Address a http://errorprone.info/bugpattern/Finally warning.
RELNOTES=n/a
PiperOrigin-RevId: 1003277753
2026-10-20 11:54:42 -07:00
arshiya tabasum de57a419b5 Check the predicate on setEntry calls from filterEntries(...).entrySet().toArray(...).
`FilteredEntryMap.EntrySet` wrapped only the entries returned by `iterator()`, so the entries returned by `toArray()` were the backing map's own entries, and their `setValue` bypassed the filter.

The fix is to override `toArray`. But instead of using `standardToArray` like `AbstractBiMap.EntrySet` and `UnmodifiableEntries` do, we use `newArrayList(iterator()).toArray(...)` like  `FilteredMapValues` and `FilteredEntryMap.KeySet` do so that we avoid evaluating the predicate against all elements twice (once in `size()` and once in `iterator()`).

- Fixes https://github.com/google/guava/pull/8758
- Support for https://github.com/google/guava/issues/1575

RELNOTES=n/a
PiperOrigin-RevId: 1003049749
2026-10-20 06:13:31 -07:00
Éamonn McManus 669a232b4e In ThreadFactoryBuilder, propagate null from newThread on the backing ThreadFactory.
`ThreadFactory.newThread` is permitted to return `null` to reject a request to create a thread. Previously, a factory built by `ThreadFactoryBuilder` threw `NullPointerException` if its backing factory returned `null`.

Fixes https://github.com/google/guava/issues/3568.
Closes https://github.com/google/guava/pull/8742.

RELNOTES=In the `ThreadFactory` returned by `ThreadFactoryBuilder`, a null return from `newThread` on the backing `ThreadFactory` is now propagated to the caller. Previously it triggered a NullPointerException.
PiperOrigin-RevId: 1001877586
2026-10-18 10:40:59 -07:00
cpovirk 665d66e83c Prepare for when our nullness checker knows that getFileAttributeView can return null.
RELNOTES=n/a
PiperOrigin-RevId: 1001870050
2026-10-18 10:09:50 -07:00
cpovirk 9247d70e16 Make FileBackedOutputStream even more resilient to broken temp-directory permissions than java.nio.file.Files.createTempFile is.
_If_ `java.io.tmpdir` is world-writable and does not set the very important sticky bit, then an attacker has a chance to unlink the temp file and replace it with a symlink between when it is created and when it is opened. This could cause the user of the stream to write/read data to/from an unintended location.

It's not clear that it's worth defending against this, given that the problem arises only with broken temp-directory permissions, which are much more likely to open holes elsewhere than here. But given the rise of security scanning over time, I'm figuring that it's worth addressing even _some_ borderline reports (like this one from our internal scans) when it appears straightfoward and safe enough to do so.

RELNOTES=n/a
PiperOrigin-RevId: 1001464603
2026-10-17 07:22:15 -07:00
arshiya tabasum 5e82f2f528 Reject control characters in MediaType parameter values.
Fixes https://github.com/google/guava/pull/8743

RELNOTES=n/a
PiperOrigin-RevId: 1000906952
2026-10-16 09:31:15 -07:00
Lubaba Khalid dea4984457 Document that SimpleStatsCounter.snapshot() may be
inconsistent with concurrent updates.

`SimpleStatsCounter` is documented as thread-safe, but it updates its counters independently
and without locking, so a snapshot taken during an update can include part of it (for example,
a load-success count without the corresponding load time). That's intentional for performance,
so document it rather than adding synchronization.

Fixes https://github.com/google/guava/pull/8741

RELNOTES=n/a
PiperOrigin-RevId: 999541957
2026-10-14 12:33:21 -07:00
cpovirk 2b86a82166 Keep the referent alive until after we've finished creating and registering the reference.
This prevents (for the case of `GcFinalization`, but other cases are similar):
- a `NullPointerException` if our finalization logic runs before `FinalizableReference` has assigned to `this.latch`
- indefinite retention of the `Reference` object if our finalization logic runs before `reference.add`

Fixes https://github.com/google/guava/issues/8738

RELNOTES=n/a
PiperOrigin-RevId: 998855369
2026-10-13 13:32:37 -07:00
arshiya tabasum 6b3a8d7498 Fix integer overflow in InetAddresses scope-ID parsing.
Fixes https://github.com/google/guava/pull/8735

RELNOTES=n/a
PiperOrigin-RevId: 996752850
2026-10-09 14:19:13 -07:00
cpovirk 1485e0093c Further tweak Javadoc output:
- While it makes sense to have an HTML `<title>` (i.e., what shows up in the tab button or taskbar button for that page) that says (e.g.) "Truth API," it's weirder for the in-page title to say "Truth API" instead of just "Truth." Javadoc lets us set the two independently; I just chose poorly in https://github.com/google/guava/commit/49300093df01df7d7bea5f1d657ecf58fbc4f596.
- Truth was showing a copyright date of 1980, presumably some kind of default from somewhere or other. I've given it [the same value as Guava](https://github.com/google/guava/blob/1da08c4d381abf3613ad956d3aec9fa77dfc94b2/pom.xml#L100).

It's possible that [JSpecify](https://github.com/jspecify/jspecify/issues/904) would have the same issue, though I'm not sure because it uses Gradle instead of Maven. But even if it does, I'm not sure that its Javadoc ends up with a summary page at the moment, I guess because it contains only one package? So maybe there's nowhere for "JSpecify API" to appear in the actual page text, only in the `<title>` where we want it.

RELNOTES=n/a
PiperOrigin-RevId: 996717116
2026-10-09 13:20:57 -07:00
TABISH AYUB RAZA 1da08c4d38 More frequently validate elements during TreeMultiset.setCount(element, oldCount, newCount).
But (for better or for worse) preserve the existing lenient behavior of `setCount(element, 0, 0)`.

Fixes https://github.com/google/guava/pull/8720

RELNOTES=n/a
PiperOrigin-RevId: 995897499
2026-10-08 09:48:57 -07:00
cpovirk 49300093df Hide our long "HEAD-SNAPSHOT" version numbers from the generated Javadoc.
Compare https://github.com/jspecify/jspecify/issues/904.

RELNOTES=n/a
PiperOrigin-RevId: 995344595
2026-10-07 14:11:46 -07:00
cpovirk 7573b12d80 Bump deps and plugins.
But don't update maven-surefire-plugin to 3.6.0: It appears to produce either module-system errors (under JDK 11) or infinite(?) loops over tests (under JDK 26).

- Fixes https://github.com/google/guava/pull/8726
- Fixes https://github.com/google/guava/pull/8725
- Fixes https://github.com/google/guava/pull/8724
- Fixes https://github.com/google/guava/pull/8723

RELNOTES=n/a
PiperOrigin-RevId: 995300021
2026-10-07 13:07:06 -07:00
cpovirk a24e79ef3e Fix more GWT/J2CL nullness annotations, and fix a GWT/J2CL nullness bug in cache.
RELNOTES=n/a
PiperOrigin-RevId: 995298922
2026-10-07 13:03:35 -07:00
cpovirk 3dab0e8773 Bump toolchain, Javadoc-generated links, and handwritten links to Java 27.
I rechecked links that looked worth rechecking.

RELNOTES=n/a
PiperOrigin-RevId: 994789692
2026-10-06 19:51:23 -07:00
Mahammad Insaf 786bb1a9b4 Ignore negative skip counts in ByteStreams.limit streams.
`LimitedInputStream.skip` passed a negative count on to the delegate. `FileInputStream` then seeks backward and returns a negative value, which was subtracted from the bytes left, so the stream could move before the position where the limit began and supply more than the limit.

Fixes https://github.com/google/guava/pull/8712

RELNOTES=n/a
PiperOrigin-RevId: 994451753
2026-10-06 09:48:06 -07:00
cpovirk 81c7d030f8 Cap deserialized LocalCache+MapMakerInternalMap concurrency level at 1024.
1024 ought to be enough for anybody. And probably few people are serializing caches or weak-entry-based maps, anyway. And people should be using [Caffeine](https://github.com/ben-manes/caffeine).

There was already a cap of 64k, so these collections didn't permit arbitrary-sized allocations. Still, the reduction brings them more in line with what is already possible when deserializing built-in JDK types. See, for example, [`LogRecord`](https://github.com/openjdk/jdk/blob/4e8bec6f862b58732537dea15cb3dd50a01fede0/src/java.logging/share/classes/java/util/logging/LogRecord.java#L704) and [`ZoneRules`](https://github.com/openjdk/jdk/blob/4e8bec6f862b58732537dea15cb3dd50a01fede0/src/java.base/share/classes/java/time/zone/ZoneRules.java#L464) (though the constant factors are still different).

(If any user of the classes is directly passing a concurrency level of more than 1024, it's extremely likely that that user would be better off if we were to cap it to 1024 in that code path, too. But I'm not bothering in this CL.)

RELNOTES=n/a
PiperOrigin-RevId: 993749847
2026-10-05 09:58:26 -07:00
Kurt Alfred Kluever 51246d06bb Terminate bracketed hosts at the first closing bracket in HostAndPort.
RELNOTES=`net`: `HostAndPort.fromString` now rejects bracketed hosts that contain multiple closing brackets.
PiperOrigin-RevId: 993633306
2026-10-05 05:58:04 -07:00
cpovirk 74fb73b20e Hard-code the current JRE serialVersionUID values for classes whose serialization we test.
(This may mean a change for _Android_ values.)

We continue to [warn that not just `serialVersionUID` values but actual serialized forms can change over time](https://github.com/google/guava/blob/master/README.md#important-warnings). But it doesn't seem that occasional changes here are deterring users from persisting serialized forms _enough_ that those changes are net helpful to us: It's probably simplest to hard-code values to avoid issues like https://github.com/google/guava/issues/8693, and if we want to make a "real" change to the serialized form badly enough, then we still will.

Plus, we should probably specify `serialVersionUID` broadly to avoid any future problems computing it under Android or other environments that might not contain all the types used in [the class's relevant components](https://docs.oracle.com/en/java/javase/27/docs/specs/serialization/class.html#stream-unique-identifiers). (Compare https://github.com/google/guava/commit/230b0cdc69b03d5588cb72a38a10f51f64e2e223 and the similar changes that followed, as well as https://github.com/google/guava/commit/4d41665af1b05bad09039b82cb2a1a474a7bceaf.)

RELNOTES=n/a
PiperOrigin-RevId: 992670226
2026-10-02 19:59:00 -07:00
cpovirk 72dd370d95 Apply https://errorprone.info/bugpattern/AssertThrowsBlockToExpression suggestions.
RELNOTES=n/a
PiperOrigin-RevId: 992420855
2026-10-02 10:59:30 -07:00
Kurt Alfred Kluever d860752657 Fix integer overflow in BaseEncoding.decodingStream for >2B characters
RELNOTES=n/a
PiperOrigin-RevId: 990549481
2026-09-29 14:59:05 -07:00
cpovirk b931fe9d6d Avoid eagerly allocating as much memory as a serialization payload requests.
See [the security advisory that this addresses](https://github.com/google/guava/security/advisories/GHSA-xxph-c9ww-hj94) (soon to be published as [CVE-2026-102554](https://nvd.nist.gov/vuln/detail/cve-2026-102554)). We will publish a release 33.7.2 with the fix.

RELNOTES=`collect`: Changed `MapMaker`, `CompactHashMap`, and `CompactHashSet` deserialization to [avoid eagerly allocating as much memory as a serialization payload requests](https://github.com/google/guava/security/advisories/GHSA-xxph-c9ww-hj94).
PiperOrigin-RevId: 990274733
2026-09-29 06:50:03 -07:00
cpovirk b0ab782522 Rewrite a few instances of if (!foo) { ... } else { ... }.
Yes, one of these is changing the "old implementation" in a benchmark. That could in theory affect performance, but it seems extremely unlikely to. And if somehow it does, it seems only fair to compare against this improved implementation, anyway. (My change makes that code look at lot like the code in `NewExecutionListWithoutReverse` and in the prod `ExecutionList` itself.)

RELNOTES=n/a
PiperOrigin-RevId: 989830275
2026-09-28 14:04:26 -07:00
cpovirk 4ecac71e56 Suppress http://errorprone.info/bugpattern/TruthConstantAsserts warnings.
RELNOTES=n/a
PiperOrigin-RevId: 989713023
2026-09-28 10:40:48 -07:00
cpovirk 67b6ad17db Use a custom Map implementation instead of IdentityHashMap.
Because:

- While it continues to be true that `IdentityHashMap` has an `Entry` implementation that (among [other things](https://bugs.openjdk.org/browse/JDK-8352596)) throws an exception if accessed after removal, this is an implementation detail, one that could easily change in a way that would leave this test silently testing nothing.
- We already saw and suppressed an [IdentityHashMapBoxing](http://errorprone.info/bugpattern/IdentityHashMapBoxing) warning, and we're now seeing a [ValueClassIdentity](https://errorprone.info/bugpattern/ValueClassIdentity) warning.

That latter problem is solvable by using a type other than `Integer`, but the former problem could at best be solved by adding a check up front that `IdentityHashMap` behaves as we expect. Put that all together along with how exceedingly efficient we've become at implementing `Map`, and I think we should just implement `Map`.

(This test is originally from cl/13218883, which cited https://github.com/google/guava/issues/258.)

RELNOTES=n/a
PiperOrigin-RevId: 989706189
2026-09-28 10:27:47 -07:00
Cindy Krafft a279b884fe Make filtered NavigableMap views return snapshot entries from pollFirstEntry(), etc. (and similarly for ForwardingNavigableMap.standard*Entry).
And update `NavigableMapTestSuiteBuilder` to require immutable entries from those methods.

For simplicity, I'll focus on the `NavigableMap` case in the description below:

`Maps.filterKeys`, `filterValues` and `filterEntries` on a `NavigableMap` returned the backing map's live entries from their navigation methods. This caused two problems:

### Removing an `Entry` from the backing map might mutate the `Entry`

`pollFirstEntry()` and `pollLastEntry()` removed the entry through the backing `entrySet` iterator and then returned that same entry object.

When `TreeMap` removes a node with two children, it copies the successor's key and value into that node, so the returned entry could show a different mapping.

For example:

- `Maps.filterKeys(TreeMap{1=one, 2=two, 3=three}, k -> k != 1) .pollFirstEntry()` returned `3=three` instead of `2=two`.
- Draining `filterKeys(TreeMap{0..9}, odd)` with `pollFirstEntry()` returned keys [2, 4, 6, 7, 9] instead of [1, 3, 5, 7, 9].

### Navigation methods are supposed to return snapshots

`firstEntry()`, `lastEntry()`, `ceilingEntry()`, `floorEntry()`, `higherEntry()` and `lowerEntry()` returned live entries whose `setValue` wrote through to the backing map. This is bad for two reasons:

- [`NavigableMap`](https://docs.oracle.com/en/java/javase/27/docs/api/java.base/java/util/NavigableMap.html) specifies that these methods return snapshot entries that don't support `setValue`.
- Even if they were to support `setValue`, maps that are filtered by value (or by the full entry contents) should check that the predicate allows the new value.

---

Now, all these methods return snapshots.

But we continue to override `entrySet()` in a way that allows its entries to support `setValue` (with the predicate check).

Finally, I've moved `Iterables.removeFirstMatching` from `Iterables` to `Sets`. That is now the only location that it's used from, since it is no longer used from `Maps`. Along the way, I renamed it to "`pollFirstMatching`" to more closely match the methods that it's used from.

Fixes https://github.com/google/guava/pull/8692

I filed b/566253750 for a similar question in `SortedMultiset`.

RELNOTES=n/a
PiperOrigin-RevId: 988966779
2026-09-26 16:44:25 -07:00
cpovirk 4d41665af1 Hard-code a serialVersionUID for ImmutableClassToInstanceMap.
The "actual serialized form" of `ImmutableClassToInstanceMap` has not changed recently (if ever), but the automatically computed value did (probably from https://github.com/google/guava/commit/8a65185824065b7cbb12fdf0488f09b1f1b5e8f8 or maybe even https://github.com/google/guava/commit/8b3bbf42c5541eb4af4a1f8fcfea026cace6133e).

Specifically, this CL hard-codes the value seen for at least Guava 20.0 and Guava 33.6.0, rather than the value seen in Guava 33.7.0 and 33.7.1.

```
$ serialver -classpath ~/.m2/repository/com/google/guava/guava/33.6.0-jre/guava-33.6.0-jre.jar com.google.common.collect.ImmutableClassToInstanceMap
com.google.common.collect.ImmutableClassToInstanceMap:    private static final long serialVersionUID = 7501988272684437179L;

$ serialver -classpath ~/.m2/repository/com/google/guava/guava/33.7.0-jre/guava-33.7.0-jre.jar com.google.common.collect.ImmutableClassToInstanceMap
com.google.common.collect.ImmutableClassToInstanceMap:    private static final long serialVersionUID = 4144108963035698377L;
```

The value has changed before. (I dug up a value of 848000262024182363L in Guava 16.0.1.) We continue to [warn that not just `serialVersionUID` values but actual serialized forms can change over time](https://github.com/google/guava/blob/master/README.md#important-warnings). We're making the change here anyway, partially because it's a cheap additional way to help people who have hit problems with Error Prone's Refaster and partially because we should probably specify `serialVersionUID` more broadly to avoid any future problems computing it under Android or other environments that might not contain all the types used in [the class's relevant components](https://docs.oracle.com/en/java/javase/27/docs/specs/serialization/class.html#stream-unique-identifiers). (Compare https://github.com/google/guava/commit/230b0cdc69b03d5588cb72a38a10f51f64e2e223 and the similar changes that followed.)

- Fixes https://github.com/google/guava/issues/8693
- Relevant to https://github.com/PicnicSupermarket/error-prone-support/pull/2315
- Relevant to https://github.com/google/error-prone/issues/1318
- Partial substitute for https://github.com/google/error-prone/pull/6142

RELNOTES=n/a
PiperOrigin-RevId: 987779962
2026-09-24 14:58:02 -07:00
Cindy Krafft 17f7000f49 Document that transform and transformAsync propagate exceptions thrown by the function.
- Fixes https://github.com/google/guava/pull/8696
- Fixes https://github.com/google/guava/issues/2690

RELNOTES=n/a
PiperOrigin-RevId: 987683523
2026-09-24 12:36:12 -07:00
ionik0 88583e2ecb Advertise ClosingFuture from ListenableFuture, Futures, and FluentFuture.
Each of the three already has a passage about chaining operations and the alternatives for doing so; this adds a short pointer to `ClosingFuture` in each.

Fixes https://github.com/google/guava/issues/4022
Fixes https://github.com/google/guava/pull/8688

RELNOTES=n/a
PiperOrigin-RevId: 987556423
2026-09-24 09:27:10 -07:00
Cindy Krafft 39979d08bc Document that FluentIterable.toSortedList is stable.
`toSortedList` delegates to `Ordering.immutableSortedCopy`, which in turn
delegates to `ImmutableList.sortedCopyOf`. Both of those document that the
sort is stable, but `toSortedList` did not say so. Add the same sentence
that `ImmutableList.sortedCopyOf` uses.

Fixes #2884

Claude-Session: https://claude.ai/code/session_01X59fWmqnA4Nmb9rggkTP7n

Fixes https://github.com/google/guava/pull/8691

RELNOTES=n/a
PiperOrigin-RevId: 987463733
2026-09-24 06:33:34 -07:00
cpovirk 73acb67fe9 Update code to prepare for when our nullness checker recognizes that [Currency.getInstance can return null](https://github.com/jspecify/jdk/pull/163).
RELNOTES=n/a
PiperOrigin-RevId: 986853278
2026-09-23 10:35:36 -07:00