3

I wanted to upgrade Spring boot version from 2.2.7.RELEASE to 2.3.0.RELEASE, I am using also Spring integration file with XML configuration (see below). when starting my application, a NullPointerException is thrown. After debugging the issue, the root cause was the creation of the bean file:inbound-channel-adapter. The interesting thing is that only this type of beans which cause this issue and all other ones doesn't. Did anyone had a similar issue? Anyone can help transforming this XML to Java configuration style? Thanks in advance.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:int="http://www.springframework.org/schema/integration"
       xmlns:task="http://www.springframework.org/schema/task"
       xmlns:file="http://www.springframework.org/schema/integration/file"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
       http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
       http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">


    <bean id="compositeFilter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
        <constructor-arg>
            <list>
                <ref bean="ignoreHiddenFileListFilter"/>
                <ref bean="acceptOnceFileListFilter"/>
                <ref bean="extensionFileFilter"/>
            </list>
        </constructor-arg>
    </bean>

    <!-- upload folder listener  -->
    <file:inbound-channel-adapter id="uploadFilesScanner" directory="${integration.upload-folder}" filter="compositeFilter">
        <int:poller fixed-rate="${integration.poller-rate:10000}"/>
    </file:inbound-channel-adapter>

    <file:outbound-gateway request-channel="uploadFilesScanner" reply-channel="batchFilesScanner" directory="${integration.directory}" delete-source-files="true"/>

    <!-- 1) Scan for files -->
    <file:inbound-channel-adapter id="batchFilesScanner" directory="${integration.directory}" filter="compositeFilter">
        <int:poller fixed-rate="5000"/>
    </file:inbound-channel-adapter>

    <!-- 2) move the file to processing -->
    <file:outbound-gateway request-channel="batchFilesScanner" reply-channel="batchFilesProcessing" directory="${integration.processing-folder}" delete-source-files="true"/>

    <!-- 3) transform csv file -->
    <int:service-activator input-channel="batchFilesProcessing" output-channel="batchFilesTran" ref="batchTransformerTask" method="execute"/>

    <!-- 4) move the file to archive folder -->
    <file:outbound-gateway request-channel="batchFilesTran" reply-channel="batchFilesArchive" directory="${integration.archive-folder}" delete-source-files="true"/>

    <int:service-activator input-channel="batchFilesArchive" ref="cleanupHelper" method="execute"/>

    <!-- Transformer task channel configuration -->
    <task:executor id="batchFilesTranTaskExecutor" pool-size="1" rejection-policy="CALLER_RUNS" queue-capacity="1"/>
    <int:channel id="batchFilesTran">
        <int:dispatcher load-balancer="round-robin" task-executor="batchFilesTranTaskExecutor" failover="false"/>
    </int:channel>

    <int:service-activator input-channel="errorChannel" ref="intErrorHandler" method="execute"/>

</beans>

NullPointerException:

Caused by:
        java.lang.NullPointerException
            at org.springframework.integration.support.utils.IntegrationUtils.obtainComponentName(IntegrationUtils.java:205)
            at org.springframework.integration.graph.IntegrationGraphServer$NodeFactory.sourceNode(IntegrationGraphServer.java:399)
            at org.springframework.integration.graph.IntegrationGraphServer.lambda$pollingAdapters$1(IntegrationGraphServer.java:216)
            at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
            at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
            at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
            at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
            at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
            at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
            at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
            at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
            at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
            at org.springframework.integration.graph.IntegrationGraphServer.pollingAdapters(IntegrationGraphServer.java:221)
            at org.springframework.integration.graph.IntegrationGraphServer.buildGraph(IntegrationGraphServer.java:184)
            at org.springframework.integration.graph.IntegrationGraphServer.onApplicationEvent(IntegrationGraphServer.java:116)
            at org.springframework.integration.graph.IntegrationGraphServer.onApplicationEvent(IntegrationGraphServer.java:67)
            at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
            at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
            at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
            at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:403)
            at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:360)
            at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:897)
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
            at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
            at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
            at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
            at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
            at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
            at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
            at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
            ... 88 more

NBE
  • 33
  • 1
  • 4
  • The issue is still there also with version 5.3.1 java.lang.NullPointerException: null at org.springframework.integration.support.utils.IntegrationUtils.obtainComponentName(IntegrationUtils.java:205) ~[spring-integration-core-5.3.1.RELEASE.jar:5.3.1.RELEASE] at org.springframework.integration.graph.IntegrationGraphServer$NodeFactory.sourceNode(IntegrationGraphServer.java:399) ~[spring-integration-core-5.3.1.RELEASE.jar:5.3.1.RELEASE] – NBE Jun 12 '20 at 09:11

2 Answers2

1

The issue is confirmed. The FileReadingMessageSourceFactoryBean doesn't populate a beanName into a FileReadingMessageSource it produces.

Your config is too big to convert it over here immediately. Consider to follow docs: https://docs.spring.io/spring-integration/docs/current/reference/html/overview.html#programming-tips

A Java & Annotations configuration analog for the <file:inbound-channel-adapter> is like this:

@Bean
@InboundChannelAdapter
public FileReadingMessageSource fileReadingMessageSource() {

...
}

See more info here: https://docs.spring.io/spring-integration/docs/current/reference/html/configuration.html#annotations

With Java DSL it is just a matter to take an IntegrationFlows.from(MessageSource) factory and follow its builder for the rest:

https://docs.spring.io/spring-integration/docs/current/reference/html/dsl.html#java-dsl-inbound-adapters

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Artem, when you say its confirmed, has an issue been raised and this will be corrected in future releases? Or is the answer "wont fix" and we need to to follow the "workarounds" - I agree, we should be moving away from xml configs to java dsl. This is the last piece of xml in some very old code. – Todd Lindner Jun 05 '20 at 14:49
  • No, we will fix it soon enough for June 10th – Artem Bilan Jun 05 '20 at 15:01
  • Thanks do you have an issue link? I would just like to follow. – Todd Lindner Jun 06 '20 at 16:02
  • Here it is: https://github.com/spring-projects/spring-integration/pull/3296. Will be released tomorrow – Artem Bilan Jun 09 '20 at 14:46
  • @ArtemBilan: I tried to upgrade my spring boot version to the newly released one 2.3.1.RELEASE which upgrade spring-integration to 5.3.1, which I assume contains the fix for this issue. However, I am still getting the exact same error, i.e., NullPointerException when trying to get the bean name of FileReadingMessageSource – NBE Jun 12 '20 at 09:07
  • Hm. Suspicious. Any chances to have a simple project to reproduce? – Artem Bilan Jun 12 '20 at 13:09
  • @ArtemBilan it works now, sorry it was my mistake I forgot to update one dependency in a related module which led to load the old version. thanks again for the fix. – NBE Jun 15 '20 at 07:04
  • Please, accept the answer then. Thank you for confirmation! – Artem Bilan Jun 15 '20 at 13:09
0

I stick to the Spring Boot version 2.3.0 and only override the version of SI to 5.3.1 release and it worked. The Exception is gone.