-
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
Add Java8+ APIs to guava-android #6567
Comments
Sorry, this kind of problem crops up occasionally. See, e.g., https://stackoverflow.com/q/65646026/28465. Since we dropped support for Java 7 back in 31.0, we can in theory now get away with adding methods that use Java 8+ types like Can we get away with it in practice? I'm going to run a test with I do note that this general class of problem will exist as long as guava-jre contains any APIs that guava-android doesn't. And I'm unsure whether the two will fully converge. But this problem is a reason to consider making them converge, even if it doesn't make fully sense. And even if they don't fully converge, there's a big difference between missing commonly used APIs (like our Independent of all that, one thing that we really, really should do is finally get back to #3683: It is designed to make Gradle pick the maximum numeric part of the version number for Guava but then choose -android or -jre as appropriate. That PR is frequently on my mind; I just need to find an hour on a day when I'm feeling up for a deep dive and when nothing else is on fire :) (For non-Gradle users, we could additionally consider releasing separate |
It looks like we'd be able to add I'm thinking I might try something like this:
I don't expect to add any of the APIs in the next Guava release. But that's only because we've had a surprising number of changes that I'd like to release soonish so that users can pick them out without taking even a small risk from (I'm going to generalize this issue to be about the overall effort.) |
Actually, we added |
…-android` (but don't do so yet). Progress toward #6567 RELNOTES=n/a PiperOrigin-RevId: 542547311
…-android` (but don't do so yet). Progress toward #6567 RELNOTES=n/a PiperOrigin-RevId: 543468006
To be conservative, this commit does not removes most annotation artifacts from Gradle's runtime classpath, only j2objc-annotations. The other artifacts contain at least some annotations with RUNTIME visibility (IIRC). (Even this change could theoretically affect users who assume that they can read CLASS-retention annotations (of which j2objc-annotations has some) from bytecode and find them in the runtime classpath. But that seems unlikely, especially for j2objc annotations.) We may consider being more aggressive in the future. For now, this particular commit addresses #2824 for Gradle users just a tiny bit, and it helps with the problem that prompted #6567. Fixes #3683 RELNOTES=Added [Gradle Module Metadata](https://docs.gradle.org/current/userguide/publishing_gradle_module_metadata.html). If you use Gradle 6 or higher, Gradle can automatically intelligently resolve conflicts between `guava-android` and `guava-jre`, among [other benefits](#3683). PiperOrigin-RevId: 337348979
To be conservative, this commit does not removes most annotation artifacts from Gradle's runtime classpath, only j2objc-annotations. The other artifacts contain at least some annotations with RUNTIME visibility (IIRC). (Even this change could theoretically affect users who assume that they can read CLASS-retention annotations (of which j2objc-annotations has some) from bytecode and find them in the runtime classpath. But that seems unlikely, especially for j2objc annotations.) We may consider being more aggressive in the future. For now, this particular commit addresses #2824 for Gradle users just a tiny bit, and it helps with the problem that prompted #6567. Fixes #3683 RELNOTES=Added [Gradle Module Metadata](https://docs.gradle.org/current/userguide/publishing_gradle_module_metadata.html). If you use Gradle 6 or higher, Gradle can automatically intelligently resolve conflicts between `guava-android` and `guava-jre`, among [other benefits](#3683). PiperOrigin-RevId: 544108700
@swankjesse, from my reading the original issue will be solved by ce78fc6, see the section titled "Selecting the appropriate flavor" in 32.1 release notes, will test when 32.1.1 is released. |
Thanks, yes, that's the theory. I've released 32.1.1. Sorry for the trouble with 32.1.0. Please do let us know how it goes. |
Not trivial... got a capability conflict, will have to look deeper later. |
The primary change comes as a followup to cl/543468006: Now that the Google-internal `ImmutableTable` declares [methods with Java 8+ types in their signatures](#6567), we get a `NoClassDefFoundError` when performing reflection on the class under old Android emulators. We perform reflection only when (a) using `NullPointerTester` or (b) using serialization. So we (a) stop running `NullPointerTester` under an Android emulator (though we continue to run the same `guava-android` test under a JVM) and (b) specify a `serialVersionUID` so that serialization doesn't need to compute one. (Specifying `serialVersionUID` was our MO for a while. Perhaps we just got careless, and perhaps we should be more diligent. Alternatively, perhaps we should change the `serialVersionUID` every release or so so as to encourage people [not to persist serialized data](https://github.com/google/guava#important-warnings). I at least went to a tiny bit of effort to keep `guava-jre` and `guava-android` on different `serialVersionUID` values, though maybe that's more likely to cause needless trouble someday than to prevent it?) The other change is to avoid running another GC test under an Android emulator. We'd originally done this for one copy of `AbstractIteratorTester` in cl/444929745, but for whatever reason, we didn't need it for the other copy until (I assume) cl/546307327 and its switch to a different emulator version. RELNOTES=n/a PiperOrigin-RevId: 550670580
The primary change comes as a followup to cl/543468006: Now that the Google-internal `ImmutableTable` declares [methods with Java 8+ types in their signatures](#6567), we get a `NoClassDefFoundError` when performing reflection on the class under old Android emulators. We perform reflection only when (a) using `NullPointerTester` or (b) using serialization. So we (a) stop running `NullPointerTester` under an Android emulator (though we continue to run the same `guava-android` test under a JVM) and (b) specify a `serialVersionUID` so that serialization doesn't need to compute one. (Specifying `serialVersionUID` was our MO for a while. Perhaps we just got careless, and perhaps we should be more diligent. Alternatively, perhaps we should change the `serialVersionUID` every release or so so as to encourage people [not to persist serialized data](https://github.com/google/guava#important-warnings). I at least went to a tiny bit of effort to keep `guava-jre` and `guava-android` on different `serialVersionUID` values, though maybe that's more likely to cause needless trouble someday than to prevent it?) The other change is to avoid running another GC test under an Android emulator. We'd originally done this for one copy of `AbstractIteratorTester` in cl/444929745, but for whatever reason, we didn't need it for the other copy until (I assume) cl/546307327 and its switch to a different emulator version. RELNOTES=n/a PiperOrigin-RevId: 550872250
…/docs/api/java.base/java/util/SequencedCollection.html) methods to `ImmutableSortedSet`. There are a couple reasons that this is maybe kind of nice, and then there's my real motivation for doing it. Reasons that this is maybe kind of nice: - We add `@DoNotCall` and `@Deprecated` to the mutator methods, as usual. - We refine the return type of `reversed()` to `ImmutableSortedSet`. But again, those aren't my real motivation. (If they _were_ my real motivation, you might notice, then there would be no reason for us to override `getFirst()` and `getLast()`.) My _real_ motivation is that we are looking to give `guava-android` APIs that use Java 8+ types in their signatures, such as `ImmutableSet.toImmutableSet`. And as a result of some part of those changes, we start seeing errors in some of our Google-internal build rules. Those errors come because some the desugaring process is inserting its own versions of `getFirst` and friends, versions that refer to the desugar-provided copies of `SortedSet` and `NavigableSet`, which our build process then looks for but cannot find. Since this CL is preparation for adding `ImmutableSet.toImmutableSet`, it constitutes further progress toward #6567 RELNOTES=`collect`: Added [`SequencedCollection`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/SequencedCollection.html) methods to `ImmutableSortedSet`. PiperOrigin-RevId: 575207552
…/docs/api/java.base/java/util/SequencedCollection.html) methods to `ImmutableSortedSet`. There are a couple reasons that this is maybe kind of nice, and then there's my real motivation for doing it. Reasons that this is maybe kind of nice: - We add `@DoNotCall` and `@Deprecated` to the mutator methods, as usual. - We refine the return type of `reversed()` to `ImmutableSortedSet`. But again, those aren't my real motivation. (If they _were_ my real motivation, you might notice, then there would be no reason for us to override `getFirst()` and `getLast()`.) My _real_ motivation is that we are looking to give `guava-android` APIs that use Java 8+ types in their signatures, such as `ImmutableSet.toImmutableSet`. And as a result of some part of those changes, we start seeing errors in some of our Google-internal build rules. Those errors come because some the desugaring process is inserting its own versions of `getFirst` and friends, versions that refer to the desugar-provided copies of `SortedSet` and `NavigableSet`, which our build process then looks for but cannot find. Since this CL is preparation for adding `ImmutableSet.toImmutableSet`, it constitutes further progress toward #6567 RELNOTES=`collect`: Added [`SequencedCollection`](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/SequencedCollection.html) methods to `ImmutableSortedSet`. PiperOrigin-RevId: 575459262
…package-private method. (The latter prepares for [Android compatibility for Java 8 APIs](#6567).) RELNOTES=n/a PiperOrigin-RevId: 626483101
…package-private method. (The latter prepares for [Android compatibility for Java 8 APIs](#6567).) RELNOTES=n/a PiperOrigin-RevId: 626483101
…package-private method. (The latter prepares for [Android compatibility for Java 8 APIs](#6567).) RELNOTES=n/a PiperOrigin-RevId: 626483101
…package-private method. (The latter prepares for [Android compatibility for Java 8 APIs](#6567).) RELNOTES=n/a PiperOrigin-RevId: 626483101
…package-private method. (The latter prepares for [Android compatibility for Java 8 APIs](#6567).) RELNOTES=n/a PiperOrigin-RevId: 626483101
…package-private method. (The latter prepares for [Android compatibility for Java 8 APIs](#6567).) RELNOTES=n/a PiperOrigin-RevId: 626483101
…package-private method. (The latter prepares for [Android compatibility for Java 8 APIs](#6567).) RELNOTES=n/a PiperOrigin-RevId: 627098517
(for example, `ImmutableList.toImmutableList()`) For now, we're making them `@Beta` just in case users encounter enough problems that we find it less disruptive to revert this change than to keep it. However, we plan to remove `@Beta` soon, at which point we'll be committed to this APIs. If you use Guava under Android, please [test with Guava 33.0.0 or higher](https://groups.google.com/g/guava-announce/c/9-dw_C6G_NM), ideally with 34.0.0 or higher (which will contain this commit), and [report any problems](https://github.com/google/guava/issues/new?assignees=&labels=type%3Ddefect&projects=&template=bug_report.yaml). Our expectation is that this commit should not cause problems, even for users who don't use enable [library desugaring](https://developer.android.com/studio/write/java11-default-support-table). But we will see what happens in wild. Of course, if you want to actually _use_ these APIs, then you'll need to [enable library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) or target a [new enough version of Android](https://developer.android.com/reference/java/util/stream/Stream), just as with any other `Stream`-based APIs. (progress toward #6567) RELNOTES=`collect`: Made our `Collector` APIs (e.g., `ImmutableList.toImmutableList()`) available in `guava-android`. PiperOrigin-RevId: 629191336
(for example, `ImmutableList.toImmutableList()`) For now, we're making them `@Beta` just in case users encounter enough problems that we find it less disruptive to revert this change than to keep it. However, we plan to remove `@Beta` soon, at which point we'll be committed to this APIs. If you use Guava under Android, please [test with Guava 33.0.0 or higher](https://groups.google.com/g/guava-announce/c/9-dw_C6G_NM), ideally with 34.0.0 or higher (which will contain this commit), and [report any problems](https://github.com/google/guava/issues/new?assignees=&labels=type%3Ddefect&projects=&template=bug_report.yaml). Our expectation is that this commit should not cause problems, even for users who don't use enable [library desugaring](https://developer.android.com/studio/write/java11-default-support-table). But we will see what happens in wild. Of course, if you want to actually _use_ these APIs, then you'll need to [enable library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) or target a [new enough version of Android](https://developer.android.com/reference/java/util/stream/Stream), just as with any other `Stream`-based APIs. (progress toward #6567) RELNOTES=`collect`: Made our `Collector` APIs (e.g., `ImmutableList.toImmutableList()`) available in `guava-android`. PiperOrigin-RevId: 629191336
(for example, `ImmutableList.toImmutableList()`) For now, we're making them `@Beta` just in case users encounter enough problems that we find it less disruptive to revert this change than to keep it. However, we plan to remove `@Beta` soon, at which point we'll be committed to this APIs. If you use Guava under Android, please [test with Guava 33.0.0 or higher](https://groups.google.com/g/guava-announce/c/9-dw_C6G_NM), ideally with 34.0.0 or higher (which will contain this commit), and [report any problems](https://github.com/google/guava/issues/new?assignees=&labels=type%3Ddefect&projects=&template=bug_report.yaml). Our expectation is that this commit should not cause problems, even for users who don't use enable [library desugaring](https://developer.android.com/studio/write/java11-default-support-table). But we will see what happens in wild. Of course, if you want to actually _use_ these APIs, then you'll need to [enable library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) or target a [new enough version of Android](https://developer.android.com/reference/java/util/stream/Stream), just as with any other `Stream`-based APIs. (progress toward #6567) RELNOTES=`collect`: Made our `Collector` APIs (e.g., `ImmutableList.toImmutableList()`) available in `guava-android`. PiperOrigin-RevId: 629491350
33.2.0 adds Barring surprises, we'll add most Java 8+ APIs in the next release or thereafter. |
…testing. We had disabled the tests in that environment because `NullPointerTester` performed reflection on types that contained `Collector`-based APIs. Since `Collector` wasn't available, the tests failed. But now, we've enabled library desugaring for our internal tests (though we continue not to _require_ library desugaring unless users actually use such APIs), so the tests can work again. (relevant to #6567) RELNOTES=n/a PiperOrigin-RevId: 634770528
…testing. We had disabled the tests in that environment because `NullPointerTester` performed reflection on types that contained `Collector`-based APIs. Since `Collector` wasn't available, the tests failed. But now, we've enabled library desugaring for our internal tests (though we continue not to _require_ library desugaring unless users actually use such APIs), so the tests can work again. (relevant to #6567) RELNOTES=n/a PiperOrigin-RevId: 634784425
(progress toward #6567) RELNOTES=`collect`: Removed `@Beta` from the `guava-android` `Collector` APIs. PiperOrigin-RevId: 630165794
(progress toward #6567) RELNOTES=`collect`: Removed `@Beta` from the `guava-android` `Collector` APIs. PiperOrigin-RevId: 630165794
(progress toward #6567) RELNOTES=`collect`: Removed `@Beta` from the `guava-android` `Collector` APIs. PiperOrigin-RevId: 639518116
Also, related minor changes: - Import `java.time.Duration` instead of using it fully qualified. (Somehow, existing unqualified usages of `Duration` in _Javadoc_ references were working even without the import.) Compare cl/641315337. - "Upstream" a fix to a Javadoc reference to `maximumSize` from the Android flavor to the mainline. Fixes #7232 Progress on #6567 RELNOTES=`cache`: Added `CacheBuilder` `Duration` overloads to `guava-android`. PiperOrigin-RevId: 642709673
Also, related minor changes: - Import `java.time.Duration` instead of using it fully qualified. (Somehow, existing unqualified usages of `Duration` in _Javadoc_ references were working even without the import.) Compare cl/641315337. - "Upstream" a fix to a Javadoc reference to `maximumSize` from the Android flavor to the mainline. Fixes #7232 Progress on #6567 RELNOTES=`cache`: Added `CacheBuilder` `Duration` overloads to `guava-android`. PiperOrigin-RevId: 642709673
Also, related minor changes: - Import `java.time.Duration` instead of using it fully qualified. (Somehow, existing unqualified usages of `Duration` in _Javadoc_ references were working even without the import.) Compare cl/641315337. - "Upstream" a fix to a Javadoc reference to `maximumSize` from the Android flavor to the mainline. Fixes #7232 Progress on #6567 RELNOTES=`cache`: Added `CacheBuilder` `Duration` overloads to `guava-android`. PiperOrigin-RevId: 642709673
Also, related minor changes: - Import `java.time.Duration` instead of using it fully qualified. (Somehow, existing unqualified usages of `Duration` in _Javadoc_ references were working even without the import.) Compare cl/641315337. - "Upstream" a fix to a Javadoc reference to `maximumSize` from the Android flavor to the mainline. Fixes #7232 Progress on #6567 RELNOTES=`cache`: Added `CacheBuilder` `Duration` overloads to `guava-android`. PiperOrigin-RevId: 642709673
Also, related minor changes: - Import `java.time.Duration` instead of using it fully qualified. (Somehow, existing unqualified usages of `Duration` in _Javadoc_ references were working even without the import.) Compare cl/641315337. - "Upstream" a fix to a Javadoc reference to `maximumSize` from the Android flavor to the mainline. Fixes #7232 Progress on #6567 RELNOTES=`cache`: Added `CacheBuilder` `Duration` overloads to `guava-android`. PiperOrigin-RevId: 642993916
When we upgraded Truth we started getting crashes like this:
As @TWiStErRob explains on Paparazzi #906:
A very simple fix for our problem is for Guava to support the
toImmutableEnumSet()
function on all platforms. I don’t believe this function needs the same implementation on all platforms; it just needs something so we don’t crash at runtime.The text was updated successfully, but these errors were encountered: