9

I wrote a simple spring integration application that moves files from one directory to another, it looks like this:

@Bean
@InboundChannelAdapter(value="requestChannel", poller = @Poller(fixedDelay="100"))
public FileReadingMessageSource adapter(){
    FileReadingMessageSource source = new FileReadingMessageSource();
    source.setDirectory(new File("D:/TestIn"));
    return source;

}

@Bean 
MessageChannel requestChannel(){
    return new DirectChannel();
}

@Bean
@ServiceActivator(inputChannel="requestChannel")
public FileWritingMessageHandler handle(){
    FileWritingMessageHandler handler = new FileWritingMessageHandler(new File("D:/TestOut"));
    handler.setDeleteSourceFiles(true);
    return handler;
}

It works perfectly well, but every copy operation gives me this exception

    2015-03-26 09:56:39.222  INFO 4772 --- [ask-scheduler-5] o.s.i.file.FileReadingMessageSource      : Created message: [GenericMessage [payload=D:\TestIn\9.txt, headers={id=d8b27257-0a90-b7ad-65cb-85e93668fb5a, timestamp=1427360199222}]]
2015-03-26 09:56:39.223 ERROR 4772 --- [ask-scheduler-5] o.s.integration.handler.LoggingHandler   : org.springframework.messaging.MessagingException: ; nested exception is org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
    at org.springframework.integration.dispatcher.AbstractDispatcher.wrapExceptionIfNecessary(AbstractDispatcher.java:133)

I read in another topic that this happens when you filter out the headers somewhere in your code, but the first line of this trace tells me, that the only headers generated are id and timestamp.

Blue
  • 601
  • 2
  • 8
  • 19

1 Answers1

8

Everything looks good, but no: you don't face the filter out the headers somewhere issue.

That's just because FileWritingMessageHandler is request/reply by default.

To achieve you just move requirement you should add this:

handler.setExpectReply(false);

The code from that components looks like:

if (!this.expectReply) {
    return null;
}

if (resultFile != null) {
    if (originalFileFromHeader == null && payload instanceof File) {
        return this.getMessageBuilderFactory().withPayload(resultFile)
                    .setHeader(FileHeaders.ORIGINAL_FILE, payload);
    }
}
return resultFile;

So, it tries to send resultFile to the outputChannel of the endpoint for that @ServiceActivator. Since you don't have such an option and there is no replyChannel header you end up with that Exception.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Where do I catch the 'expected reply' or the exceptions that are raised? – Fatmajk Apr 17 '18 at 13:43
  • Sounds like a new SO question? Sorry, need more context. Shortly: in most cases Spring Integration is just Java. So, you catch an exception from the code which call it. – Artem Bilan Apr 17 '18 at 13:47
  • Yeah I could, but I thought it was related to this. With the Handler.setExpectReply(true) I can read this from the documentation: "Specify whether the handle method should be expected to return a reply. The default is 'true'.". But since the method is using 'Bean' and 'ServiceActivator' annotations, where do I catch the returned Reply? – Fatmajk Apr 17 '18 at 13:51
  • The `@ServiceActivator` has an `outputChannel` attribute. New SO question would really be better: community get a problem and a solution for it; the person who answers gets a reputation. Everyone is winning – Artem Bilan Apr 17 '18 at 13:56
  • New question up: https://stackoverflow.com/questions/49880845/handle-expected-return-from-spring-integration-file – Fatmajk Apr 17 '18 at 14:31