如何简单地设置风暴螺栓/喷嘴成员的序列化器?

时间:2014-11-14 13:35:21

标签: java serialization apache-storm

我有一个使用工厂界面来创建它使用的工具的螺栓。它会在调用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

作为旁注,我开始怀疑,为什么暴风雨让你注册工厂而不是Bolts和Spouts。因为最终它们被序列化并在不同的线程中被复制,所以最好只给风暴一个意思来产生这些螺栓并分离关注点。

1 个答案:

答案 0 :(得分:1)

不要在构造函数中设置任何值。在拓扑首次由驱动程序构建并在拓扑提交到集群之前调用构造函数。这就是为什么你设置的任何实例变量,无论是通过类初始化还是在构造函数中,都必须是可序列化的。

相反,只需将这些实例变量保留为null并在prepare()方法中设置它们。当你这样做时,你不需要序列化任何值,所以这也适用于不可序列化的实例变量。