diff --git a/spring-context/spring-context.gradle b/spring-context/spring-context.gradle index 5f5ac1001e..04d4e1e8c7 100644 --- a/spring-context/spring-context.gradle +++ b/spring-context/spring-context.gradle @@ -36,6 +36,7 @@ dependencies { testImplementation("org.apache.commons:commons-pool2") testImplementation("org.awaitility:awaitility") testImplementation("jakarta.inject:jakarta.inject-tck") + testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core") testRuntimeOnly("jakarta.xml.bind:jakarta.xml.bind-api") testRuntimeOnly("org.glassfish:jakarta.el") // Substitute for javax.management:jmxremote_optional:1.0.1_04 (not available on Maven Central) diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java index 827ee3fd89..6a0f939c4f 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 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. @@ -49,8 +49,6 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.MessageSource; -import org.springframework.core.KotlinDetector; -import org.springframework.core.KotlinReflectionParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; @@ -75,6 +73,7 @@ import org.springframework.util.ReflectionUtils; * {@code jakarta.validation} API being present but no explicit Validator having been configured. * * @author Juergen Hoeller + * @author Sebastien Deleuze * @since 3.0 * @see jakarta.validation.ValidatorFactory * @see jakarta.validation.Validator @@ -118,13 +117,6 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter private ValidatorFactory validatorFactory; - public LocalValidatorFactoryBean() { - if (KotlinDetector.isKotlinReflectPresent()) { - this.parameterNameDiscoverer = new KotlinReflectionParameterNameDiscoverer(); - } - } - - /** * Specify the desired provider class, if any. *
If not specified, JSR-303's default search mechanism will be used. @@ -196,9 +188,8 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter /** * Set the ParameterNameDiscoverer to use for resolving method and constructor * parameter names if needed for message interpolation. - *
Default is Hibernate Validator's own internal use of standard Java reflection, - * with an additional {@link KotlinReflectionParameterNameDiscoverer} if Kotlin - * is present. This may be overridden with a custom subclass or a Spring-controlled + *
Default is Hibernate Validator's own internal use of standard Java reflection.
+ * This may be overridden with a custom subclass or a Spring-controlled
* {@link org.springframework.core.DefaultParameterNameDiscoverer} if necessary.
*/
public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) {
diff --git a/spring-context/src/test/kotlin/org/springframework/validation/beanvalidation/KotlinMethodValidationTests.kt b/spring-context/src/test/kotlin/org/springframework/validation/beanvalidation/KotlinMethodValidationTests.kt
new file mode 100644
index 0000000000..ba3b6f93f5
--- /dev/null
+++ b/spring-context/src/test/kotlin/org/springframework/validation/beanvalidation/KotlinMethodValidationTests.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2002-2023 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.validation.beanvalidation
+
+import jakarta.validation.ValidationException
+import jakarta.validation.Validator
+import jakarta.validation.constraints.NotEmpty
+import kotlinx.coroutines.runBlocking
+import org.assertj.core.api.Assertions
+import org.junit.jupiter.api.Test
+import org.springframework.aop.framework.ProxyFactory
+import org.springframework.validation.annotation.Validated
+
+/**
+ * Kotlin tests for [MethodValidationInterceptor] + [LocalValidatorFactoryBean].
+ *
+ * @author Sebastien Deleuze
+ */
+@Suppress("UsePropertyAccessSyntax")
+class KotlinMethodValidationTests {
+
+ @Test
+ fun parameterValidation() {
+ val bean = MyValidBean()
+ val proxyFactory = ProxyFactory(bean)
+ val validator = LocalValidatorFactoryBean()
+ validator.afterPropertiesSet()
+ proxyFactory.addAdvice(MethodValidationInterceptor(validator as Validator))
+ val proxy = proxyFactory.getProxy() as MyValidBean
+ Assertions.assertThat(proxy.validName("name")).isEqualTo("name")
+ Assertions.assertThatExceptionOfType(ValidationException::class.java).isThrownBy {
+ proxy.validName("")
+ }
+ }
+
+ @Test
+ fun coroutinesParameterValidation() = runBlocking