2014-11-14 32 views
2

我有一個螺栓,它使用工廠界面來創建它使用的工具。它調用prepare時創建這些工具。 Factory實現只有基本成員(字符串,整數),默認情況下應該是可序列化的。如何簡單地設置風暴螺栓/噴口成員的序列化程序?

當我運行我的拓撲結構時,我得到一個來自工廠實現的NotSerializableException。我想知道如何爲工廠註冊序列化程序。

這裏有一個例子:

public class Demo extends BaseRichBolt { 

    public static interface IExecutor 
    { 
     public void execute(Tuple tuple); 
    } 

    public static interface IExecutorCreator 
    { 
     public IExecutor create(Map map, TopologyContext tc, OutputCollector oc ); 
    }; 

    public static class DummyExecutor implements IExecutor 
    { 
     public void execute(Tuple tuple) {} 
    }; 

    public static class DummyExecutorCreator implements IExecutorCreator 
    { 
     String name_; 
     public DummyExecutorCreator(String name) { this.name_ = name;} 
     public IExecutor create(Map map, TopologyContext tc, OutputCollector oc) { 
      return new DummyExecutor(); 
     } 
    }; 

    public void declareOutputFields(OutputFieldsDeclarer ofd) { 

    } 

    private IExecutor   executor_; 
    private IExecutorCreator creator_; 

    public Demo(IExecutorCreator creator) 
    { 
     this.creator_ = creator; 
    } 

    public void prepare(Map map, TopologyContext tc, OutputCollector oc) { 
     this.executor_ = this.creator_.create(map, tc, oc); 
    } 

    public void execute(Tuple tuple) { 
     this.executor_.execute(tuple); 
    } 

} 

當我嘗試在拓撲上運行它,我得到這個錯誤: java.io.NotSerializableException: Demo$DummyExecutorCreator

作爲一個方面說明,我開始懷疑,爲什麼不風暴有你註冊工廠,而不是螺栓和噴口。因爲最終他們會被序列化並複製到不同的線程中,所以最好讓風暴成爲生成這些線程並分離問題的手段。

+1

你的工廠的任何原因不只是實現序列化?除非有什麼特別的事情發生,你們這裏的例子正在隱藏,那應該是正常的。 – thyme 2014-11-14 15:28:31

+0

@thyme謝謝,事實確實如此。我已經在DummyExecutorCreator中添加了'implements java.io.Serializable',它像一個魅力一樣工作。 – Arthur 2014-11-14 16:43:10

回答

0

不要在您的構造函數中設置任何值。構造函數在驅動程序首次構建拓撲時並且拓撲提交到集羣之前調用。這就是爲什麼您設置的任何實例變量,無論是通過類初始化還是在構造函數中,都必須是可序列化的。

而是簡單地將這些實例變量留空並將它們設置在prepare()方法中。當你這樣做時,你不需要序列化任何值,所以這也適用於不可序列化的實例變量。

相關問題