7580 Commits
Author SHA1 Message Date
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
Wangshu Pang 79152348ec Make Lists.transform() views delegate spliterator()/forEach() to the backing list.
`TransformingRandomAccessList` and `TransformingSequentialList` previously inherited default implementations from `AbstractList`/`AbstractSequentialList`, which lost the backing list's spliterator characteristics (e.g., `IMMUTABLE`), sized/subsized properties, and custom `forEach()` optimizations.

Includes a suggestion from @kojallipalli2210-alt on #8589.

Fixes https://github.com/google/guava/issues/8165.
Closes https://github.com/google/guava/pull/8589.

RELNOTES=`collections`: In `Lists.transform`, delegate `spliterator()` and `forEach()` to the backing list.
PiperOrigin-RevId: 986925834
2026-09-23 12:26:11 -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
cpovirk 1278ad9c22 Make more classes and methods final.
Plus, remove a `ListenableFutureTask` comment, which I should have removed in https://github.com/google/guava/commit/bc982e8596e29814c2390a88f8e0faa9930a4fca and which appears to have been stale since cl/82743827(!).

RELNOTES=n/a
PiperOrigin-RevId: 986765725
2026-09-23 08:19:42 -07:00
cpovirk 16fda80173 Update Public Suffix List data.
RELNOTES=n/a
PiperOrigin-RevId: 985945693
2026-09-22 06:07:05 -07:00
Google Java Core Libraries 2a11c2a311 Internal change.
RELNOTES=n/a
PiperOrigin-RevId: 985396382
2026-09-21 11:19:17 -07:00
cpovirk 77b2cf6b92 Format some Markdown.
RELNOTES=n/a
PiperOrigin-RevId: 984055579
2026-09-18 14:05:11 -07:00
cpovirk 794fa736c9 Optimize @AndroidIncompatible annotations.
Largely, this is about enabling tests that were unlocked by our upgrade to the emulator we test under now that we are on a minSdkVersion of 24. That upgrade both fixed bugs and improved performance of some excessively slow methods.

But I also took this opportunity to be more systematic about which tests we consider "too slow" to run under Android. I believe that what I did was (keeping in mind that test runtime can vary from run to run):
- If a test takes ~30s+, add/keep `@AndroidIncompatible`. Otherwise, consider it "fast enough."
- If a test takes ~15s+, add/keep/update a comment about its approximate runtime.
- But make an unprincipled exception for `Utf8Test.testIsWellFormed_3Bytes`, which takes ~70s but felt some combination of "important" and "possible to imagine behavior differences from rogue optimizations." (Maybe vaguely compare b/262383185??)

RELNOTES=n/a
PiperOrigin-RevId: 984013883
2026-09-18 12:49:35 -07:00
cpovirk d7433962fd Enable parameterized graph tests under Android.
This is possible after the TestParameterInjector migration of https://github.com/google/guava/commit/0bfee017f6146c3e09b14c08e1634d51b5a6c791. (And it becomes practical with the increased shard count that I'm putting into place in this CL.)

RELNOTES=n/a
PiperOrigin-RevId: 984012271
2026-09-18 12:46:28 -07:00
cpovirk ce2511debd Enable more cache tests under Android.
Most of these changes were probably unlocked by our upgrade to the emulator we test under now that we are on a minSdkVersion of 24.

The complicated change is to get our `WeakReference`-related test working. Part of the fix there is to create the `WeakReference` in a separate method, similar to https://github.com/google/guava/commit/c02d13681b930d3e1585092dfff757f2d39d9dd0. Then we use `GcFinalization`, as usual for this kind of thing.

It's possible that I should be more concerned by my old "Bug?" comments in `CacheLoadingTest`. Maybe they were some kind of Android bug that got fixed, or maybe they reflect a real issue in `cache` that might still exist.

RELNOTES=n/a
PiperOrigin-RevId: 984005922
2026-09-18 12:34:17 -07:00
Éamonn McManus 77920a18b8 Remove unused static imports of DIRECTED and UNDIRECTED.
RELNOTES=n/a
PiperOrigin-RevId: 983989938
2026-09-18 12:04:56 -07:00
cpovirk 48a4d3c111 Remove some accidental @Serial annotations from https://github.com/google/guava/commit/412c1bfc86f73c0719c910d90718dbdb1659d326.
I had done some regex search and replace to insert `@Serial`, including to do so at the site of `@GwtIncompatible // serialization`. That makes sense for lots of prod members (though not all, and thankfully I seem to have avoided at least some possible mistakes, like in `ImmutableMapKeySet`), but it appears to have made sense approximately never for test members.

RELNOTES=n/a
PiperOrigin-RevId: 983985663
2026-09-18 11:57:36 -07:00
cpovirk 5a7407d8f0 Internal change.
PiperOrigin-RevId: 983280808
2026-09-17 10:31:55 -07:00
cpovirk 11ef04e810 Steer users of Converter.convertAll toward Stream.
We already do this for very similar methods like `Iterables.transform`.

RELNOTES=n/a
PiperOrigin-RevId: 982030950
2026-09-15 14:12:21 -07:00
cpovirk b30262d1bc Address findings of "redundant" 0xff masking before (byte) casts.
My understanding is that [the masking is still necessary under GWT](https://www.gwtproject.org/doc/latest/DevGuideCodingBasicsCompatibility). (J2CL, by contrast, probably gets it right, or at least our tests don't show otherwise.) We [no longer have an easy way to test under GWT](https://github.com/google/guava/releases/tag/v33.5.0), so I'm erring on the side of caution.

RELNOTES=n/a
PiperOrigin-RevId: 979527347
2026-09-10 19:19:40 -07:00
Patrick Strawderman 5f97cde6cf Short-circuit equals for same instance comparison.
This is similar to https://github.com/google/guava/pull/8427 but for yet more classes.

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

RELNOTES=n/a
PiperOrigin-RevId: 979362291
2026-09-10 13:29:34 -07:00
cpovirk 0bfee017f6 Migrate graph tests from Parameterized to TestParameterInjector.
This is good in general, but what finally got me to do it was that `Parameterized` was generating test names that were too long for our Android infrastructure. (I haven't yet checked whether the TestParameterInjector names are short enough.)

RELNOTES=n/a
PiperOrigin-RevId: 978699274
2026-09-09 12:48:46 -07:00
cpovirk 3cffad12e0 Suppress more https://errorprone.info/bugpattern/DistinctVarargsChecker warnings.
(like https://github.com/google/guava/commit/2daf2db9cb3e909fecd2dbedc4caf90eb25e1df1 but for files that are built directly by `java_test` targets, rather than as part of a `java_library`)

RELNOTES=n/a
PiperOrigin-RevId: 978610515
2026-09-09 10:08:46 -07:00
cuishuang 4afb1e04a4 Avoid recursion when MultiReader advances past empty readers.
This parallels the fix to https://github.com/google/guava/issues/2996 back in 2017.

Closes https://github.com/google/guava/pull/8662.
Fixes https://github.com/google/guava/pull/8661.

RELNOTES=`io`: Removed a use of recursion that could potentially lead to a stack overflow during reading, if `CharSource.concat` is used to concatenate many empty sources.
PiperOrigin-RevId: 978109335
2026-09-08 14:13:15 -07:00
cpovirk 12b08072ae Under JEP 401, don't run tests that expect failures from new Primitive(x) == new Primitive(x).
PiperOrigin-RevId: 977954170
2026-09-08 09:30:03 -07:00
cpovirk e5c81f97e2 Make Futures.withTimeout reject nulls even when the input Future is already done.
The current behavior is fragile to races and (more realistically?) to tests that use completed `Future` instances when the prod code might see in-progress ones.

RELNOTES=n/a
PiperOrigin-RevId: 977869166
2026-09-08 06:10:31 -07:00
cpovirk 5fb424c43a Make it possible to run ./mvnw package instead of ./mvnw install.
This [just came up again](https://github.com/google/guava/issues/8650#issuecomment-5510207112). It is a better solution to https://github.com/google/guava/issues/2193 than https://github.com/google/guava/pull/8127 was.

(I think it makes sense for `gradle_integration_tests.sh` to continue using `install` so that the Maven-produced artifacts become visible to Gradle. But I haven't tested.)

Sadly, it's still not enough for `mvn compile` to work:

```
[ERROR] Failed to execute goal on project guava-gwt: Could not resolve dependencies for project com.google.guava:guava-gwt:jar:999.0.0-HEAD-jre-SNAPSHOT
[ERROR] dependency: com.google.guava:guava-testlib:jar:tests:999.0.0-HEAD-jre-SNAPSHOT (test)
[ERROR]         Could not find artifact com.google.guava:guava-testlib:jar:tests:999.0.0-HEAD-jre-SNAPSHOT
[ERROR] dependency: com.google.guava:guava-tests:jar:tests:999.0.0-HEAD-jre-SNAPSHOT (test)
[ERROR]         Could not find artifact com.google.guava:guava-tests:jar:tests:999.0.0-HEAD-jre-SNAPSHOT
```

(For all testing of such changes, it's necessary to delete/move `~/.m2/repository/com/google/guava` so that Maven doesn't just read from previous builds that are installed there—thanks to our habit of using `mvn install` instead of `mvn package`!)

RELNOTES=n/a
PiperOrigin-RevId: 976459357
2026-09-04 13:10:36 -07:00
cpovirk 14c81e523a Address some IntelliJ inspections, mostly in cache.
RELNOTES=n/a
PiperOrigin-RevId: 975367151
2026-09-02 15:40:02 -07:00
cpovirk f744cde9f5 Replace calls to Runnables.doNothing() with a do-nothing lambda, () -> {}.
`Runnables.doNothing()` exists only because Java lambdas didn't exist in 2013. `() -> {}` is shorter and more standard.

RELNOTES=n/a
PiperOrigin-RevId: 975197633
2026-09-02 10:19:37 -07:00
cpovirk 936fd96f77 Remove some unused members.
RELNOTES=n/a
PiperOrigin-RevId: 975165950
2026-09-02 09:18:13 -07:00
cpovirk 25e291479a Replace calls to Runnables.doNothing() with a do-nothing lambda, () -> {}.
`Runnables.doNothing()` exists only because Java lambdas didn't exist in 2013. `() -> {}` is shorter and more standard.

PiperOrigin-RevId: 974801764
2026-09-01 17:42:21 -07:00
cpovirk 0678c0c7a3 Make the internal copy of the backport reject weak/soft references to most value classes, too, when running under the JVM.
This should catch problems that would arise in Robolectric tests (or other usage of the backport on the JVM, but we otherwise non-Robolectric JVM use of the backport in our depot).

Also, tweak the implementation to be more open-source-able (by avoiding the Java-8-incompatible expression `switch`), even though we're not open-sourcing it yet.

(followup to https://github.com/google/guava/commit/f516e7587dd92720f61a56a3a1c0998c62806788)

RELNOTES=n/a
PiperOrigin-RevId: 974678606
2026-09-01 13:38:26 -07:00
dependabot[bot] b274e74ff2 Bump the github-actions group with 3 updates
Bumps the github-actions group with 3 updates: [actions/setup-java](https://github.com/actions/setup-java), [gradle/actions/setup-gradle](https://github.com/gradle/actions) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).

Updates `actions/setup-java` from 5.6.0 to 6.0.0
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/03ad4de0992f5dab5e18fcb136590ce7c4a0ac95...dd06d9cba3e5552c54d9f8ea23572deb30010f7c)

Updates `gradle/actions/setup-gradle` from 6.2.0 to 6.3.0
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/3f131e8634966bd73d06cc69884922b02e6faf92...9c971963bec38e04b3d30dcc455b5382be2fdbfb)

Updates `github/codeql-action/upload-sarif` from 4.37.3 to 4.37.8
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28)

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

RELNOTES=n/a
PiperOrigin-RevId: 974544358
2026-09-01 09:40:33 -07:00
cpovirk bc982e8596 Make more classes and members final.
The candidates in this batch came courtesy of IntelliJ. (I then had to get Gemini to revert problems related to reflection on Guava internals, and I reverted changes to publicly visible APIs, including those now conveniently tagged with `@J2ktPublic`.)

Also:

- Change `LineBuffer` methods from `protected` to package-private.
- Change [`AbstractClassInitializationTest`](https://github.com/google/guava/issues/8617) `getPackageName` and `isIgnored` methods from `public` to `private`. (These aren't yet in a Guava release, so the change is safe, as is the change to make `testClassesInitialize` be `final`.)
  - I suspect that I could also have removed `throws Exception` from `testClassesInitialize` while I was there. But that shouldn't matter to anyone, since there should be no callers or overrides even after release, and keeping `throws Exception` is slightly more flexible for us.

RELNOTES=n/a
PiperOrigin-RevId: 974457816
2026-09-01 06:18:52 -07:00
cpovirk b3346e3895 Address https://errorprone.info/bugpattern/MissingSummary warnings.
...by restoring some Javadoc to the `guava-android` copy of `Equivalance`. Somehow I seem to have managed to remove it in https://github.com/google/guava/commit/d62f77b786579150003d0e786a3c6ba41afe4155.

I also changed "iff" to "if" in various places.

RELNOTES=n/a
PiperOrigin-RevId: 974101803
2026-08-31 15:13:21 -07:00
cpovirk 743176354e Bump Gradle to 9.7.1.
PiperOrigin-RevId: 974059912
2026-08-31 13:53:46 -07:00
cpovirk 32ba16fcdd Remove caching of cheap collection views across common.collect.
(like https://github.com/google/guava/commit/e87d019e47a29bf263a82fe81caede34e9728e15 and https://github.com/google/guava/commit/0a8e1ec55afe1d9361ebbd0c4149adfbb32ccf9a but for a wider variety of collections)

This includes removing `ViewCachingAbstractMap` entirely in favor of using `AbstractMap` directly.

For J2ObjC safety, I removed `@Weak` and `@WeakOuter` annotations now that there is no reference cycle between the outer collection and its view collections. (Really, we should have used `@RetainedWith` instead of `@Weak*`, anyway, so this CL improves fixes existing issues in addition to perhaps preventing new ones. For more on `@RetainedWith`, see cl/781580713.) Parts of the `@Weak*` changes should have been done as part of https://github.com/google/guava/commit/0a8e1ec55afe1d9361ebbd0c4149adfbb32ccf9a for `Compact*HashMap`.

_Not_ covered in this CL:

- various other cached views that might benefit, such as `RegularImmutableSet.asList` (cl/922882558)
- views that I worry at least a little more about, mainly "invertible operations" (`BiMap.inverse`, `NavigableSet.descendingSet`, etc.)
- maybe migrating off `AbstractMap` in some additional cases in which it would make sense to avoid inheriting its fields
- GWT/J2CL

RELNOTES=n/a
PiperOrigin-RevId: 973885682
2026-08-31 08:07:10 -07:00
cpovirk f516e7587d Internally disallow weak and soft references to _most_ value classes in MapMaker and CacheBuilder (in the JRE flavor but not the Android flavor, not even for Robolectric tests).
Update corresponding tests to avoid value classes.

RELNOTES=n/a
PiperOrigin-RevId: 973492685
2026-08-30 10:52:22 -07:00
cpovirk 7a23c72cd9 Internal change.
RELNOTES=n/a
PiperOrigin-RevId: 973462112
2026-08-30 08:21:48 -07:00
Google Java Core Libraries d5cc108ede Accommodate Kotlin's visibility rules.
PiperOrigin-RevId: 972735608
2026-08-28 12:41:15 -07:00
Google Java Core Libraries 7547675aeb Fix J2KT/Native compatibility issues in Guava collect tests.
- In SetViewTest, suppress ErrorProne's `VoidMissingNullable` in `SetContainsThrows` rather than changing the type argument to `@Nullable Void`. This allows Kotlin/Native to compile `AbstractSet<Void>` successfully without incorrectly implying that the set can contain null elements.
- In TableCollectionTest, extract the `suite()` method and its associated helper methods into a new `TableCollectionTestSuite` class, and remove `extends TestCase` from `TableCollectionTest`. This properly isolates the test infrastructure and prevents test runner issues where making the original class abstract caused test suites to be silently dropped on JVM and J2KT environments.

PiperOrigin-RevId: 972700907
2026-08-28 11:38:20 -07:00
cpovirk a3bde340e4 Recommend () -> {} over Runnables.doNothing().
It's shorter, and it is even more transparent about what it does (i.e., nothing).

`doNothing()` is admittedly a singleton (though we don't promise that), while the singleton-ness of `() -> {}` depends on details of your program and toolchain. I don't expect that to be much of an issue in practice. (If anything, the thing that people ought to consider is whether to ensure that [every new usages of a do-nothing `Runnable` is a fresh object](https://github.com/google/guava/blob/1f5d40726a38b11174e0e13da78ecb9f7630cc6e/guava/src/com/google/common/util/concurrent/InterruptibleTask.java#L42).)

RELNOTES=n/a
PiperOrigin-RevId: 972573845
2026-08-28 07:18:23 -07:00
cpovirk 1f5d40726a Address some IntelliJ inspections:
- redundantly `final` methods in `final` classes (as in https://github.com/google/guava/commit/1d5c444f9f2487b109451d5b1dc1365135ce34f1 and probably some prior CL)
- missing commas between independent clauses

RELNOTES=n/a
PiperOrigin-RevId: 971613237
2026-08-26 18:03:19 -07:00
Éamonn McManus 3353f79bb9 Internal change.
RELNOTES=n/a
PiperOrigin-RevId: 971512471
2026-08-26 14:46:54 -07:00
cpovirk 80fd5c114d Add a test that each class in a package is safe to initialize first, and apply it to Guava.
This new testing detected one problem, which I addressed in https://github.com/google/guava/commit/5195255413ee7eac23a012484c9d0236c1826363.

For further background, see https://github.com/google/guava/issues/8617.

I hope that the additional testing doesn't slow external CI significantly. I ran Guava's tests once with this change and once without, and I saw a 13s slowdown. But I don't know what the normal level of variation is. We could consider running the test internally only, but I figure it's safer to run everywhere for now.

(While making a copy of `ClassPathUtil`, address a deprecation warning there, and migrate to [the `AssertionError constructor that was added to Android in API Level 19](https://developer.android.com/reference/java/lang/AssertionError#AssertionError(java.lang.String,%20java.lang.Throwable)). We have done such similar migrations elsewhere, as in https://github.com/google/guava/commit/c497a975ba2845d553bb1c1ae76d7118320b32a5.))

RELNOTES=`testlib`: Added `AbstractClassInitializationTest`.
PiperOrigin-RevId: 971504745
2026-08-26 14:33:55 -07:00
cpovirk 5195255413 Make it safe to initialize RegularImmutableList before ImmutableList in guava-android (as has already been safe in guava-jre).
That initialization ordering has been impossible to trigger through public APIs since https://github.com/google/guava/issues/1977. However, we've since learned of cases in the wild in which libraries use reflection to access non-public APIs for the purpose of initializing them in basically arbitrary order:
- GraalVM does this if users request build-time initialization for a class directly or indirectly.
- At least two systems inside Google try to eagerly initialize classes during normal runtime.
- It's not hard to imagine a custom serialization framework that would do this. (Normal Java serialization, by contrast, is fine: `ImmutableList` instances are always serialized as `SerializedForm` instances, rather than as `RegularImmutableList` instances directly.) I wonder if GWT-RPC could have caused such trouble back in the day. (My quick read of our old serializer implementation suggests "no," but I didn't think about the GWT-RPC system as a whole.)

Plus, we've gotten reports of what I still suspect to be a bug in someone's Android toolchain, in which a nondescript use of `ImmutableSet.asList` appeared to be optimized to skip the `ImmutableList` initialization and instead access `RegularImmutableList` directly. (This is uncommon, so it may happen only with a combination of some toolchain and a case in which `RegularImmutableList` is specialized to handle _only_ the empty-collection case. Here's [an old example](https://issues.chromium.org/issues/40051933#comment6).) Since the first two cases above are most likely to be pulling in `guava-jre`, not `guava-android`, this is likely the biggest practical danger.

Beyond avoiding NPE, I believe that this CL even protects against [class-initialization deadlocks](https://github.com/google/guava/issues/1977) for a system that manages to try to initialize `RegularImmutableList` first in one thread and `ImmutableList` first in another—even though, again, the latter should be "impossible":
- A caller who initializes `ImmutableList` first is safe because `ImmutableList` initialization doesn't trigger `RegularImmutableList` initialization.
- A caller who somehow initializes `RegularImmutableList` first is safe because it either initializes `ImmutableList` itself or safely waits for the other thread, which can complete without dependency on `RegularImmutableList`, as discussed above.

That said, I would still worry about any system that manages to initialize `RegularImmutableList` first—not because of trouble with `RegularImmutableList` itself anymore but because these same kinds of trouble (both NPE-like problems and class-init deadlocks) could arise with other classes.

Anyway: Other than the tests that show that this change helps (cl/967775267), this CL is the only work that I have in mind for https://github.com/google/guava/issues/8617 at the moment.

(Also, undo my static importing of `RegularImmutableList.EMPTY` from cl/88131198. I remain the world's biggest fan of static imports, but I acknowledge that a class-init cycle is a case that's not necessarily best swept under the rug. Not that I'd expect for most readers to have that on their radars regardless. But I am not _totally_ unreasonable. (Compare https://github.com/google/guava/commit/ccb126df16cca8002946d8c9b4347c670d2ca6eb.))

(And remove a comment about how our `subList` declarations narrow the return type. They do, but there's enough else going on that I found the comment weird when I came across it.)

RELNOTES=n/a
PiperOrigin-RevId: 971463557
2026-08-26 13:23:28 -07:00
Kurt Alfred Kluever 6331603dfb Document Java 24+ Gatherers.windowFixed() on Lists.partition() and related methods.
RELNOTES=n/a
PiperOrigin-RevId: 970852727
2026-08-25 15:58:24 -07:00
Uttkarsh Singh d21bbc24c8 Fix a/an grammar typos in comments
Fixes https://github.com/google/guava/pull/8624

RELNOTES=n/a
PiperOrigin-RevId: 970744628
2026-08-25 13:12:58 -07:00
cpovirk 3121e272c4 Stop passing [-ntp](https://maven.apache.org/docs/3.6.1/release-notes.html#user-visible-changes) now that it [is the default for GitHub Actions](https://github.com/actions/setup-java/pull/1053).
The default changed [in time for `actions/setup-java` release 5.5.0](https://github.com/actions/setup-java/commit/6c4d4a5025dca6ad7cc86c839fadbcb66762ed3b). We are [on 5.6.0](https://github.com/google/guava/blob/ad1aebcf6df97a3e7b1965e8b58746228f150233/.github/workflows/ci.yml#L44).

I [noticed this yesterday](https://github.com/google/guava/pull/8627#issuecomment-5400043165).

RELNOTES=n/a
PiperOrigin-RevId: 970673459
2026-08-25 11:16:55 -07:00