2014-11-14 34 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()方法中。当你这样做时,你不需要序列化任何值,所以这也适用于不可序列化的实例变量。

相关问题