1

我有一个 spring 集成 sftp 流,我将其作为子上下文加载到我的整个应用程序上下文中。这是基于动态 ftp SI 示例。我的集成流程与反应器或其中的流无关。它是一个简单的流程,其中一个direct channel连接sftp-outbound-gateway到将文件传输到 sftp 服务器。我什至可以运行单元测试并且流程工作正常(能够传输文件)但是当我运行一个加载完整父应用程序的集成测试然后使用其中加载的这个 sftp 流程初始化子上下文时,它会抛出一个错误无法找到 reactor/StringUtils 类。

原因似乎是 spring-integration-sftp 将 reactor jar 作为瞬态 deps 加载,但由于我的父应用程序已经在类路径中加载了不同版本的 reactor,我从 spring 集成 dep 中排除了 reactor-core。如果我不从 spring-integration 中排除 reactor-core,那么会有一些版本冲突,所以我想排除它。

reactorVersion = 2.0.0.M2

compile("io.projectreactor:reactor-core:$reactorVersion")
compile "io.projectreactor.spring:reactor-spring-context:$reactorVersion"

compile("org.springframework.integration:spring-integration-sftp") {
    exclude module: "reactor-core"
}

初始化 SI 流程

context = new ClassPathXmlApplicationContext(new String[] { "classpath:adapters/"
                + sink.getConfigurationFile() }, false);
        setEnvironment(context, sink);
        context.setParent(parentContext);
        context.refresh();
        context.registerShutdownHook();

我运行集成测试时的错误

org.springframework.beans.factory.BeanDefinitionStoreException:从类路径资源 [adapters/sftp.xml] 解析 XML 文档时出现意外异常;嵌套异常是 java.lang.NoClassDefFoundError: reactor/util/StringUtils at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:414) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions( XmlBeanDefinitionReader.java:336) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)

最后是 SI 流程

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-sftp="http://www.springframework.org/schema/integration/sftp"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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
    http://www.springframework.org/schema/integration/sftp http://www.springframework.org/schema/integration/sftp/spring-integration-sftp.xsd">

<import resource="common.xml" />

<bean id="sftpSessionFactory"
    class="org.springframework.integration.file.remote.session.CachingSessionFactory">
    <constructor-arg ref="defaultSftpSessionFactory" />
</bean>

<bean id="defaultSftpSessionFactory"
    class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
    <property name="host" value="${sink.host}" />
    <property name="port" value="22" />
    <property name="privateKey" value="${sink.private.key}" />
    <property name="privateKeyPassphrase" value="${sink.private.key.phrase}" />
    <property name="user" value="${sink.user}" />
    <property name="password" value="${sink.pass}" />
</bean>

<int:channel id="input" />

<int-sftp:outbound-channel-adapter
    auto-startup="true" session-factory="sftpSessionFactory" channel="input"
    remote-directory="${sink.path}" remote-filename-generator-expression="headers['remote_file_name']">
    <int-sftp:request-handler-advice-chain>
        <bean
            class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <property name="onSuccessExpression" value="payload" />
            <property name="successChannel" ref="successChannel" />
            <property name="onFailureExpression" value="payload" />
            <property name="failureChannel" ref="failureChannel" />
            <property name="trapException" value="true" />
        </bean>
    </int-sftp:request-handler-advice-chain>
</int-sftp:outbound-channel-adapter>

<int:channel id="successChannel" />
<int:service-activator input-channel="successChannel"
    ref="completionHandler" method="handle" />

<int:channel id="failureChannel" />
<int:service-activator input-channel="failureChannel"
    ref="failureHandler" method="handle" />


更新以添加我的反应器配置

@Configuration
@EnableReactor
public class ReactorConfiguration {

static {
    Environment.initializeIfEmpty().assignErrorJournal();
}

@Bean
public EventBus eventBus() {
    return EventBus.config().env(Environment.get()).dispatcher(Environment.SHARED).get();
}

@Bean
public IdGenerator randomUUIDGenerator() {
    return new IdGenerator() {
        @Override
        public UUID generateId() {
            return UUIDUtils.random();
        }
    };
}
}
4

1 回答 1

0

Gradle 目前在排除传递依赖项的依赖项方面做得并不好。

不是spring-integration-sftp那个拉反应堆,它是spring-integration-core

尝试通过它明确排除。

我们在 SI 4.2 中删除了硬传递反应器依赖项(但尚未发布)。

Spring 团队创建了一个可能有帮助的gradle 插件。

于 2015-04-28T22:16:52.253 回答