Skip to content

Commit 0e67fbc

Browse files
committed
Merge branch '3.0.x'
Closes gh-34174
2 parents 12537c7 + a0de59c commit 0e67fbc

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/BindableRuntimeHintsRegistrar.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
import java.util.Set;
2828
import java.util.stream.StreamSupport;
2929

30+
import kotlin.jvm.JvmClassMappingKt;
31+
import kotlin.reflect.KClass;
32+
3033
import org.springframework.aot.hint.ExecutableMode;
34+
import org.springframework.aot.hint.MemberCategory;
3135
import org.springframework.aot.hint.ReflectionHints;
3236
import org.springframework.aot.hint.RuntimeHints;
3337
import org.springframework.aot.hint.RuntimeHintsRegistrar;
@@ -163,7 +167,12 @@ else if (!ObjectUtils.isEmpty(this.propertyDescriptors)) {
163167
private void handleConstructor(ReflectionHints hints) {
164168
if (this.bindConstructor != null) {
165169
verifyParameterNamesAreAvailable();
166-
hints.registerConstructor(this.bindConstructor, ExecutableMode.INVOKE);
170+
if (KotlinDetector.isKotlinType(this.bindConstructor.getDeclaringClass())) {
171+
KotlinDelegate.handleConstructor(hints, this.bindConstructor);
172+
}
173+
else {
174+
hints.registerConstructor(this.bindConstructor, ExecutableMode.INVOKE);
175+
}
167176
return;
168177
}
169178
Arrays.stream(this.type.getDeclaredConstructors()).filter(this::hasNoParameters).findFirst()
@@ -302,4 +311,21 @@ private boolean isJavaType(Class<?> candidate) {
302311

303312
}
304313

314+
/**
315+
* Inner class to avoid a hard dependency on Kotlin at runtime.
316+
*/
317+
private static class KotlinDelegate {
318+
319+
static void handleConstructor(ReflectionHints hints, Constructor<?> constructor) {
320+
KClass<?> kClass = JvmClassMappingKt.getKotlinClass(constructor.getDeclaringClass());
321+
if (kClass.isData()) {
322+
hints.registerType(constructor.getDeclaringClass(), MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
323+
}
324+
else {
325+
hints.registerConstructor(constructor, ExecutableMode.INVOKE);
326+
}
327+
}
328+
329+
}
330+
305331
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2012-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.context.properties.bind
18+
19+
import org.assertj.core.api.Assertions.assertThat
20+
import org.junit.jupiter.api.Test
21+
import org.springframework.aot.hint.MemberCategory
22+
import org.springframework.aot.hint.RuntimeHints
23+
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates
24+
25+
26+
/**
27+
* Tests for {@link BindableRuntimeHintsRegistrar}.
28+
*
29+
* @author Andy Wilkinsin
30+
*/
31+
class KotlinBindableRuntimeHintsRegistrarTests {
32+
33+
@Test
34+
fun `registerHints for data class with default value should allow declared constructors to be invoked`() {
35+
val runtimeHints = RuntimeHints()
36+
val register = BindableRuntimeHintsRegistrar.forTypes(PropertyWithDefaultValue::class.java)
37+
register.registerHints(runtimeHints)
38+
assertThat(runtimeHints.reflection().typeHints()).hasSize(1)
39+
assertThat(runtimeHints.reflection().typeHints()).allSatisfy { hint ->
40+
assertThat(hint.memberCategories).containsExactly(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)
41+
}
42+
}
43+
44+
data class PropertyWithDefaultValue(var a: String = "alpha")
45+
}

0 commit comments

Comments
 (0)