-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
feat: Add support for JDK21 Sequenced Collections. #3708
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
feat: Add support for JDK21 Sequenced Collections. #3708
Conversation
JEP 431 introduced new Sequenced Collection interfaces in JDK 21. Previously, unstubbed methods returning these types would result in null. This changes allow Mockito appropriate empty collections (e.g. ArrayList for SequencedCollection) while maintaining the Java 11 baseline compatability. Fixes mockito#3659 Signed-off-by: BeomSeogKim <kbs4520@daum.net>
@@ -176,6 +176,33 @@ public void should_return_empty_duration() throws Exception { | |||
assertEquals("seconds of empty " + fqcn, 0L, seconds); | |||
} | |||
|
|||
@Test | |||
public void should_return_empty_sequenced_collection_on_java21() throws Exception { | |||
Class<?> sequencedCollectionClass = getClassOrSkipTest("java.util.SequencedCollection"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mockito/developers I wonder if we should split this test for each JDK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we can use Assume.assumeThat
for this: https://github.com/search?q=repo%3Amockito%2Fmockito+assumeThat&type=code However, let's do that in a follow-up PR to keep things manageable.
@BeomSeogKim do you mind picking that up next?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the follow up PR.
#3711
Thanks for the kindness review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
@@ -176,6 +176,33 @@ public void should_return_empty_duration() throws Exception { | |||
assertEquals("seconds of empty " + fqcn, 0L, seconds); | |||
} | |||
|
|||
@Test | |||
public void should_return_empty_sequenced_collection_on_java21() throws Exception { | |||
Class<?> sequencedCollectionClass = getClassOrSkipTest("java.util.SequencedCollection"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we can use Assume.assumeThat
for this: https://github.com/search?q=repo%3Amockito%2Fmockito+assumeThat&type=code However, let's do that in a follow-up PR to keep things manageable.
@BeomSeogKim do you mind picking that up next?
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3708 +/- ##
============================================
+ Coverage 86.42% 86.43% +0.01%
- Complexity 2964 2969 +5
============================================
Files 341 341
Lines 9000 9011 +11
Branches 1105 1110 +5
============================================
+ Hits 7778 7789 +11
Misses 941 941
Partials 281 281 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| Package | Type | Package file | Manager | Update | Change | |---|---|---|---|---|---| | [org.mockito:mockito-core](https://github.com/mockito/mockito) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `5.18.0` -> `5.19.0` | | [com.google.api-client:google-api-client](https://github.com/googleapis/google-api-java-client) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.8.0` -> `2.8.1` | | [com.datadoghq:dd-trace-api](https://github.com/datadog/dd-trace-java) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `1.52.0` -> `1.52.1` | | [software.amazon.awssdk:sdk-core](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.32.22` -> `2.32.23` | | [software.amazon.awssdk:sqs](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.32.22` -> `2.32.23` | | [software.amazon.awssdk:regions](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.32.22` -> `2.32.23` | | [software.amazon.awssdk:dynamodb-enhanced](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.32.22` -> `2.32.23` | | [software.amazon.awssdk:dynamodb](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.32.22` -> `2.32.23` | | [software.amazon.awssdk:aws-core](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.32.22` -> `2.32.23` | | [software.amazon.awssdk:bom](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.32.22` -> `2.32.23` | | [software.amazon.awssdk:auth](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.32.22` -> `2.32.23` | --- ### Release Notes <details> <summary>mockito/mockito (org.mockito:mockito-core)</summary> ### [`v5.19.0`](https://github.com/mockito/mockito/releases/tag/v5.19.0) <sup><sup>*Changelog generated by [Shipkit Changelog Gradle Plugin](https://github.com/shipkit/shipkit-changelog)*</sup></sup> ##### 5.19.0 - 2025-08-15 - [37 commit(s)](mockito/mockito@v5.18.0...v5.19.0) by Adrian-Kim, Tim van der Lippe, Tran Ngoc Nhan, dependabot\[bot], juyeop - feat: Add support for JDK21 Sequenced Collections. [(#​3708)](mockito/mockito#3708) - Bump actions/checkout from 4 to 5 [(#​3707)](mockito/mockito#3707) - build: Allow overriding 'Created-By' for reproducible builds [(#​3704)](mockito/mockito#3704) - Bump org.assertj:assertj-core from 3.27.3 to 3.27.4 [(#​3703)](mockito/mockito#3703) - Bump androidx.test:runner from 1.6.2 to 1.7.0 [(#​3697)](mockito/mockito#3697) - Bump org.junit.platform:junit-platform-launcher from 1.13.3 to 1.13.4 [(#​3694)](mockito/mockito#3694) - Bump com.diffplug.spotless:spotless-plugin-gradle from 7.1.0 to 7.2.1 [(#​3693)](mockito/mockito#3693) - Bump junit-jupiter from 5.13.3 to 5.13.4 [(#​3691)](mockito/mockito#3691) - Bump com.gradle.develocity from 4.0.2 to 4.1 [(#​3689)](mockito/mockito#3689) - Bump com.google.googlejavaformat:google-java-format from 1.27.0 to 1.28.0 [(#​3688)](mockito/mockito#3688) - Bump com.google.googlejavaformat:google-java-format from 1.25.2 to 1.27.0 [(#​3686)](mockito/mockito#3686) - Bump com.diffplug.spotless:spotless-plugin-gradle from 7.0.4 to 7.1.0 [(#​3685)](mockito/mockito#3685) - Bump junit-jupiter from 5.13.2 to 5.13.3 [(#​3684)](mockito/mockito#3684) - Bump org.shipkit:shipkit-auto-version from 2.1.0 to 2.1.2 [(#​3683)](mockito/mockito#3683) - Bump com.diffplug.spotless:spotless-plugin-gradle from 7.0.2 to 7.0.4 [(#​3682)](mockito/mockito#3682) - Only run release after both Java and Android tests have finished [(#​3681)](mockito/mockito#3681) - Bump org.junit.platform:junit-platform-launcher from 1.12.2 to 1.13.3 [(#​3680)](mockito/mockito#3680) - Bump org.codehaus.groovy:groovy from 3.0.24 to 3.0.25 [(#​3679)](mockito/mockito#3679) - Bump org.eclipse.platform:org.eclipse.osgi from 3.23.0 to 3.23.100 [(#​3678)](mockito/mockito#3678) - Can no longer publish snapshot releases [(#​3677)](mockito/mockito#3677) - Update Gradle to 8.14.2 [(#​3676)](mockito/mockito#3676) - Bump errorprone from 2.23.0 to 2.39.0 [(#​3674)](mockito/mockito#3674) - Correct Junit docs link [(#​3672)](mockito/mockito#3672) - Bump net.ltgt.gradle:gradle-errorprone-plugin from 4.1.0 to 4.3.0 [(#​3670)](mockito/mockito#3670) - Bump junit-jupiter from 5.13.1 to 5.13.2 [(#​3669)](mockito/mockito#3669) - Bump bytebuddy from 1.17.5 to 1.17.6 [(#​3668)](mockito/mockito#3668) - Bump junit-jupiter from 5.12.2 to 5.13.1 [(#​3666)](mockito/mockito#3666) - Bump org.jetbrains.kotlin:kotlin-stdlib from 2.0.21 to 2.2.0 [(#​3665)](mockito/mockito#3665) - Bump org.gradle.toolchains.foojay-resolver-convention from 0.9.0 to 1.0.0 [(#​3661)](mockito/mockito#3661) - Bump org.junit.platform:junit-platform-launcher from 1.11.4 to 1.12.2 [(#​3660)](mockito/mockito#3660) - Add JDK21 sequenced collections for ReturnsEmptyValues [(#​3659)](mockito/mockito#3659) - Bump com.gradle.develocity from 3.19.1 to 4.0.2 [(#​3658)](mockito/mockito#3658) - Bump ru.vyarus:gradle-animalsniffer-plugin from 1.7.2 to 2.0.1 [(#​3657)](mockito/mockito#3657) - Bump org.eclipse.platform:org.eclipse.osgi from 3.22.0 to 3.23.0 [(#​3656)](mockito/mockito#3656) - Bump org.codehaus.groovy:groovy from 3.0.23 to 3.0.24 [(#​3655)](mockito/mockito#3655) - Bump junit-jupiter from 5.11.4 to 5.12.2 [(#​3653)](mockito/mockito#3653) - Reproducible Build: need to inject JDK distribution details to rebuild [(#​3563)](mockito/mockito#3563) </details> <details> <summary>googleapis/google-api-java-client (com.google.api-client:google-api-client)</summary> ### [`v2.8.1`](https://github.com/googleapis/google-api-java-client/blob/HEAD/CHANGELOG.md#281-2025-08-14) ##### Bug Fixes - **deps:** Update project.http.version to v2 ([#​2598](googleapis/google-api-java-client#2598)) ([4874da1](googleapis/google-api-java-client@4874da1)) </details> <details> <summary>datadog/dd-trace-java (com.datadoghq:dd-trace-api)</summary> ### [`v1.52.1`](https://github.com/DataDog/dd-trace-java/releases/tag/v1.52.1): 1.52.1 ### Components #### Application Security Management (WAF) - 🐛 Fix NullPointerException log in AppSec ([#​9356](DataDog/dd-trace-java#9356) - [@​jandro996](https://github.com/jandro996)) #### Continuous Integration Visibility - ✨⚡ Do not follow symlinks by default when building repository index ([#​9322](DataDog/dd-trace-java#9322) - [@​nikita-tkachenko-datadog](https://github.com/nikita-tkachenko-datadog)) #### GraalVM native-image - 🐛 Update GraalVM config to reflect TempLocationManager's new package ([#​9338](DataDog/dd-trace-java#9338) - [@​luneo7](https://github.com/luneo7) - thanks for the contribution!) #### Profiling - 🐛 Properly handle trace agent IPv6 URL in profiling ([#​9339](DataDog/dd-trace-java#9339) - [@​jbachorik](https://github.com/jbachorik)) #### Realtime User Monitoring - ✨ Support async servlet for RUM injection ([#​9343](DataDog/dd-trace-java#9343) - [@​amarziali](https://github.com/amarziali)) - 🐛 Improve RUM injection matching and avoid truncating responses ([#​9342](DataDog/dd-trace-java#9342) - [@​amarziali](https://github.com/amarziali)) - ✨ Make rum injector stream/writer more resilient to errors ([#​9340](DataDog/dd-trace-java#9340) - [@​amarziali](https://github.com/amarziali)) #### Tracer core - 🐛 Avoid NPE on featureDiscovery creation ([#​9354](DataDog/dd-trace-java#9354) - [@​amarziali](https://github.com/amarziali)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - "after 6pm every weekday,before 2am every weekday" in timezone Australia/Melbourne, Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Never, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). GitOrigin-RevId: 74bf02ba96add7578dbd1f225449c2f86de0c99d
…ard `Assume.assumeThat` utility for conditional execution. Follow-up to mockito#3708 Signed-off-by: BeomSeogKim <kbs4520@daum.net>
…ard `Assume.assumeThat` utility for conditional execution. Follow-up to mockito#3708 Signed-off-by: BeomSeogKim <kbs4520@daum.net>
This PR resolves issue #3659 by adding support for JDK 21's Sequenced Collections.
Description
JEP 431 introduced new SequencedCollection, SequencedSet, and SequencedMap interfaces in JDK 21. When a mock method with one of these return types was unstubbed, Mockito would previously return null instead of an empty collection.
Implementation Details
To address this while maintaining Java 11 compatibility, ReturnsEmptyValues has been updated. The key changes are:
A new private method, returnValueForSequencedCollection, was introduced to handle the reflection-based checks in isolation.
This method is called at the beginning of returnValueFor to prioritize these special version-specific checks.
Fixes #3659
Checklist
including project members to get a better picture of the change
commit is meaningful and help the people that will explore a change in 2 years
./gradlew spotlessApply
for auto-formatting)Fixes #<issue number>
in the description if relevantFixes #<issue number>
if relevant