Skip to content

Commit 8eb618b

Browse files
committed
Make Kotlin functions accessible in CoroutinesUtils
In order to allow using private classes like in Java for example. Closes gh-23840
1 parent 2f78abd commit 8eb618b

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
2525
import kotlin.reflect.KClassifier;
2626
import kotlin.reflect.KFunction;
2727
import kotlin.reflect.full.KCallables;
28+
import kotlin.reflect.jvm.KCallablesJvm;
2829
import kotlin.reflect.jvm.ReflectJvmMapping;
2930
import kotlinx.coroutines.BuildersKt;
3031
import kotlinx.coroutines.CoroutineStart;
@@ -70,6 +71,9 @@ public static <T> Deferred<T> monoToDeferred(Mono<T> source) {
7071
*/
7172
public static Publisher<?> invokeSuspendingFunction(Method method, Object target, Object... args) {
7273
KFunction<?> function = Objects.requireNonNull(ReflectJvmMapping.getKotlinFunction(method));
74+
if (method.isAccessible() && !KCallablesJvm.isAccessible(function)) {
75+
KCallablesJvm.setAccessible(function, true);
76+
}
7377
KClassifier classifier = function.getReturnType().getClassifier();
7478
Mono<Object> mono = MonoKt.mono(Dispatchers.getUnconfined(), (scope, continuation) ->
7579
KCallables.callSuspend(function, getSuspendedFunctionArgs(target, args), continuation))

spring-webflux/src/test/kotlin/org/springframework/web/reactive/result/KotlinInvocableHandlerMethodTests.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -97,6 +97,14 @@ class KotlinInvocableHandlerMethodTests {
9797
assertThat(this.exchange.response.headers.getFirst("foo")).isEqualTo("bar")
9898
}
9999

100+
@Test
101+
fun privateController() {
102+
this.resolvers.add(stubResolver("foo"))
103+
val method = PrivateCoroutinesController::singleArg.javaMethod!!
104+
val result = invoke(PrivateCoroutinesController(), method,"foo")
105+
assertHandlerResultValue(result, "success:foo")
106+
}
107+
100108
private fun invoke(handler: Any, method: Method, vararg providedArgs: Any?): Mono<HandlerResult> {
101109
val invocable = InvocableHandlerMethod(handler, method)
102110
invocable.setArgumentResolvers(this.resolvers)
@@ -146,7 +154,13 @@ class KotlinInvocableHandlerMethodTests {
146154
delay(10)
147155
response.headers.add("foo", "bar")
148156
}
157+
}
149158

159+
private class PrivateCoroutinesController {
150160

161+
suspend fun singleArg(q: String?): String {
162+
delay(10)
163+
return "success:$q"
164+
}
151165
}
152166
}

0 commit comments

Comments
 (0)