Skip to content

Commit 23696b7

Browse files
committed
Add a classpath check for AOP Coroutines/Reactive conversion
Closes gh-32599
1 parent 7b7cfb2 commit 23696b7

File tree

3 files changed

+13
-5
lines changed

3 files changed

+13
-5
lines changed

spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ class CglibAopProxy implements AopProxy, Serializable {
102102

103103
private static final String COROUTINES_FLOW_CLASS_NAME = "kotlinx.coroutines.flow.Flow";
104104

105+
private static final boolean coroutinesReactorPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt",
106+
CglibAopProxy.class.getClassLoader());;
107+
105108

106109
/** The configuration used to configure this proxy. */
107110
protected final AdvisedSupport advised;
@@ -421,7 +424,7 @@ private static Object processReturnType(
421424
throw new AopInvocationException(
422425
"Null return value from advice does not match primitive return type for: " + method);
423426
}
424-
if (KotlinDetector.isSuspendingFunction(method)) {
427+
if (coroutinesReactorPresent && KotlinDetector.isSuspendingFunction(method)) {
425428
return COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, -1).getParameterType().getName()) ?
426429
CoroutinesUtils.asFlow(returnValue) :
427430
CoroutinesUtils.awaitSingleOrNull(returnValue, arguments[arguments.length - 1]);

spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
7575

7676
private static final String COROUTINES_FLOW_CLASS_NAME = "kotlinx.coroutines.flow.Flow";
7777

78+
private static final boolean coroutinesReactorPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt",
79+
JdkDynamicAopProxy.class.getClassLoader());;
80+
7881
/** We use a static Log to avoid serialization issues. */
7982
private static final Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
8083

@@ -234,7 +237,7 @@ else if (retVal == null && returnType != void.class && returnType.isPrimitive())
234237
throw new AopInvocationException(
235238
"Null return value from advice does not match primitive return type for: " + method);
236239
}
237-
if (KotlinDetector.isSuspendingFunction(method)) {
240+
if (coroutinesReactorPresent && KotlinDetector.isSuspendingFunction(method)) {
238241
return COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, -1).getParameterType().getName()) ?
239242
CoroutinesUtils.asFlow(retVal) : CoroutinesUtils.awaitSingleOrNull(retVal, args[args.length - 1]);
240243
}

spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import kotlin.coroutines.Continuation;
2929
import kotlin.coroutines.CoroutineContext;
3030
import kotlinx.coroutines.Job;
31-
import org.reactivestreams.Publisher;
3231

3332
import org.springframework.aop.Advisor;
3433
import org.springframework.aop.AopInvocationException;
@@ -65,6 +64,9 @@
6564
*/
6665
public abstract class AopUtils {
6766

67+
private static final boolean coroutinesReactorPresent = ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt",
68+
AopUtils.class.getClassLoader());;
69+
6870
/**
6971
* Check whether the given object is a JDK dynamic proxy or a CGLIB proxy.
7072
* <p>This method additionally checks if the given object is an instance
@@ -347,7 +349,7 @@ public static Object invokeJoinpointUsingReflection(@Nullable Object target, Met
347349
// Use reflection to invoke the method.
348350
try {
349351
ReflectionUtils.makeAccessible(method);
350-
return KotlinDetector.isSuspendingFunction(method) ?
352+
return coroutinesReactorPresent && KotlinDetector.isSuspendingFunction(method) ?
351353
KotlinDelegate.invokeSuspendingFunction(method, target, args) : method.invoke(target, args);
352354
}
353355
catch (InvocationTargetException ex) {
@@ -370,7 +372,7 @@ public static Object invokeJoinpointUsingReflection(@Nullable Object target, Met
370372
*/
371373
private static class KotlinDelegate {
372374

373-
public static Publisher<?> invokeSuspendingFunction(Method method, @Nullable Object target, Object... args) {
375+
public static Object invokeSuspendingFunction(Method method, @Nullable Object target, Object... args) {
374376
Continuation<?> continuation = (Continuation<?>) args[args.length -1];
375377
Assert.state(continuation != null, "No Continuation available");
376378
CoroutineContext context = continuation.getContext().minusKey(Job.Key);

0 commit comments

Comments
 (0)