Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
237 commits
Select commit Hold shift + click to select a range
3fa56db
Fix Spliterator characteristics in ConcurrentReferenceHashMap
kilink Nov 13, 2025
6be1c29
Polish contribution
sbrannen Nov 17, 2025
46ee944
Update Antora Spring UI to v0.4.20
github-actions[bot] Nov 13, 2025
f3ed04c
Fix single-check idiom in UnmodifiableMultiValueMap
kilink Nov 14, 2025
5af1c9b
Fix HtmlUtils unescape for supplementary chars
juntae6942 Sep 13, 2025
030dace
Polishing contribution
bclozel Nov 17, 2025
8553f97
Merge HtmlCharacterEntityDecoderTests into HtmlUtilsTests
sbrannen Nov 17, 2025
f94645d
Narrow Aware interface exclusion check to BeanFactoryAware only
jhoeller Nov 18, 2025
8545a75
Add resetCaches() method to Caffeine/ConcurrentMapCacheManager
jhoeller Nov 18, 2025
e428817
Fix getCacheNames() concurrent access in NoOpCacheManager
jhoeller Nov 18, 2025
bd10b7a
Remove javadoc references to deprecated PropertiesBeanDefinitionReader
jhoeller Nov 19, 2025
4e97013
Polishing
jhoeller Nov 19, 2025
ff62e73
Fix cross-reference links in HtmlUnit sections
ngocnhan-tran1996 Nov 19, 2025
e146e80
Polishing
sbrannen Nov 19, 2025
e5de8b9
Fix link to MockMvc test in HtmlUnit section
sbrannen Nov 19, 2025
59025c5
Lazily initialize ProblemDetail for picking up actual status code
jhoeller Nov 19, 2025
7a0ea14
Next development version (v6.2.15-SNAPSHOT)
bclozel Nov 20, 2025
1bdd833
Update outdated comments in JdbcOperationsExtensions.kt
sdeleuze Nov 20, 2025
a4b1155
Update Antora Spring UI to v0.4.22
github-actions[bot] Nov 20, 2025
a413466
Update Antora Spring UI to v0.4.25
github-actions[bot] Nov 24, 2025
ab93020
Link to Spring Framework Artifacts wiki page
sbrannen Nov 26, 2025
85c47a7
Fix formatting for backticks in Kotlin docs
sbrannen Nov 26, 2025
37e26e0
Use current links to JUnit documentation
sbrannen Nov 26, 2025
f9b4fba
Add required type to TypeMismatchException message args
rstoyanchev Nov 25, 2025
19b080b
Clarify JMS sessionTransacted flag for local versus global transaction
jhoeller Nov 26, 2025
ab96576
Expose non-existent resources at the end of the sorted result
jhoeller Nov 26, 2025
e7a5452
Consistent namespace element declarations
jhoeller Nov 26, 2025
1409334
Refer to "Spring Tools" instead of "Spring Tools for Eclipse"
sbrannen Nov 26, 2025
b39055f
Fix broken Javadoc links to methods
ngocnhan-tran1996 Nov 26, 2025
22d2810
Narrow method annotation check in hasQualifier to setter methods
jhoeller Nov 26, 2025
c2f7cd3
Convert sentence to tip in Kotlin testing chapter
sbrannen Nov 27, 2025
b25f983
Tighten cacheable decision behind @Lazy injection point
jhoeller Nov 27, 2025
3b556ba
Polishing
jhoeller Nov 27, 2025
8211654
Use concurrent set for reactive transaction synchronizations
jhoeller Nov 28, 2025
3121daf
Stop linking to 6.1.22-SNAPSHOT reference docs
sbrannen Nov 28, 2025
3faa7ca
Polishing
jhoeller Nov 30, 2025
bc07318
Use channelId for ReactorNettyWebSocketSession's id
rstoyanchev Dec 1, 2025
67a9230
BindingContext constructor uses given ReactiveAdapterRegistry arg
JohnNiang Nov 7, 2025
2144813
FragmentsRendering exposes its fragments
rstoyanchev Dec 1, 2025
8744982
Clear remaining invoker resources when releasing shared Connection
jhoeller Dec 1, 2025
8f6d44a
Improve debug log for received message
jhoeller Dec 1, 2025
0008106
Upgrade json-path to 2.10.0
ivonaest Nov 27, 2025
2aa3b0a
Select method with resolved return type match (among multiple candida…
jhoeller Dec 1, 2025
3eb1df0
Update antora-extensions to 1.14.7
sbrannen Dec 2, 2025
afc40d7
Avoid computeIfAbsent for createMappings which calls back into same map
jhoeller Dec 3, 2025
1fd1d8d
Polishing
jhoeller Dec 3, 2025
5b4728f
Avoid http - web.utils package cycle
rstoyanchev Dec 2, 2025
8803d3c
Lower bad requests to DEBUG level in AbstractHandshakeHandler
rstoyanchev Dec 2, 2025
96503a2
Polishing
rstoyanchev Dec 4, 2025
e79d8e3
Document that annotations which reference types not present are ignored
sbrannen Dec 5, 2025
97b9517
Handle absolute file URLs in getClassPathManifestEntriesFromJar
jhoeller Dec 5, 2025
8041a09
Polishing
jhoeller Dec 5, 2025
ad849fb
Accept assignable match for covariant return type
jhoeller Dec 8, 2025
221adf1
Fix SubscriberInputStream.resume()
izeye Dec 8, 2025
3b1fa36
Polishing contribution
bclozel Dec 8, 2025
24df35c
Do not keep target connection after failed settings
jhoeller Dec 9, 2025
2155e9f
Upgrade to Micrometer 1.14.14
bclozel Dec 9, 2025
c89c4ac
Upgrade to Reactor 2024.0.13
bclozel Dec 9, 2025
23625ee
Do not send null HTTP header value in JdkClientHttpRequest
bclozel Dec 11, 2025
d470580
Next development version (v6.2.16-SNAPSHOT)
bclozel Dec 11, 2025
5eb16a6
Refresh GitHub Actions
snicoll Dec 12, 2025
08b77dd
Fix typos and grammar in reference manual
ngocnhan-tran1996 Dec 13, 2025
8362893
Revise contribution
sbrannen Dec 13, 2025
c0e8a36
Polishing
sbrannen Dec 13, 2025
91a0c28
Fix RfcUriParser parsing for single char fragments
bclozel Dec 17, 2025
9a0bfd7
Do not attempt nested PropertyHandler resolution for argument conversion
jhoeller Dec 17, 2025
be68a77
Fix memory leak in WiretapConnector
bclozel Dec 19, 2025
476aae5
Polish integration tests
sbrannen Dec 15, 2025
add3b1a
Extract CopyPropertiesTests as nested test class in BeanUtilsTests
sbrannen Dec 15, 2025
b3fb9f4
Reliably resolve generic read/write methods in PropertyDescriptorUtils
sbrannen Dec 15, 2025
7482ccc
Upgrade Antora dependencies
sdeleuze Jan 7, 2026
5236b35
Update Principal check in TransportHandlingSockJsService
rstoyanchev Nov 5, 2025
05beb4a
Upgrade to JUnit 5.14.2
sbrannen Jan 14, 2026
05a9cc2
Improve DisconnectedClientHelper to better guard ClassNotFoundException
quaff Jan 14, 2026
dcb7922
Exclude DataAccessException and MessagingException in DisconnectedCli…
rstoyanchev Jan 14, 2026
6bd0ed8
Polishing
jhoeller Jan 14, 2026
183cd4c
Clear Netty channel attribute
rstoyanchev Jan 16, 2026
0033eda
Apply transactionIsolationLock in EclipseLinkConnectionHandle as well
jhoeller Jan 16, 2026
c750efb
Bring back WebLogicJtaTransactionManager for WebLogic 15.1.1
jhoeller Jan 16, 2026
9e51231
Avoid javadoc build failure against HttpClient 5.5.x
jhoeller Jan 16, 2026
13defc0
Fix setBody call in reactorNettyAttributes test
jhoeller Jan 16, 2026
fd8b4d5
Replace getErrors() with getBindingResult() in examples
ngocnhan-tran1996 Jan 18, 2026
154dad6
Revise contribution
sbrannen Jan 18, 2026
cf3ed22
Fix test parameterization in CaffeineReactiveCachingTests
sbrannen Jan 20, 2026
1977f31
Prevent accidental printStackTrace() usage in main codebase
jhoeller Jan 20, 2026
f531cc9
Polishing
jhoeller Jan 20, 2026
c6e73b5
Fix JMSReplyTo references in javadoc (backported from main)
jhoeller Jan 21, 2026
58af70f
Upgrade to Selenium 4.40, HtmlUnit 4.21, Protobuf 4.33.4
jhoeller Jan 21, 2026
c49d5dc
Handle early exception from AsynchronousFileChannel#write
rstoyanchev Jan 22, 2026
1e0a853
Revise setPersistenceUnitName javadoc
jhoeller Jan 25, 2026
ecfd78f
Polishing (aligned with main)
jhoeller Jan 25, 2026
539a098
Update GitHub upload-artifact action to version 6
pgoslatara Jan 23, 2026
3a6c778
Upgrade to AssertJ 3.27.7
sbrannen Jan 25, 2026
2ff93f4
Consistently indent with tabs instead of spaces
sbrannen Jan 25, 2026
9f1332c
Refine solution to clear Netty channel attribute
rstoyanchev Jan 20, 2026
7b7126a
Polishing in ReactorClientHttpConnector
rstoyanchev Jan 26, 2026
1ec3cb4
Polishing (aligned with main)
jhoeller Jan 27, 2026
bc5e395
Update docs content types for ProblemDetail
rstoyanchev Jan 28, 2026
af1e9da
Update docs on trailing slash handling
rstoyanchev Jan 28, 2026
b6d1e88
Fix unfinished edit from previous commit
rstoyanchev Jan 28, 2026
103057d
Fix links to JUnit User Guide
sbrannen Jan 28, 2026
91ff706
Fix formatting and spelling
sbrannen Jan 28, 2026
b9cd06a
Support -1 for undetermined length in SqlBinaryValue/SqlCharacterValue
jhoeller Jan 28, 2026
dcf98bc
Polishing
jhoeller Jan 28, 2026
fb9db14
Consistently refer to "an SQL" statement, type, etc.
sbrannen Jan 28, 2026
56d8ec2
Consistently close streams through try-with-resources
jhoeller Jan 28, 2026
0c3dd8c
Fix "remove" implementation in netty headers adapter
bclozel Jan 29, 2026
a3c9166
Optimize NamedParameterUtils#buildValueArray by lazily fetching SqlPa…
dingqianwen Jan 30, 2026
9572025
Upgrade fast-xml-parser from 4.5.2 to 5.3.4 in /framework-docs
dependabot[bot] Jan 30, 2026
a391db2
Upgrade to ASM 9.9.1 and Objenesis 3.5
jhoeller Feb 2, 2026
ed72432
Upgrade to Groovy 4.0.30, Netty 4.1.130, Mockito 5.21
jhoeller Feb 2, 2026
5973a17
Polishing
jhoeller Feb 5, 2026
a0319b1
Repeatedly check status while trying to lock for shutdown
jhoeller Feb 6, 2026
bb35e9f
Make LocalEntityManagerFactoryBean#setDataSource work on Hibernate an…
jhoeller Feb 8, 2026
8396c07
Fix wildcard MIME type support in messaging converters
bclozel Feb 10, 2026
b00c387
Upgrade to Micrometer 1.15.9
bclozel Feb 10, 2026
7240a5a
Upgrade to Reactor 2024.0.15
bclozel Feb 10, 2026
849553d
Avoid determineValidationGroups not necessary
rstoyanchev Feb 9, 2026
5c537db
Optimize single PathPattern match
rstoyanchev Feb 9, 2026
6162d89
Cache HandlerMethod with resolved bean if singleton
rstoyanchev Feb 9, 2026
a065563
Optimize RequestMappingInfo hashcode calculation
rstoyanchev Feb 10, 2026
757b713
Use updated message in HttpEntityMethodProcessor
bclozel Feb 11, 2026
8334388
avoid unnecessary locking in ConcurrentReferenceHashMap's implementat…
chschu Feb 10, 2026
6d849bd
Next development version (v6.2.17-SNAPSHOT)
bclozel Feb 12, 2026
50bffe7
Detect all common size exceptions from Tomcat and Commons FileUpload 2.x
jhoeller Feb 13, 2026
474d520
Fix MultipartParser & PartGenerator memory leak
bclozel Feb 13, 2026
2c7ed5e
Align validation groups check with InvocableHandlerMethod in spring-web
jhoeller Feb 17, 2026
bfa8129
Polishing
jhoeller Feb 17, 2026
acab61f
Consistent adaptation of HTTP headers on Servlet responses
jhoeller Feb 17, 2026
999bbe3
Polishing
jhoeller Feb 17, 2026
c8735ef
Polishing (aligned with main)
jhoeller Feb 17, 2026
1c7e790
Skip serialization of potentially non-serializable cached state
jhoeller Feb 17, 2026
50ef3b0
Update Javadoc of RestClient.Builder defaultStatusHandler
rstoyanchev Feb 19, 2026
a3f7179
Fix InvalidMimeTypeException for compatible media types
bclozel Feb 20, 2026
2d81a9f
Optimize MediaType(MediaType, Charset) constructor
bclozel Feb 13, 2026
9042682
Optimal charset handling in AbstractHttpMessageConverter
rstoyanchev Feb 13, 2026
7768cee
Polish SpEL operator examples in reference docs
ngocnhan-tran1996 Feb 22, 2026
f87b5ee
Polish contribution
sbrannen Feb 23, 2026
972ba73
Reject late-executing tasks after termination waiting
jhoeller Feb 24, 2026
b619e69
Polishing (aligned with main)
jhoeller Feb 24, 2026
688975e
Upgrade fast-xml-parser to 5.3.6
dependabot[bot] Feb 25, 2026
f3d0f94
Upgrade to JUnit 5.14.3
sbrannen Feb 25, 2026
c77993a
Emphasize @⁠Configuration classes over XML and Groovy in testing chapter
sbrannen Feb 25, 2026
455cb76
Further emphasize @⁠Configuration classes over XML and Groovy in test…
sbrannen Feb 25, 2026
728466d
Cancel late-executing tasks within revised closed handling
jhoeller Feb 28, 2026
b426ef2
Polishing
jhoeller Feb 28, 2026
566a42b
Remove prefixed FactoryBean name in ApplicationListenerDetector
jhoeller Mar 1, 2026
c83fb69
Fix links to UriComponentsBuilder and polish examples
ngocnhan-tran1996 Mar 1, 2026
2d10d51
Consistently refer to URLs and URIs in documentation
sbrannen Mar 1, 2026
f41786b
Fix typo
sbrannen Mar 1, 2026
b9517b8
Upgrade fast-xml-parser to 5.3.8
dependabot[bot] Mar 1, 2026
2bbea84
Fix format string argument count
cetf9h Mar 3, 2026
0a93378
Exclude legacy @⁠javax.validation.Constraint from attribute override …
sbrannen Mar 3, 2026
cd9a430
Polishing
jhoeller Mar 3, 2026
507399d
Polish documentation for FrameworkServlet and HttpServletBean
sbrannen Mar 5, 2026
5806a23
Address Checkstyle violation
sbrannen Mar 5, 2026
88f081b
Resolve context initializers only once in AbstractTestContextBootstra…
sbrannen Mar 8, 2026
526f67c
Polish @⁠Bean Javadoc and reference docs
sbrannen Mar 10, 2026
7c27183
Polishing
sbrannen Mar 10, 2026
74ab662
Document registration recommendations for BeanPostProcessor and BeanF…
sbrannen Mar 9, 2026
d4f4c69
Document @Fallback alongside Primary in the reference docs and @Bean …
sbrannen Mar 10, 2026
131f94f
Use link for first reference to @⁠Fallback in @⁠Bean Javadoc
sbrannen Mar 10, 2026
8dc888e
Guard against invalid id/event values in Server Sent Events
bclozel Mar 10, 2026
d1e69a9
Upgrade to Reactor 2024.0.16 and Micrometer 1.15.10
jhoeller Mar 10, 2026
99fbce1
Polishing (aligned with main)
jhoeller Mar 11, 2026
d8c7793
Upgrade to SnakeYAML 2.6, Protobuf 4.34, H2 2.4.240
jhoeller Mar 11, 2026
47dc1c4
Fix log message in ConfigurationClassBeanDefinitionReader
sbrannen Mar 12, 2026
de6601f
Restore ScriptTemplateViewTests
sdeleuze Mar 12, 2026
317a1f9
Leverage ResourceHandlerUtils in ScriptTemplateView
sdeleuze Mar 12, 2026
b4646ce
Next development version (v6.2.18-SNAPSHOT)
bclozel Mar 13, 2026
15c82d5
Improve XJC configuration for spring-oxm in the Gradle build
Sineaggi Jan 22, 2026
2269c56
Polish contribution
sbrannen Mar 15, 2026
10faa7f
Remove obsolete, custom Eclipse configuration for spring-oxm
sbrannen Mar 15, 2026
0c4ed55
Consistently use American English spelling
sbrannen Mar 15, 2026
e598df8
Fix common typos and grammatical mistakes
sbrannen Mar 15, 2026
52345c5
Fix typo in StompSession Javadoc
xxxxxxjun Mar 15, 2026
40562e2
Update Antora Spring UI to v0.4.26
github-actions[bot] Mar 14, 2026
01248c7
Remove obsolete "test" prefix from test method names
sbrannen Mar 16, 2026
6d6b788
Enable SpringJUnit5 Checkstyle rule
sbrannen Mar 17, 2026
506c6f1
Clean up AssertJ usage after migration
sbrannen Mar 20, 2026
e607f1c
Share codings resolution in resource resolvers
bclozel Mar 20, 2026
3997551
Recognize error code 149 as deadlock loser (MySQL Galera)
jhoeller Mar 21, 2026
8b67472
Avoid endless re-interruption loop on shutdown
jhoeller Mar 21, 2026
96a028a
Consistent IOException spelling in class/method names
jhoeller Mar 21, 2026
315591f
Sync changes to antora-playbook.yml from docs-build branch
sbrannen Mar 23, 2026
b7137c5
Fix incorrect cross reference in AbstractEnvironment Javadoc
bebeis Mar 23, 2026
0c2375a
Consistent handling of early setCatalog/setSchema/setHoldability calls
jhoeller Mar 24, 2026
522a2e2
Introduce Kotlin examples for Bean Overrides (@⁠MockitoBean, etc.)
sbrannen Mar 26, 2026
db6111f
Add documentation notes on error handling with sync=true
jhoeller Mar 28, 2026
49bb287
Polishing
jhoeller Mar 28, 2026
41f4072
Fix ApplicationListenerMethodAdapter name in error message
jhoeller Mar 28, 2026
cdfb77d
Upgrade to Netty 4.1.132 and Protobuf 4.34.1
jhoeller Mar 28, 2026
aff0ce1
Polishing
jhoeller Mar 28, 2026
5a4a14c
Polishing
sbrannen Mar 30, 2026
1a05ed2
Correct Javadoc for MergedAnnotation.asAnnotationAttributes()
sbrannen Mar 30, 2026
fa04db3
Consistently log request details in ExchangeFunctions
rstoyanchev Mar 20, 2026
9af3961
Deprecate methodIdentification() in CacheAspectSupport for removal
sbrannen Mar 31, 2026
9ceb9ef
Polishing
jhoeller Apr 1, 2026
153e553
Ignore .cursor directory
sbrannen Apr 2, 2026
5873e40
Enforce use of AssertJ assumptions via Checkstyle
sbrannen Apr 2, 2026
6f204bf
Polishing
sbrannen Apr 2, 2026
684b1e8
Enforce strict implementation of Resource#isReadable() contract
jhoeller Apr 2, 2026
d78d80b
Skip annotations that cannot be processed in AnnotationBeanNameGenerator
sbrannen Apr 2, 2026
39a6d47
Deprecate types removed in 7.0
bclozel Apr 3, 2026
659271c
Fix BridgeMethodResolverTests.findBridgedMethodInHierarchy() in Eclipse
sbrannen Apr 6, 2026
b2069e4
Fix flaky SpEL tests
sbrannen Apr 6, 2026
9c82638
Fix typo
sbrannen Apr 6, 2026
2a9afd6
Document valid SpEL separators for tokenizer
bclozel Apr 7, 2026
b6a2469
Use ClassLoader for method or field in MergedAnnotation
sbrannen Apr 7, 2026
df19898
Allow unlimited caching in ContentCachingRequestWrapper
bclozel Apr 8, 2026
d356e7a
Improve Javadoc for MergedAnnotations
sbrannen Apr 8, 2026
2801c7e
Avoid MessageFormat rendering for exception messages in binding errors
jhoeller Apr 8, 2026
d675132
Improve SpringValidatorAdapter and MethodValidationAdapter performance
jhoeller Apr 8, 2026
241a7dc
Polishing
jhoeller Apr 8, 2026
923ec6a
Upgrade to Groovy 4.0.31 and Mockito 5.23
jhoeller Apr 8, 2026
63cd96f
Revise target bean exception with consistent message formatting
jhoeller Apr 8, 2026
6101419
Support @⁠Sql with DataSource wrapped in a TransactionAwareDataSource…
sbrannen Apr 8, 2026
589e58e
Skip binding entirely when field is not allowed
bclozel Apr 9, 2026
c5e5605
Document that `spring.profiles.active` is ignored by @⁠ActiveProfiles
Mohak-Nagaraju Apr 9, 2026
438b101
Revise documentation for @⁠ActiveProfiles and ActiveProfilesResolver
sbrannen Apr 9, 2026
cbdec80
Allow null id/event in ServerSentEvent
bclozel Apr 10, 2026
57d4765
Fix nullable value class handling in CoroutinesUtils
T45K Mar 13, 2026
b07bc2c
Apply nullable value class fix to InvocableHandlerMethod
sdeleuze Apr 10, 2026
9d14448
Improve SpEL tests for Elvis and Ternary operators
sbrannen Apr 12, 2026
f182f9a
Clarify semantics of HttpMethod.valueOf()
angry-2k Apr 14, 2026
69068ba
Further clarify semantics of HttpMethod.valueOf()
sbrannen Apr 14, 2026
623ccd1
Revise "Skip binding entirely when field is not allowed"
sbrannen Apr 16, 2026
af4b122
Extract ServletRequestParameterPropertyValuesTests
sbrannen Apr 16, 2026
9e0b83e
Polish WebRequestDataBinderTests
sbrannen Apr 16, 2026
4e3f264
Add missing tests for WebRequestDataBinder
sbrannen Apr 16, 2026
b338fdd
Add doOnDiscard in MultipartHttpMessageReader
rstoyanchev Apr 16, 2026
f6671e7
Upgrade to Reactor 2024.0.17 and Micrometer 1.15.11
jhoeller Apr 16, 2026
515152b
Next development version (v6.2.19-SNAPSHOT)
snicoll Apr 17, 2026
c2a5265
Merge branch '6.2.x' into 7.0.x
snicoll Apr 17, 2026
9c0aa40
Merge branch '7.0.x'
snicoll Apr 17, 2026
ad999ce
Test
sgerke-1L Apr 17, 2026
0b4084f
Fix
sgerke-1L Apr 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,10 @@ public static Publisher<?> invokeSuspendingFunction(
Object arg = args[index];
if (!(parameter.isOptional() && arg == null)) {
KType type = parameter.getType();
if (!type.isMarkedNullable() &&
if (!(type.isMarkedNullable() && arg == null) &&
type.getClassifier() instanceof KClass<?> kClass &&
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass))) {
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass)) &&
!JvmClassMappingKt.getJavaClass(kClass).isInstance(arg)) {
arg = box(kClass, arg);
}
argMap.put(parameter, arg);
Expand Down Expand Up @@ -166,9 +167,10 @@ public static Publisher<?> invokeSuspendingFunction(
private static Object box(KClass<?> kClass, @Nullable Object arg) {
KFunction<?> constructor = Objects.requireNonNull(KClasses.getPrimaryConstructor(kClass));
KType type = constructor.getParameters().get(0).getType();
if (!type.isMarkedNullable() &&
if (!(type.isMarkedNullable() && arg == null) &&
type.getClassifier() instanceof KClass<?> parameterClass &&
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass))) {
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass)) &&
!JvmClassMappingKt.getJavaClass(parameterClass).isInstance(arg)) {
arg = box(parameterClass, arg);
}
if (!KCallablesJvm.isAccessible(constructor)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,13 @@ class CoroutinesUtilsTests {
Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo")
}

@Test
suspend fun invokeSuspendingFunctionWithNullableValueClassParameterAndUnderlyingValue() {
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithNullableValueClass") }
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, "foo", null) as Mono
Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo")
}

@Test
suspend fun invokeSuspendingFunctionWithNullableValueClassParameter() {
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithNullableValueClass") }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,10 @@ private static class KotlinDelegate {
Object arg = args[index];
if (!(parameter.isOptional() && arg == null)) {
KType type = parameter.getType();
if (!type.isMarkedNullable() &&
if (!(type.isMarkedNullable() && arg == null) &&
type.getClassifier() instanceof KClass<?> kClass &&
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass))) {
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass)) &&
!JvmClassMappingKt.getJavaClass(kClass).isInstance(arg)) {
arg = box(kClass, arg);
}
argMap.put(parameter, arg);
Expand All @@ -337,9 +338,10 @@ private static class KotlinDelegate {
private static Object box(KClass<?> kClass, @Nullable Object arg) {
KFunction<?> constructor = Objects.requireNonNull(KClasses.getPrimaryConstructor(kClass));
KType type = constructor.getParameters().get(0).getType();
if (!type.isMarkedNullable() &&
if (!(type.isMarkedNullable() && arg == null) &&
type.getClassifier() instanceof KClass<?> parameterClass &&
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass))) {
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass)) &&
!JvmClassMappingKt.getJavaClass(parameterClass).isInstance(arg)) {
arg = box(parameterClass, arg);
}
if (!KCallablesJvm.isAccessible(constructor)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ class InvocableHandlerMethodKotlinTests {
Assertions.assertThat(value).isEqualTo(1L)
}

@Test
fun valueClassWithNullableAndUnderlyingValue() {
composite.addResolver(StubArgumentResolver(LongValueClass::class.java, 1L))
val value = getInvocable(ValueClassHandler::valueClassWithNullable.javaMethod!!).invokeForRequest(request, null)
Assertions.assertThat(value).isEqualTo(1L)
}

@Test
fun valueClassWithNullable() {
composite.addResolver(StubArgumentResolver(LongValueClass::class.java, null))
Expand Down Expand Up @@ -215,6 +222,14 @@ class InvocableHandlerMethodKotlinTests {
StepVerifier.create(value as Mono<Long>).verifyComplete()
}

@Test
fun suspendingValueClassWithNullableAndUnderlyingValue() {
composite.addResolver(ContinuationHandlerMethodArgumentResolver())
composite.addResolver(StubArgumentResolver(LongValueClass::class.java, 1L))
val value = getInvocable(SuspendingValueClassHandler::valueClassWithNullable.javaMethod!!).invokeForRequest(request, null)
StepVerifier.create(value as Mono<Long>).expectNext(1L).verifyComplete()
}

@Test
fun suspendingValueClassWithPrivateConstructor() {
composite.addResolver(ContinuationHandlerMethodArgumentResolver())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,10 @@ private static class KotlinDelegate {
Object arg = args[index];
if (!(parameter.isOptional() && arg == null)) {
KType type = parameter.getType();
if (!type.isMarkedNullable() &&
if (!(type.isMarkedNullable() && arg == null) &&
type.getClassifier() instanceof KClass<?> kClass &&
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass))) {
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass)) &&
!JvmClassMappingKt.getJavaClass(kClass).isInstance(arg)) {
arg = box(kClass, arg);
}
argMap.put(parameter, arg);
Expand All @@ -378,9 +379,10 @@ private static class KotlinDelegate {
private static Object box(KClass<?> kClass, @Nullable Object arg) {
KFunction<?> constructor = Objects.requireNonNull(KClasses.getPrimaryConstructor(kClass));
KType type = constructor.getParameters().get(0).getType();
if (!type.isMarkedNullable() &&
if (!(type.isMarkedNullable() && arg == null) &&
type.getClassifier() instanceof KClass<?> parameterClass &&
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass))) {
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass)) &&
!JvmClassMappingKt.getJavaClass(parameterClass).isInstance(arg)) {
arg = box(parameterClass, arg);
}
if (!KCallablesJvm.isAccessible(constructor)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,14 @@ class InvocableHandlerMethodKotlinTests {
assertHandlerResultValue(result, "1")
}

@Test
fun valueClassWithNullableAndUnderlyingValue() {
this.resolvers.add(stubResolver(1L, LongValueClass::class.java))
val method = ValueClassController::valueClassWithNullable.javaMethod!!
val result = invoke(ValueClassController(), method)
assertHandlerResultValue(result, "1")
}

@Test
fun valueClassWithNullable() {
this.resolvers.add(stubResolver(null, LongValueClass::class.java))
Expand Down Expand Up @@ -320,6 +328,14 @@ class InvocableHandlerMethodKotlinTests {
assertHandlerResultValue(result, "null")
}

@Test
fun suspendingValueClassWithNullableAndUnderlyingValue() {
this.resolvers.add(stubResolver(1L, LongValueClass::class.java))
val method = SuspendingValueClassController::valueClassWithNullable.javaMethod!!
val result = invoke(SuspendingValueClassController(), method)
assertHandlerResultValue(result, "1")
}

@Test
fun suspendingValueClassWithPrivateConstructor() {
this.resolvers.add(stubResolver(1L, Long::class.java))
Expand Down Expand Up @@ -590,4 +606,4 @@ class InvocableHandlerMethodKotlinTests {
}

class CustomException(message: String) : Throwable(message)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() {
assertThat(entity.body).isEqualTo("foobar")
}


@Configuration
@EnableWebFlux
@ComponentScan(resourcePattern = "**/CoroutinesIntegrationTests*")
Expand Down Expand Up @@ -207,7 +206,6 @@ class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() {
}
return ResponseEntity.ok().body(strings)
}

}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright 2002-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.web.reactive.result.method.annotation

import kotlinx.coroutines.delay
import org.assertj.core.api.Assertions.assertThat
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.reactive.config.EnableWebFlux
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer
import java.util.UUID

class CoroutinesValueClassIntegrationTest : AbstractRequestMappingIntegrationTests() {

override fun initApplicationContext(): ApplicationContext {
val context = AnnotationConfigApplicationContext()
context.register(WebConfig::class.java)
context.refresh()
return context
}


@ParameterizedHttpServerTest
fun `Suspending handler method with nullable value class request param`(httpServer: HttpServer) {
startServer(httpServer)

val entity = performGet("/suspend-value-class?value=550e8400-e29b-41d4-a716-446655440000", HttpHeaders.EMPTY, String::class.java)
assertThat(entity.statusCode).isEqualTo(HttpStatus.OK)
assertThat(entity.body).isEqualTo("550e8400-e29b-41d4-a716-446655440000")
}

@ParameterizedHttpServerTest
fun `Suspending handler method with nullable value class request param omitted`(httpServer: HttpServer) {
startServer(httpServer)

val entity = performGet("/suspend-value-class", HttpHeaders.EMPTY, String::class.java)
assertThat(entity.statusCode).isEqualTo(HttpStatus.OK)
assertThat(entity.body).isEqualTo("outer-null")
}

@ParameterizedHttpServerTest
fun `Suspending handler method with non-optional nullable inner value class request param`(httpServer: HttpServer) {
startServer(httpServer)

val entity = performGet("/suspend-nullable-inner-value-class", HttpHeaders.EMPTY, String::class.java)
assertThat(entity.statusCode).isEqualTo(HttpStatus.OK)
assertThat(entity.body).isEqualTo("inner-null")
}

@ParameterizedHttpServerTest
fun `Suspending handler method with optional nullable inner value class request param`(httpServer: HttpServer) {
startServer(httpServer)

val entity = performGet("/suspend-nullable-inner-value-class-optional", HttpHeaders.EMPTY, String::class.java)
assertThat(entity.statusCode).isEqualTo(HttpStatus.OK)
assertThat(entity.body).isEqualTo("outer-null")
}


@Configuration
@EnableWebFlux
@ComponentScan(resourcePattern = "**/CoroutinesValueClassIntegrationTest*")
open class WebConfig

@RestController
class CoroutinesController {

@GetMapping("/suspend-value-class")
suspend fun suspendingValueClassEndpoint(@RequestParam value: ValueClass?): String {
delay(1)
return when (value) {
null -> "outer-null"
else -> value.value.toString()
}
}

@GetMapping("/suspend-nullable-inner-value-class")
suspend fun suspendingNullableInnerValueClassEndpoint(
@RequestParam(required = false) value: NullableInnerValueClass
): String {
delay(1)
return if (value.value == null) "inner-null" else value.value.toString()
}

@GetMapping("/suspend-nullable-inner-value-class-optional")
suspend fun suspendingOptionalNullableInnerValueClassEndpoint(
@RequestParam(required = false) value: NullableInnerValueClass?
): String {
delay(1)
return when {
value == null -> "outer-null"
value.value == null -> "inner-null"
else -> value.value.toString()
}
}
}

@JvmInline
value class ValueClass(val value: UUID)

@JvmInline
value class NullableInnerValueClass(val value: UUID?)

}
Loading