Reynaldo Reynaldo - 24 days ago 10
Java Question

Why do I get an unexpected RuntimeException warn in the logs when using RemoteFileTemplate?

I'm using Spring-integration 4.1.1.RELEASE and have code that uploads files in message payloads to a remote sFtp share. I'm using an sFtpRemoteFileTemplate initialized like this:

Expression remoteDirectoryExpression = new LiteralExpression("si.sftp.sample");
SpelExpressionParser parser = new SpelExpressionParser();
Expression fileNameExpression = parser.parseExpression("payload.name");

template = new SftpRemoteFileTemplate(sessionFactory);
template.setCharset("UTF-8");
template.setBeanFactory(beanFactory);
template.setAutoCreateDirectory(true);
template.setRemoteDirectoryExpression(remoteDirectoryExpression);
template.setFileNameExpression(fileNameExpression);
template.setTemporaryFileSuffix(".writing");
template.setUseTemporaryFileName(true);


However when running the code, this warning appears in my log files - once for each expression in the template:

WARN - o.s.i.e.ExpressionUtils: Creating EvaluationContext with no beanFactory
java.lang.RuntimeException: No beanfactory
at org.springframework.integration.expression.ExpressionUtils.createStandardEvaluationContext(ExpressionUtils.java:79) [spring-integration-core-4.1.1.RELEASE.jar:na]
at org.springframework.integration.util.AbstractExpressionEvaluator.getEvaluationContext(AbstractExpressionEvaluator.java:114) [spring-integration-core-4.1.1.RELEASE.jar:na]
at org.springframework.integration.util.AbstractExpressionEvaluator.getEvaluationContext(AbstractExpressionEvaluator.java:100) [spring-integration-core-4.1.1.RELEASE.jar:na]
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:164) [spring-integration-core-4.1.1.RELEASE.jar:na]
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:123) [spring-integration-core-4.1.1.RELEASE.jar:na]
at org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor.processMessage(ExpressionEvaluatingMessageProcessor.java:72) [spring-integration-core-4.1.1.RELEASE.jar:na]


Why is that? I haven't managed to get rid of it, and my suspicion is that the Bean Factory instance is not delegated to the ExpressionEvaluatingMessageProcessor inside RemoteFileTemplate (The calling class has implemented BeanFactoryAware and I've verified the beanFactory field is populated properly). I've created a test case for it, where I've managed to reproduce it.

@Test
public void shouldUploadFile() throws Exception
{
Message<File> msg = MessageBuilder
.withPayload(Fixture.getFile())
.build();

final String remoteDir = template.send(msg);
org.junit.Assert.assertNotNull("remote file must exist", remoteDir);
logger.info("uploaded file: \'{}\'", remoteDir);
SftpTestUtils.cleanUp(template, Fixture.getFileName());
}


It shouldn't be a problem with the ExpressionEvaluatingMessageProcessor, as this test case passes without warnings under the same context:

@Test
public void shouldTestProcessor()
{
SpelExpressionParser parser = new SpelExpressionParser();
Expression fileNameExpression = parser.parseExpression("payload.name");
ExpressionEvaluatingMessageProcessor<String> fileNameProcessor = new ExpressionEvaluatingMessageProcessor<String>(
fileNameExpression, String.class);
fileNameProcessor.setBeanFactory(beanFactory);
Message<File> message = MessageBuilder.withPayload(Fixture.getFile()).build();
String fileName = fileNameProcessor.processMessage(message);
org.junit.Assert.assertEquals("filename is not as expected", Fixture.getFileName(), fileName);
logger.info("generated fileName: \'{}\'", fileName);
}


Any clues?

Answer

You need to invoke afterPropertiesSet() to finalize the initialization of the RFT when constructing it outside of a Spring ApplicationContext.

This is true for many Spring Integration components.

Those that implement Lifecycle (not RFT) may also need to be start()ed.

Comments