Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在IDE中和在JBoss Fuse中部署时Apache Camel聚合的不同行为_Java_Eclipse_Apache Camel_Apache Karaf - Fatal编程技术网

Java 在IDE中和在JBoss Fuse中部署时Apache Camel聚合的不同行为

Java 在IDE中和在JBoss Fuse中部署时Apache Camel聚合的不同行为,java,eclipse,apache-camel,apache-karaf,Java,Eclipse,Apache Camel,Apache Karaf,我对Apache Camel有一个我无法理解的问题。我在JBoss Fuse 6.3.0中遇到了这个问题,它捆绑了Apache Camel 2.17.0.redhat-630224 我有一个简单的方法:它从FTP服务器下载文件,将它们转换成POJO(这部分工作正常),然后将它们聚合成单个POJO,然后将其编组并保存到文件中 在JBossDeveloperStudio中,我通过执行“RunAs…>LocalCamelContext”来测试这一点。在幕后,它只是运行mvncleanpackage o

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

我有一个简单的方法:它从FTP服务器下载文件,将它们转换成POJO(这部分工作正常),然后将它们聚合成单个POJO,然后将其编组并保存到文件中

在JBossDeveloperStudio中,我通过执行“RunAs…>LocalCamelContext”来测试这一点。在幕后,它只是运行
mvncleanpackage org.apache.camel:camel-maven-plugin:run
。无论是从IDE还是在终端中手动执行,路由都可以正常工作

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

聚合由实现
org.apache.camel.processor.aggregate.AggregationStrategy
(文档化)的自定义类处理。我遇到的问题是,我收到的
newExchange
参数的正文总是空的。现在,预期
oldchange
第一次为空,但是
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
第二个
if
每次都会触发,即使对于第一个聚合,如果我删除第一个
if
中的
return

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

当我在没有指定类的情况下得到
newExchanges
的主体时(
Object newBody=newExchange.getIn().getBody();
),结果不是空的,但我不能将其转换为
MyClass
:我得到了
java.lang.ClassCastException:net.j11e.MyClass不能转换为net.j11e.MyClass

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

osgi:find class MyClass
返回两个捆绑包:mine和dozer osgi,这(我猜)是合乎逻辑的,因为MyClass实例是由dozer转换生成的


好吧,也许我不应该经常卸载和重新安装捆绑包,而应该使用
osgi:update
osgi:refresh
,或者其他什么。但是,还是应该有办法让它发挥作用?除了卸载我的捆绑包、刷新/更新推土机、停止/重新启动Fuse和重新安装我的捆绑包,希望上述操作之一能够以某种方式加载正确的类之外,还有什么其他方法吗?

对于将来可能遇到此问题的人,这里有一个概述:

  • 这个问题是由另一个包(在我的例子中是dozer osgi)仍在使用由您的包导出的包的旧版本这一事实引起的。在这里,这会导致对MyClass的转换失败,这使得
    getBody
    返回null(
    getMandatoryBody
    将返回异常,等等)
  • 要识别导致问题的捆绑包,请使用命令
    osgi:find class MyClass
    。这将退还您的包裹。。。还有一个
  • 通过查找捆绑包id(
    osgi:list | grep thebundle
    )并刷新它(
    osgi:refresh 123
    ),刷新该捆绑包。您还可以从Fuse的web UI(hawtio)中刷新捆绑包:OSGi>捆绑包>您的捆绑包>页面顶部的刷新按钮(在开始、停止、更新和卸载按钮旁边)
这与其说是解决这一问题的正确方法,不如说是一种缓解措施。真正的解决方案可能包括修改包的导入/导出规则或其他东西,但这超出了我目前的技能范围


公平的警告:有时候,仅仅刷新dozer osgi显然是不够的。MyClass不再由它导入(
osgi:find class MyClass
不会返回dozer osgi),但我仍然存在
NullPointerException
问题。在这些罕见的事件中,我不得不重新启动保险丝。我不知道为什么会发生这几起案件

我想cusom类是正在部署的包的一部分吧?如何进行部署?@SoucianceEqdamRashti是的,自定义聚合器在捆绑包中。我可以通过检查maven生成的工件来检查这一点,这也是因为当应用程序运行时,我在聚合方法中对System.out.println的调用出现在我的日志中;)在您的保险丝安装中,您的Camel是否比2.16版本更新?如果能看到您的实际路线,那将非常有趣。@SoucianceEqdamRashti:是的,它是Camel 2.17.0。
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");
        }

        // ...