GH-3079: Use getMostSpecificMethod for SpEL calls (#3082)

* GH-3079: Use getMostSpecificMethod for SpEL calls

Fixes https://github.com/spring-projects/spring-integration/issues/3079

It turns out that we need to use a *most specific* method for the target
to be called reflectively from the SpEL

NOTE: We drop a *Method not found* error in case of wrong method source
since now we find a right source via `ClassUtils.getMostSpecificMethod()`

**Cherry-pick to 5.1.x**

* * `@Ignore` `MethodInvokingMessageProcessorTests.testProcessMessageMethodNotFound()`
instead of removal
This commit is contained in:
Artem Bilan
2019-10-16 15:57:33 -04:00
committed by Gary Russell
parent 87af95ee7a
commit 33667884a7
3 changed files with 16 additions and 4 deletions

View File

@@ -417,7 +417,8 @@ public class MessagingMethodInvokerHelper extends AbstractExpressionEvaluator im
StandardEvaluationContext context = getEvaluationContext();
Class<?> targetType = AopUtils.getTargetClass(this.targetObject);
if (this.method != null) {
context.registerMethodFilter(targetType, new FixedMethodFilter(this.method));
context.registerMethodFilter(targetType,
new FixedMethodFilter(ClassUtils.getMostSpecificMethod(this.method, targetType)));
if (this.expectedType != null) {
Assert.state(context.getTypeConverter()
.canConvert(TypeDescriptor.valueOf((this.method).getReturnType()), this.expectedType),

View File

@@ -74,6 +74,7 @@ import org.springframework.integration.store.MessageStore;
import org.springframework.integration.store.SimpleMessageStore;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.support.MutableMessageBuilder;
import org.springframework.integration.transformer.GenericTransformer;
import org.springframework.integration.transformer.PayloadSerializingTransformer;
import org.springframework.integration.util.NoBeansOverrideAnnotationConfigContextLoader;
import org.springframework.messaging.Message;
@@ -362,10 +363,10 @@ public class IntegrationFlowTests {
assertThat(out).isNotNull();
assertThat(out.getPayload()).isEqualTo("bar");
this.tappedChannel5.send(new GenericMessage<>("foo"));
this.tappedChannel5.send(new GenericMessage<>(""));
out = this.wireTapSubflowResult.receive(10000);
assertThat(out).isNotNull();
assertThat(out.getPayload()).isEqualTo("FOO");
assertThat(out.getPayload()).isEqualTo("");
}
@Autowired
@@ -700,7 +701,15 @@ public class IntegrationFlowTests {
public IntegrationFlow wireTapFlow5() {
return f -> f
.wireTap(sf -> sf
.<String, String>transform(String::toUpperCase)
.transform(// Must not be lambda for SpEL fallback behavior on empty payload
new GenericTransformer<String, String>() {
@Override
public String transform(String source) {
return source.toUpperCase();
}
})
.channel(MessageChannels.queue("wireTapSubflowResult")))
.channel("nullChannel");
}

View File

@@ -42,6 +42,7 @@ import java.util.stream.Collectors;
import org.aopalliance.intercept.MethodInterceptor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
@@ -451,6 +452,7 @@ public class MethodInvokingMessageProcessorTests {
}
@Test
@Ignore("See https://github.com/spring-projects/spring-framework/issues/23824")
public void testProcessMessageMethodNotFound() throws Exception {
TestDifferentErrorService service = new TestDifferentErrorService();
Method method = TestErrorService.class.getMethod("checked", String.class);