Skip to content

Commit ef175d7

Browse files
committed
Fix BeanUtils#instantiateClass w/ Kotlin + noarg constructor
Issue: SPR-15851
1 parent f57e558 commit ef175d7

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

spring-beans/src/main/java/org/springframework/beans/BeanUtils.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -734,12 +734,11 @@ public static <T> Constructor<T> findPrimaryConstructor(Class<T> clazz) {
734734
* Instantiate a Kotlin class using the provided constructor.
735735
* @param ctor the constructor of the Kotlin class to instantiate
736736
* @param args the constructor arguments to apply (use null for unspecified parameter if needed)
737-
* @throws BeanInstantiationException if no primary constructor can be found
738737
*/
739-
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) {
738+
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws IllegalAccessException, InvocationTargetException, InstantiationException {
740739
KFunction<T> kotlinConstructor = ReflectJvmMapping.getKotlinFunction(ctor);
741740
if (kotlinConstructor == null) {
742-
throw new BeanInstantiationException(ctor.getDeclaringClass(), "No corresponding Kotlin constructor found");
741+
return ctor.newInstance(args);
743742
}
744743
List<KParameter> parameters = kotlinConstructor.getParameters();
745744
Map<KParameter, Object> argParameters = new HashMap<>(parameters.size());

spring-beans/src/test/kotlin/org/springframework/beans/BeanUtilsKotlinTests.kt

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,37 +29,46 @@ class BeanUtilsKotlinTests {
2929
@Test
3030
fun `Instantiate immutable class`() {
3131
val constructor = BeanUtils.findPrimaryConstructor(Foo::class.java)!!
32-
val foo = BeanUtils.instantiateClass(constructor, "bar", 3)
33-
assertEquals("bar", foo.param1)
32+
val foo = BeanUtils.instantiateClass(constructor, "a", 3)
33+
assertEquals("a", foo.param1)
3434
assertEquals(3, foo.param2)
3535
}
3636

3737
@Test
3838
fun `Instantiate immutable class with optional parameter and all parameters specified`() {
3939
val constructor = BeanUtils.findPrimaryConstructor(Bar::class.java)!!
40-
val bar = BeanUtils.instantiateClass(constructor, "baz", 8)
41-
assertEquals("baz", bar.param1)
40+
val bar = BeanUtils.instantiateClass(constructor, "a", 8)
41+
assertEquals("a", bar.param1)
4242
assertEquals(8, bar.param2)
4343
}
4444

4545
@Test
4646
fun `Instantiate immutable class with optional parameter and only mandatory parameters specified by position`() {
4747
val constructor = BeanUtils.findPrimaryConstructor(Bar::class.java)!!
48-
val bar = BeanUtils.instantiateClass(constructor, "baz")
49-
assertEquals("baz", bar.param1)
48+
val bar = BeanUtils.instantiateClass(constructor, "a")
49+
assertEquals("a", bar.param1)
5050
assertEquals(12, bar.param2)
5151
}
5252

5353
@Test
54-
fun `Instantiate immutable class with optional parameter specified with null value`() {
54+
fun `Instantiate immutable class with optional parameter specified with null value`() {
5555
val constructor = BeanUtils.findPrimaryConstructor(Bar::class.java)!!
56-
val bar = BeanUtils.instantiateClass(constructor, "baz", null)
57-
assertEquals("baz", bar.param1)
56+
val bar = BeanUtils.instantiateClass(constructor, "a", null)
57+
assertEquals("a", bar.param1)
5858
assertEquals(12, bar.param2)
5959
}
6060

61+
@Test // SPR-15851
62+
fun `Instantiate mutable class with declared constructor and default values for all parameters`() {
63+
val baz = BeanUtils.instantiateClass(Baz::class.java.getDeclaredConstructor())
64+
assertEquals("a", baz.param1)
65+
assertEquals(12, baz.param2)
66+
}
67+
6168
class Foo(val param1: String, val param2: Int)
6269

6370
class Bar(val param1: String, val param2: Int = 12)
64-
71+
72+
class Baz(var param1: String = "a", var param2: Int = 12)
73+
6574
}

0 commit comments

Comments
 (0)