【问题标题】:Different behavior of Apache Camel aggregation in IDE and when deployed in JBoss Fuse在 IDE 中和在 JBoss Fuse 中部署时 Apache Camel 聚合的不同行为
【发布时间】:2017-04-13 15:35:19
【问题描述】:

我在使用 Apache Camel 时遇到了一个我无法理解的问题。 JBoss Fuse 6.3.0 有这个问题,它捆绑了 Apache Camel 2.17.0.redhat-630224。

我有一个简单的路线:它从 FTP 服务器下载文件,将它们转换为 POJO(这部分有效),然后将它们聚合成一个 POJO,然后编组并保存到一个文件中。

在 JBoss Developer Studio 中,我通过执行“运行方式... > 本地 Camel 上下文”来对此进行测试。在幕后,这只是运行mvn clean package org.apache.camel:camel-maven-plugin:run。无论我是从 IDE 还是在终端中手动执行,路由都可以正常工作。

但是,当我构建一个 OSGi 包(使用 mvn clean install)并将其部署到 JBoss Fuse (Apache Karaf) 中时,应用程序部署成功并且下载/转换部分工作正常,但随后聚合失败。

聚合由实现org.apache.camel.processor.aggregate.AggregationStrategy 的自定义类处理(记录在here)。我遇到的问题是我收到的newExchange 参数总是有一个空正文。现在,oldExchange 第一次为空是意料之中的,但newExchange 的主体呢? (编辑:相关表达式是一个简单的常数,因为所有 POJO 都聚合在一起)

更奇怪的是:如果我在聚合器之前修改路由以编组我的 POJO,我会收到一个包含预期数据的字符串。这证明(我认为!)转换按预期工作。此外,Fuse 的日志没有显示错误消息(无论是在部署时还是在运行时)。这看起来很像配置或依赖问题,但在我的一生中,我在任何地方都找不到任何类似的问题。

有没有人见过类似的东西?或者至少,您对问题的根源有什么建议吗?

编辑:这是路线的相关部分:

<choice>
    // one <when> per file which produces a POJO
    <when id="_when_some_xml">
        <simple>${file:onlyname} == 'something.xml'</simple>
        <to id="_to2" uri="ref:transform_something_xml"/>
    </when>
</choice>
// if I add a marshalling here, I receive non-null exchanges in the aggregator... but they're strings and not the POJOs I want.
<aggregate completionSize="12" id="_aggregate_things"
            strategyMethodAllowNull="true" strategyRef="MyAggregator">
    <correlationExpression>
        <constant trim="false">true</constant>
    </correlationExpression>
    <log id="_log_things_aggregated" message="Data aggregated."/>
    <convertBodyTo id="_convertBodyTo_anotherClass" type="net.j11e.mypackage.MyClass"/>
    // [...] next: marshal and save to file

注意:我尝试了 strategyMethodAllowNull="false",没有改变任何东西。

这里是聚合器:

public class EpgAggregator implements AggregationStrategy {

    @Override
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
        // first message being aggregated: no oldExchange, simply keep the message
        if (oldExchange == null) {
            System.out.println("Old exchange is null");
            return newExchange;
        }

        if (newExchange.getIn().getBody(MyClass.class) == null) {
            System.out.println("newExchange body is null");
        }

        // ...

如果我删除第一个if 中的return,则每次都会触发第二个if,即使对于第一个聚合也是如此。

编辑 好的,感谢 noMad17n 在下面的评论,我有了一个突破:问题与类加载有关。

当我得到newExchanges 的主体而不指定类时(Object newBody = newExchange.getIn().getBody();),结果不为空,但我无法将其转换为MyClass:我得到了java.lang.ClassCastException: net.j11e.MyClass cannot be cast to net.j11e.MyClass

阅读了有关 OSGi 如何导致多个类加载器加载同一个类的信息,我将 MyClass 重命名为 MyOtherClass 并在重新启动 (??) 后,一切正常。但是,在卸载我的捆绑包并重新安装后,问题又回来了。

osgi:find-class MyClass 返回两个包:mine 和 dozer-osgi,这(我猜)是合乎逻辑的,因为 MyClass 实例是由推土机转换产生的。

好的,所以也许我不应该经常卸载和重新安装捆绑包,而是使用osgi:updateosgi:refresh 或其他任何东西。但是,应该有办法使这项工作?除了卸载我的包、刷新/更新推土机、停止/重新启动 Fuse 和重新安装我的包之外,希望上述操作之一以某种方式加载正确的类?

【问题讨论】:

  • 我认为 cusom 类是正在部署的同一个包的一部分?您如何进行部署?
  • @SoucianceEqdamRashti 是的,自定义聚合器在捆绑包中。我可以通过检查 maven 生成的工件来检查这一点 - 也因为当应用程序运行时,我在聚合方法中对 System.out.println 的调用出现在我的日志中;)
  • 在您的 Fuse 安装上,您的 Camel 是否比 2.16 更新?
  • 看看你的实际路线会很有趣。
  • @SoucianceEqdamRashti:是的,它是 Camel 2.17.0。

标签: java eclipse apache-camel apache-karaf


【解决方案1】:

对于那些将来可能会遇到此问题的人,这里有一个回顾:

  • 这个问题是由你的包导出的一个旧版本的包仍然被另一个(在我的例子中,dozer-osgi)使用的事实引起的。在这里,这会导致对 MyClass 的强制转换失败,这使得 getBody 返回 null(getMandatoryBody 将返回异常等)
  • 要识别导致问题的捆绑包,请使用命令osgi:find-class MyClass。这将返回您的捆绑包......以及另一个。
  • 通过查找其捆绑包 ID (osgi:list | grep thebundle) 并刷新它 (osgi:refresh 123) 来刷新该捆绑包。您还可以从 Fuse 的 Web UI (hawtio) 刷新包:OSGi > bundles > your bundle > 页面顶部的刷新按钮(在开始、停止、更新和卸载按钮旁边)。

这与其说是对这个问题的适当解决方案,不如说是一种缓解措施。真正的解决方案可能涉及修复包导入/导出规则或其他东西,但这超出了我目前的技能。

同样的警告:有时,刷新 dozer-osgi 显然是不够的。 MyClass 不再被它导入(osgi:find-class MyClass 不会返回 dozer-osgi),但我仍然有我的NullPointerException 问题。在这些罕见的情况下,我不得不重新启动 Fuse。我不知道为什么会发生这几个案例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 2019-03-10
    • 2016-04-18
    • 1970-01-01
    相关资源
    最近更新 更多