2017-04-03 45 views
0

我在与Apache的骆驼的问题,我无法理解的时候。我已经与JBoss 6.3.0保险丝,捆绑了Apache的骆驼2.17.0.redhat-630224这个问题。不同的行为,并部署在JBoss中保险丝

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

在JBoss中开发工作室,我做“为...>本地骆驼上下文中运行”进行测试。在幕后,这只是运行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,我收到一个带有预期数据的String。这证明(我认为!)这种转变如预期的那样发挥作用。此外,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 =“假”,并没有改变任何事情。

而这里的聚合:

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触发每一次,即使是第一次聚集,如果我在第一if删除return

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

当我拿到newExchanges的身体没有指定一个类(Object newBody = newExchange.getIn().getBody();),结果还是不为空,但我不能强制转换为MyClass:我得到了java.lang.ClassCastException: net.j11e.MyClass cannot be cast to net.j11e.MyClass

阅读关于OSGi如何导致多个类加载器加载同一个班级,我改名MyClassMyOtherClass和重启(??)后,一切正常。但是,卸载我的软件包并重新安装后,问题又回来了。

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

好的,也许我不应该经常卸载并重新安装捆绑包,而是使用osgi:updateosgi:refresh或其他什么。但是,仍然应该有一种方法来完成这项工作?除了卸载我的软件包,刷新/更新推土机,停止/重新启动Fuse,并重新安装我的软件包,希望上述操作之一以某种方式使得正确的类被加载之外还有其他的东西吗?

+0

的cusom类是正在部署我相信同捆的一部分?你如何进行部署? –

+0

@SoucianceEqdamRashti是的,自定义聚合器在捆绑中。我可以检查通过检查行家所产生的神器 - 也因为为System.out.println我把在集合方法的调用出现在我登录时的应用程序运行;) – j11e

+0

是您在您的熔断器安装骆驼出现不到2.16 ? –

回答

0

对于那些谁可能会遇到此问题在将来,这里有一个概括:

  • 的问题是由你包出口的包装的旧版本仍然使用另一个造成的事实(在我的情况,dozer-osgi)。在这里,这导致铸造到MyClass失败,这使得getBody返回空(getMandatoryBody将返回一个异常等)
  • 以确定导致问题的束,使用命令osgi:find-class MyClass。这将返回你的包...和另一个。
  • 通过发现其包ID(osgi:list | grep thebundle)并刷新它(osgi:refresh 123)刷新该软件包。您还可以从Fuse的Web UI(hawtio)刷新该软件包:OSGi>软件包>您的软件包>页面顶部的刷新按钮(位于开始,停止,更新和卸载按钮旁边)。

这更是一个比缓解妥善解决这个问题。真正的解决方案可能涉及修复软件包导入/导出规则或其他内容,但这超出了我目前的技能。

公平的警告,也:有时,刷新推土机OSGi的显然是不够的。 MyClass不再被导入(osgi:find-class MyClass不会返回dozer-osgi),但我仍然有我的NullPointerException问题。在这些罕见的事件中,我不得不重新启动熔断器。我不知道为什么发生这几起案件。

相关问题