Spring 集成 - SpelEvaluationException:'java.lang.String' 和 'null' 类型的对象之间不支持运算符 'ADD'

Spring Integration - SpelEvaluationException: The operator 'ADD' is not supported between objects of type 'java.lang.String' and 'null'

我有一个 Spring batch/integration 作业,它应该轮询 FTP 服务器,获取所有 .txt 文件,使用 Spring 批处理组件转换它们,然后然后将它们放在队列中(使用 ActiveMQ 实现)。但是,我在尝试从 FTP 区域检索文件时遇到此错误:

ERROR [org.springframework.integration.handler.LoggingHandler] - <org.springframework.expression.spel.SpelEvaluationException: EL1030E:(pos 0): The operator 'ADD' is not supported between objects of type 'java.lang.String' and 'null'

相关 spring xml 配置(为清楚起见省略了很多代码):

<beans>

<!-- Spring integration setup -->

   <int:channel id="outboundJobRequestChannel"/>
   <int:channel id="jobLaunchReplyChannel"/>
   <int:channel id="inboundFileChannel"/>

   <batch-int:job-launching-gateway request-channel="outboundJobRequestChannel"
                               reply-channel="jobLaunchReplyChannel"
                               job-launcher="jobLauncher" />

   <int:logging-channel-adapter channel="jobLaunchReplyChannel"/>

   <int:transformer input-channel="ftpChannel"
               output-channel="outboundJobRequestChannel"
               method="toRequest">

       <bean class="package.FileMessageToJobRequest">
         <constructor-arg index="0" ref="myJob" />
         <constructor-arg index="1" value="input.file.name" />
       </bean>
   </int:transformer>  

   <bean id="ftpClientFactory" class="org.springframework.integration.ftp.session.DefaultFtpSessionFactory">
      <property name="host" value="${import.ftp.host}" />
      <property name="port" value="${import.ftp.port}" />
      <property name="username" value="${import.ftp.username}" />
      <property name="password" value="${import.ftp.password}" />
   </bean>

   <int:channel id="ftpChannel" />

   <int-ftp:inbound-channel-adapter id="ftpInbound"
       channel="ftpChannel"
       session-factory="ftpClientFactory"
       auto-create-local-directory="true"
       delete-remote-files="false"
       filename-pattern="*.txt"
       remote-directory="${import.ftp.remotefolder}"
       local-filename-generator-expression="+#this"
       temporary-file-suffix=".reading"
       local-directory="${ftp.localdir}">
    <int:poller fixed-rate="1000"/>
   </int-ftp:inbound-channel-adapter>


  <!-- Spring batch job setup -->

  <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    <property name="jobRepository" ref="jobRepository" />
  </bean>

  <batch:job-repository id="jobRepository" transaction-manager="transactionManager"/>

  <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />

  <batch:job id="myJob">
   <batch:step id="textToXmlStep" next="addToQueueStep">
     <batch:tasklet>
       <batch:chunk reader="filradReader" writer="multiResourceWriter" commit-interval="${job.commit.interval}" />  
     </batch:tasklet>
    <batch:listeners>
        <batch:listener ref="stepListener"/>
    </batch:listeners>
   </batch:step>
   <batch:step id="addToQueueStep">
    <batch:tasklet ref="addFilesToQueueTasklet" />
    <batch:listeners>
        <batch:listener ref="stepListener"/>
    </batch:listeners>
   </batch:step>
   <batch:listeners>
      <batch:listener ref="jobListener"/>
   </batch:listeners>
  </batch:job>

  <bean id="filradReader" scope="step" class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource" value="file://#{jobParameters['input.file.name']}" /> 
    <property name="lineMapper" ref="filradCompositeLineMapper"/>
    <property name="linesToSkip" value="1"/>
    <property name="skippedLinesCallback" ref="callbackHandler"/>
    <property name="encoding" value="UTF-8" />
  </bean>

  <bean id="addFilesToQueueTasklet" class="package.FilesToMqTasklet">
    <property name="filesBaseDir" value="${files.outputdir}\xml" />
    <property name="messageProducer" ref="messageProducer"/>
  </bean>


  <!-- ActiveMQ setup -->

  <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"
    p:brokerURL="${broker.url}" />

  <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
    <constructor-arg value="queue" />
  </bean>

  <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"
    p:connectionFactory-ref="connectionFactory"
    p:defaultDestination-ref="destination" />

  <bean id="messageProducer" class="package.FileMessageProducer"
    p:jmsTemplate-ref="jmsTemplate" />

  <bean id="messageListener" class="package.FileMessageListener" />

  <jms:listener-container concurrency="5-50">
    <jms:listener destination="queue" ref="messageListener"/>
  </jms:listener-container>

</beans>

(部分)FileMessageToJobRequest.java:

public FileMessageToJobRequest(final Job job, final String fileParameterName){
        this.job = job;
        this.fileParameterName = fileParameterName;
    }

    public JobLaunchRequest toRequest(Message<File> message) {
        JobParametersBuilder jobParametersBuilder =
            new JobParametersBuilder();

        jobParametersBuilder.addString(fileParameterName,
            message.getPayload().getAbsolutePath()).addDate("run.date", new Date());

        return new JobLaunchRequest(job, jobParametersBuilder.toJobParameters());
    }

(部分)FileMessageProducer.java:

public class FileMessageProducer {
    private static final Logger logger = Logger.getLogger(FileMessageProducer.class);

    protected JmsTemplate jmsTemplate; 

    public void sendFile(final File file) throws JMSException {
        jmsTemplate.send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                ObjectMessage message = session.createObjectMessage(file); 
                message.setStringProperty("fileName", file.getName());
                logger.info("Sent message: "+message.getStringProperty("fileName"));
                return message;
            }
        });

    }

(部分)FileMessageListener.java:

public class FileMessageListener implements MessageListener {

    private static final Logger logger = Logger.getLogger(FileMessageListener.class);

    public void onMessage(Message message) {
        try {
            logger.info("Received file " + message.getStringProperty("fileName"));
        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

我正在使用

测试此设置
public class FileListener {
    private static final Logger logger = Logger.getLogger(FileListener.class);
    private static final String CONFIG = "/launch-context.xml";

    public static void main(String[] args) throws Exception {
        logger.debug("FileListener started");
        new ClassPathXmlApplicationContext(CONFIG);
    }
}

完整的堆栈跟踪:

2015-03-09 10:06:52,879 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - <Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@644b27ad: startup date [Mon Mar 09 10:06:52 CET 2015]; root of context hierarchy>
2015-03-09 10:06:52,931 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [launch-context.xml]>
2015-03-09 10:06:53,111 INFO [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] - <JSR-330 'javax.inject.Named' annotation found and supported for component scanning>
2015-03-09 10:06:53,187 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/datasource-beans.xml]>
2015-03-09 10:06:53,228 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/job.xml]>
2015-03-09 10:06:53,303 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Overriding bean definition for bean 'transactionManager': replacing [Generic bean: class [org.springframework.jdbc.datasource.DataSourceTransactionManager]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [META-INF/spring/datasource-beans.xml]] with [Generic bean: class [org.springframework.batch.support.transaction.ResourcelessTransactionManager]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [META-INF/spring/job.xml]]>
2015-03-09 10:06:53,321 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Overriding bean definition for bean 'myJob': replacing [Generic bean: class [org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Generic bean: class [org.springframework.batch.core.configuration.xml.JobParserJobFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]>
2015-03-09 10:06:53,326 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/queue.xml]>
2015-03-09 10:06:54,043 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [META-INF/spring/integration.xml]>
2015-03-09 10:06:54,367 INFO [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer] - <Loading properties file from URL [file:/.../externalConfig/dev/application.properties]>
2015-03-09 10:06:54,386 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Overriding bean definition for bean 'stepListener': replacing [Generic bean: class [package.StepListener]; scope=step; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [META-INF/spring/job.xml]] with [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in class path resource [META-INF/spring/job.xml]]>
2015-03-09 10:06:54,386 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Overriding bean definition for bean 'filradReader': replacing [Generic bean: class [org.springframework.batch.item.file.FlatFileItemReader]; scope=step; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [META-INF/spring/job.xml]] with [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in class path resource [META-INF/spring/job.xml]]>
2015-03-09 10:06:54,387 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Overriding bean definition for bean 'multiResourceWriter': replacing [Generic bean: class [org.springframework.batch.item.file.MultiResourceItemWriter]; scope=step; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [META-INF/spring/job.xml]] with [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in class path resource [META-INF/spring/job.xml]]>
2015-03-09 10:06:54,387 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Overriding bean definition for bean 'filradXmlWriter': replacing [Generic bean: class [org.springframework.batch.item.xml.StaxEventItemWriter]; scope=step; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [META-INF/spring/job.xml]] with [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in class path resource [META-INF/spring/job.xml]]>
2015-03-09 10:06:54,391 INFO [org.springframework.integration.config.xml.DefaultConfiguringBeanFactoryPostProcessor] - <No bean named 'errorChannel' has been explicitly defined. Therefore, a default PublishSubscribeChannel will be created.>
2015-03-09 10:06:54,392 INFO [org.springframework.integration.config.xml.DefaultConfiguringBeanFactoryPostProcessor] - <No bean named 'taskScheduler' has been explicitly defined. Therefore, a default ThreadPoolTaskScheduler will be created.>
2015-03-09 10:06:54,402 INFO [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] - <JSR-330 'javax.inject.Inject' annotation found and supported for autowiring>
2015-03-09 10:06:54,415 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6112f78c: defining beans [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.jdbc.datasource.init.DataSourceInitializer#0,dataSource,transactionManager,jobLauncher,org.springframework.batch.core.scope.internalStepScope,org.springframework.beans.factory.config.CustomEditorConfigurer,org.springframework.batch.core.configuration.xml.CoreNamespacePostProcessor,jobRepository,filradSetMapper,stepListener,jobListener,callbackHandler,suffixCreator,filradProcessor,textToXmlStep,addToQueueStep,myJob,multiResourceReader,filradReader,filradCompositeLineMapper,taxiTokenizer,biljettTokenizer,rullstolTokenizer,multiResourceWriter,filradXmlWriter,filradTyperValidMarshaller,addFilesToQueueTasklet,connectionFactory,destination,jmsTemplate,messageProducer,messageListener,org.springframework.jms.listener.DefaultMessageListenerContainer#0,channelInitializer,$autoCreateChannelCandidates,org.springframework.integration.internalDefaultConfiguringBeanFactoryPostProcessor,outboundJobRequestChannel,jobLaunchReplyChannel,inboundFileChannel,org.springframework.batch.integration.launch.JobLaunchingGateway#0,org.springframework.integration.config.ConsumerEndpointFactoryBean#0,org.springframework.integration.handler.LoggingHandler#0,org.springframework.integration.config.ConsumerEndpointFactoryBean#1,org.springframework.integration.config.TransformerFactoryBean#0,org.springframework.integration.config.ConsumerEndpointFactoryBean#2,ftpClientFactory,ftpChannel,org.springframework.scheduling.support.PeriodicTrigger#0,ftpInbound,ftpController,scopedTarget.stepListener,scopedTarget.filradReader,scopedTarget.multiResourceWriter,scopedTarget.filradXmlWriter,nullChannel,errorChannel,_org.springframework.integration.errorLogger,taskScheduler,org.springframework.integration.config.IdGeneratorConfigurer#0]; root of factory hierarchy>
2015-03-09 10:06:54,597 INFO [org.springframework.jdbc.datasource.init.ResourceDatabasePopulator] - <Executing SQL script from URL [jar:file:/C:/Users/jesleh/.m2/repository/org/springframework/batch/spring-batch-core/2.2.3.RELEASE/spring-batch-core-2.2.3.RELEASE.jar!/org/springframework/batch/core/schema-drop-hsqldb.sql]>
2015-03-09 10:06:54,601 INFO [org.springframework.jdbc.datasource.init.ResourceDatabasePopulator] - <Done executing SQL script from URL [jar:file:/C:/Users/jesleh/.m2/repository/org/springframework/batch/spring-batch-core/2.2.3.RELEASE/spring-batch-core-2.2.3.RELEASE.jar!/org/springframework/batch/core/schema-drop-hsqldb.sql] in 4 ms.>
2015-03-09 10:06:54,601 INFO [org.springframework.jdbc.datasource.init.ResourceDatabasePopulator] - <Executing SQL script from URL [jar:file:/C:/Users/jesleh/.m2/repository/org/springframework/batch/spring-batch-core/2.2.3.RELEASE/spring-batch-core-2.2.3.RELEASE.jar!/org/springframework/batch/core/schema-hsqldb.sql]>
2015-03-09 10:06:54,614 INFO [org.springframework.jdbc.datasource.init.ResourceDatabasePopulator] - <Done executing SQL script from URL [jar:file:/C:/Users/jesleh/.m2/repository/org/springframework/batch/spring-batch-core/2.2.3.RELEASE/spring-batch-core-2.2.3.RELEASE.jar!/org/springframework/batch/core/schema-hsqldb.sql] in 12 ms.>
2015-03-09 10:06:54,663 INFO [org.springframework.batch.core.repository.support.JobRepositoryFactoryBean] - <No database type set, using meta data indicating: HSQL>
2015-03-09 10:06:54,797 INFO [org.springframework.batch.core.launch.support.SimpleJobLauncher] - <No TaskExecutor has been set, defaulting to synchronous executor.>
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
2015-03-09 10:06:55,027 INFO [org.springframework.oxm.jaxb.Jaxb2Marshaller] - <Creating JAXBContext with classes to be bound [class package.Filrad]>
2015-03-09 10:06:55,490 INFO [org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler] - <Initializing ExecutorService  'taskScheduler'>
2015-03-09 10:06:55,498 INFO [org.springframework.context.support.DefaultLifecycleProcessor] - <Starting beans in phase -2147483648>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.endpoint.EventDrivenConsumer] - <Adding {message-handler} as a subscriber to the 'outboundJobRequestChannel' channel>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.channel.DirectChannel] - <Channel 'outboundJobRequestChannel' has 1 subscriber(s).>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.endpoint.EventDrivenConsumer] - <started org.springframework.integration.config.ConsumerEndpointFactoryBean#0>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.endpoint.EventDrivenConsumer] - <Adding {logging-channel-adapter} as a subscriber to the 'jobLaunchReplyChannel' channel>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.channel.DirectChannel] - <Channel 'jobLaunchReplyChannel' has 1 subscriber(s).>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.endpoint.EventDrivenConsumer] - <started org.springframework.integration.config.ConsumerEndpointFactoryBean#1>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.endpoint.EventDrivenConsumer] - <Adding {transformer} as a subscriber to the 'ftpChannel' channel>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.channel.DirectChannel] - <Channel 'ftpChannel' has 1 subscriber(s).>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.endpoint.EventDrivenConsumer] - <started org.springframework.integration.config.ConsumerEndpointFactoryBean#2>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.endpoint.EventDrivenConsumer] - <Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.channel.PublishSubscribeChannel] - <Channel 'errorChannel' has 1 subscriber(s).>
2015-03-09 10:06:55,498 INFO [org.springframework.integration.endpoint.EventDrivenConsumer] - <started _org.springframework.integration.errorLogger>
2015-03-09 10:06:55,499 INFO [org.springframework.context.support.DefaultLifecycleProcessor] - <Starting beans in phase 2147483647>
2015-03-09 10:06:55,755 INFO [org.springframework.integration.endpoint.SourcePollingChannelAdapter] - <started ftpInbound>
2015-03-09 10:07:10,041 ERROR [org.springframework.integration.handler.LoggingHandler] - <org.springframework.expression.spel.SpelEvaluationException: EL1030E:(pos 0): The operator 'ADD' is not supported between objects of type 'java.lang.String' and 'null'
    at org.springframework.expression.spel.ExpressionState.operate(ExpressionState.java:191)
    at org.springframework.expression.spel.ast.OpPlus.getValueInternal(OpPlus.java:59)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:102)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:102)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.generateLocalFileName(AbstractInboundFileSynchronizer.java:228)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.copyFileToLocalDirectory(AbstractInboundFileSynchronizer.java:174)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.synchronizeToLocalDirectory(AbstractInboundFileSynchronizer.java:150)
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource.receive(AbstractInboundFileSynchronizingMessageSource.java:146)
    at org.springframework.integration.endpoint.SourcePollingChannelAdapter.receiveMessage(SourcePollingChannelAdapter.java:111)
    at org.springframework.integration.endpoint.AbstractTransactionSynchronizingPollingEndpoint.doPoll(AbstractTransactionSynchronizingPollingEndpoint.java:67)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.call(AbstractPollingEndpoint.java:146)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint.call(AbstractPollingEndpoint.java:144)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:236)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.run(ErrorHandlingTaskExecutor.java:52)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:48)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:49)
    at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:231)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:51)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access1(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

作业本身(读取 .txt 文件并将其转换为 xml 输出)有效,我 运行 单独执行了该步骤没有问题。问题似乎在于从 FTP 区域读取文件。我也试过用谷歌搜索这个问题,但找不到任何东西。我意识到这是一个很大的要求,但如果有人有任何想法,我会非常高兴。谢谢。

我已经把它作为答案了。

第一个错误是因为在执行操作时传递了 null local-filename-generator-expression="+#this”。尝试提供值似乎可以解决问题 local-filename-generator-expression="'sample'+#this"

您评论中的第二个错误是因为方法签名。下面的方法将 Message<File> message 作为参数,而它的调用者将 io.File 作为参数传递。因此错误。根据提供的信息,我不确定来电者在哪里,但这应该给你错误的要点。

public JobLaunchRequest toRequest(Message<File> message) {
        JobParametersBuilder jobParametersBuilder =
            new JobParametersBuilder();

我用

解决了这个问题
  <int:service-activator id="runJob" method="launch" input-channel="outboundJobRequestChannel"
        output-channel="statuses">
        <bean class="org.springframework.batch.integration.launch.JobLaunchingMessageHandler">
            <constructor-arg ref="jobLauncher"/>
        </bean>
    </int:service-activator>

而不是

<batch-int:job-launching-gateway request-channel="outboundJobRequestChannel"
                                   reply-channel="jobLaunchReplyChannel"
                                   job-launcher="jobLauncher" />

然后将 toRequest 方法的参数更改为(java.io.File 文件)。现在一切都按预期工作。感谢@minion 的帮助。