2017-04-03 46 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問題。在這些罕見的事件中,我不得不重新啓動熔斷器。我不知道爲什麼發生這幾起案件。

相關問題