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 86f0ca2199
commit 80ed25ebf3
3 changed files with 17 additions and 4 deletions

View File

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

View File

@@ -83,6 +83,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;
@@ -386,10 +387,10 @@ public class IntegrationFlowTests {
assertNotNull(out);
assertEquals("bar", out.getPayload());
this.tappedChannel5.send(new GenericMessage<>("foo"));
this.tappedChannel5.send(new GenericMessage<>(""));
out = this.wireTapSubflowResult.receive(10000);
assertNotNull(out);
assertEquals("FOO", out.getPayload());
assertEquals("", out.getPayload());
}
@Autowired
@@ -724,7 +725,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

@@ -51,6 +51,7 @@ import org.apache.commons.logging.LogFactory;
import org.hamcrest.Description;
import org.hamcrest.Matchers;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -460,6 +461,7 @@ public class MethodInvokingMessageProcessorTests {
}
@Test
@Ignore("See https://github.com/spring-projects/spring-framework/issues/23824")
public void testProcessMessageMethodNotFound() throws Exception {
expected.expect(new ExceptionCauseMatcher(SpelEvaluationException.class));
TestDifferentErrorService service = new TestDifferentErrorService();