Skip to content

Commit 107f88a

Browse files
Tom van den Bergesdeleuze
authored andcommitted
Allow non-public Kotlin classes/ctors to be instantiated
Closes gh-24712
1 parent 831a951 commit 107f88a

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import kotlin.reflect.KFunction;
3939
import kotlin.reflect.KParameter;
4040
import kotlin.reflect.full.KClasses;
41+
import kotlin.reflect.jvm.KCallablesJvm;
4142
import kotlin.reflect.jvm.ReflectJvmMapping;
4243
import org.apache.commons.logging.Log;
4344
import org.apache.commons.logging.LogFactory;
@@ -780,6 +781,11 @@ public static <T> T instantiateClass(Constructor<T> ctor, Object... args)
780781
if (kotlinConstructor == null) {
781782
return ctor.newInstance(args);
782783
}
784+
785+
if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers()))) {
786+
KCallablesJvm.setAccessible(kotlinConstructor, true);
787+
}
788+
783789
List<KParameter> parameters = kotlinConstructor.getParameters();
784790
Map<KParameter, Object> argParameters = new HashMap<>(parameters.size());
785791
Assert.isTrue(args.length <= parameters.size(),

spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ void testInstantiateClassWithMoreArgsThanParameters() throws NoSuchMethodExcepti
9595
BeanUtils.instantiateClass(ctor, null, null, "foo", null));
9696
}
9797

98+
@Test
99+
void testInstantiatePrivateClassWithPrivateConstructor() throws NoSuchMethodException {
100+
Constructor<PrivateBeanWithPrivateConstructor> ctor = PrivateBeanWithPrivateConstructor.class.getDeclaredConstructor();
101+
BeanUtils.instantiateClass(ctor);
102+
}
103+
98104
@Test
99105
void testGetPropertyDescriptors() throws Exception {
100106
PropertyDescriptor[] actual = Introspector.getBeanInfo(TestBean.class).getPropertyDescriptors();
@@ -555,4 +561,10 @@ public String getValue() {
555561
}
556562
}
557563

564+
private static class PrivateBeanWithPrivateConstructor {
565+
566+
private PrivateBeanWithPrivateConstructor() {
567+
}
568+
}
569+
558570
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,22 @@ class KotlinBeanUtilsTests {
7474
assertThat(baz.param2).isEqualTo(12)
7575
}
7676

77+
@Test
78+
@Suppress("UsePropertyAccessSyntax")
79+
fun `Instantiate class with private constructor`() {
80+
BeanUtils.instantiateClass(PrivateConstructor::class.java.getDeclaredConstructor())
81+
}
82+
83+
@Test
84+
fun `Instantiate class with protected constructor`() {
85+
BeanUtils.instantiateClass(ProtectedConstructor::class.java.getDeclaredConstructor())
86+
}
87+
88+
@Test
89+
fun `Instantiate private class`() {
90+
BeanUtils.instantiateClass(PrivateClass::class.java.getDeclaredConstructor())
91+
}
92+
7793
class Foo(val param1: String, val param2: Int)
7894

7995
class Bar(val param1: String, val param2: Int = 12)
@@ -106,4 +122,10 @@ class KotlinBeanUtilsTests {
106122
constructor(param1: String)
107123
}
108124

125+
class PrivateConstructor private constructor()
126+
127+
open class ProtectedConstructor protected constructor()
128+
129+
private class PrivateClass
130+
109131
}

0 commit comments

Comments
 (0)