Make Kotlin functions accessible in CoroutinesUtils

In order to allow using private classes like in Java
for example.

Closes gh-23840
This commit is contained in:
Sébastien Deleuze 2022-02-14 10:08:42 +01:00
parent 2f78abd56e
commit 8eb618b480
2 changed files with 20 additions and 2 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@ -25,6 +25,7 @@ import kotlin.jvm.JvmClassMappingKt;
import kotlin.reflect.KClassifier;
import kotlin.reflect.KFunction;
import kotlin.reflect.full.KCallables;
import kotlin.reflect.jvm.KCallablesJvm;
import kotlin.reflect.jvm.ReflectJvmMapping;
import kotlinx.coroutines.BuildersKt;
import kotlinx.coroutines.CoroutineStart;
@ -70,6 +71,9 @@ public abstract class CoroutinesUtils {
*/
public static Publisher<?> invokeSuspendingFunction(Method method, Object target, Object... args) {
KFunction<?> function = Objects.requireNonNull(ReflectJvmMapping.getKotlinFunction(method));
if (method.isAccessible() && !KCallablesJvm.isAccessible(function)) {
KCallablesJvm.setAccessible(function, true);
}
KClassifier classifier = function.getReturnType().getClassifier();
Mono<Object> mono = MonoKt.mono(Dispatchers.getUnconfined(), (scope, continuation) ->
KCallables.callSuspend(function, getSuspendedFunctionArgs(target, args), continuation))

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@ -97,6 +97,14 @@ class KotlinInvocableHandlerMethodTests {
assertThat(this.exchange.response.headers.getFirst("foo")).isEqualTo("bar")
}
@Test
fun privateController() {
this.resolvers.add(stubResolver("foo"))
val method = PrivateCoroutinesController::singleArg.javaMethod!!
val result = invoke(PrivateCoroutinesController(), method,"foo")
assertHandlerResultValue(result, "success:foo")
}
private fun invoke(handler: Any, method: Method, vararg providedArgs: Any?): Mono<HandlerResult> {
val invocable = InvocableHandlerMethod(handler, method)
invocable.setArgumentResolvers(this.resolvers)
@ -146,7 +154,13 @@ class KotlinInvocableHandlerMethodTests {
delay(10)
response.headers.add("foo", "bar")
}
}
private class PrivateCoroutinesController {
suspend fun singleArg(q: String?): String {
delay(10)
return "success:$q"
}
}
}