我遇到了Apache Camel的问题,我无法理解。我在JBoss Fuse 6.3.0中遇到了这个问题,它捆绑了Apache Camel 2.17.0.redhat-630224。
我有一个简单的路线:它从FTP服务器下载文件,将它们转换为POJO(这部分有效),然后将它们聚合到一个POJO中,该POJO被编组并保存到文件中。
在JBoss Developer Studio中,我通过执行" Run as ...>来测试它。当地的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 =&#34; false&#34;,没有改变任何东西。
这里是聚合器:
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();
的主体时,结果不为空,但我无法将其转换为{{1} }:我得到了MyClass
。
阅读OSGi如何导致多个类加载器加载同一个类,我将java.lang.ClassCastException: net.j11e.MyClass cannot be cast to net.j11e.MyClass
重命名为MyClass
并重启(??)后,一切正常。但是,卸载我的软件包并重新安装后,问题就出现了。
MyOtherClass
返回两个包:mine和dozer-osgi,这是(我猜)逻辑,因为MyClass实例是由推土机转换生成的。
好的,也许我不应经常卸载并重新安装捆绑包,而是使用osgi:find-class MyClass
,osgi:update
或其他任何东西。但是,应该有办法让这项工作成功吗?除了卸载我的软件包,刷新/更新推土机,停止/重新启动Fuse,以及重新安装我的软件包之外的其他东西,希望上述操作之一能够以某种方式加载正确的类?
答案 0 :(得分:1)
对于将来可能会遇到此问题的人,请回顾一下:
getBody
返回null(getMandatoryBody
将返回异常等)。osgi:find-class MyClass
。这将返回你的包...和另一个。osgi:list | grep thebundle
)并刷新它(osgi:refresh 123
)来刷新该包。您还可以从Fuse的Web UI(hawtio)刷新捆绑包:OSGi&gt;捆绑&gt;你的捆绑&gt;页面顶部的刷新按钮(启动,停止,更新和卸载按钮旁边)。这不仅仅是解决这个问题的缓解措施。真正的解决方案可能涉及修复包导入/导出规则或其他内容,但这超出了我目前的技能。
公平警告:有时候,令人耳目一新的推土机osgi显然还不够。 MyClass不再被它导入(osgi:find-class MyClass
不会返回dozer-osgi),但我仍遇到NullPointerException
问题。在这些罕见的事件中,我不得不重启Fuse。我不知道为什么会发生这几起案件。