Skip to content

Commit

Permalink
Support invoking bridged suspending functions in AopUtils
Browse files Browse the repository at this point in the history
  • Loading branch information
sdeleuze committed Aug 12, 2024
1 parent f4a73b7 commit 1911ca7
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,10 @@ public static Object invokeJoinpointUsingReflection(@Nullable Object target, Met

// Use reflection to invoke the method.
try {
ReflectionUtils.makeAccessible(method);
return (coroutinesReactorPresent && KotlinDetector.isSuspendingFunction(method) ?
KotlinDelegate.invokeSuspendingFunction(method, target, args) : method.invoke(target, args));
Method originalMethod = BridgeMethodResolver.findBridgedMethod(method);
ReflectionUtils.makeAccessible(originalMethod);
return (coroutinesReactorPresent && KotlinDetector.isSuspendingFunction(originalMethod) ?
KotlinDelegate.invokeSuspendingFunction(originalMethod, target, args) : originalMethod.invoke(target, args));
}
catch (InvocationTargetException ex) {
// Invoked method threw a checked exception.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
Expand Down Expand Up @@ -34,19 +34,48 @@ class AopUtilsKotlinTests {
@Test
fun `Invoking suspending function should return Mono`() {
val value = "foo"
val method = ReflectionUtils.findMethod(AopUtilsKotlinTests::class.java, "suspendingFunction",
String::class.java, Continuation::class.java)!!
val method = ReflectionUtils.findMethod(WithoutInterface::class.java, "handle",
String::class. java, Continuation::class.java)!!
val continuation = Continuation<Any>(CoroutineName("test")) { }
val result = AopUtils.invokeJoinpointUsingReflection(this, method, arrayOf(value, continuation))
val result = AopUtils.invokeJoinpointUsingReflection(WithoutInterface(), method, arrayOf(value, continuation))
assertThat(result).isInstanceOfSatisfying(Mono::class.java) {
assertThat(it.block()).isEqualTo(value)
}
}

@Test
fun `Invoking suspending function on bridged method should return Mono`() {
val value = "foo"
val bridgedMethod = ReflectionUtils.findMethod(WithInterface::class.java, "handle", Object::class.java, Continuation::class.java)!!
val continuation = Continuation<Any>(CoroutineName("test")) { }
val result = AopUtils.invokeJoinpointUsingReflection(WithInterface(), bridgedMethod, arrayOf(value, continuation))
assertThat(result).isInstanceOfSatisfying(Mono::class.java) {
assertThat(it.block()).isEqualTo(value)
}
}

@Suppress("unused")
suspend fun suspendingFunction(value: String): String {
delay(1)
return value
}

class WithoutInterface {
suspend fun handle(value: String): String {
delay(1)
return value
}
}

interface ProxyInterface<T> {
suspend fun handle(value: T): T
}

class WithInterface : ProxyInterface<String> {
override suspend fun handle(value: String): String {
delay(1)
return value
}
}

}

0 comments on commit 1911ca7

Please sign in to comment.