【原】storm源码之巧用java反射反序列化clojure的defrecord获取属性值

storm源码是clojure、java、python的混合体。在解决storm-0.8.2的nimbus单点问题的过程中需要从zookeeper上读取目前storm集群中正在运行的assignments信息,以获取其代码在nimbus机器上的绝对路径(PS:通过java代码实现自定义的storage)。

assignments信息可以通过CuratorFramework框架的客户端读取zookeeper上对应目录的data,如下:

1 byte[] data = curatorFramework.getData().forPath(assignments_dir);

其中data字节码数组保存的是storm nimbus在topology分配任务时序列化到zookeeper的Assignment字节码,Assignment定义如下:

1 (defrecord Assignment [master-code-dir node->host executor->node+port executor->start-time-secs])

PS:defrecord是clojure独有的一种数据结构,主要用来简便轻量地将数据组织在一起。详细可参考:defrecord

由于Assignment是在clojure源码编译后才会产生对应的Assignment类class文件,而storm的clojure源码编译又在其java源码编译之后(前者依赖后者定义的诸多接口及Utils),因此在编码期java代码中是无法import Assignment类的,只能将data反序列化成Object类,如下:

1 ByteArrayInputStream bis = new ByteArrayInputStream(serialized);
2 ObjectInputStream ois = new ObjectInputStream(bis);
3 Object assignment = ois.readObject();
4 ois.close();

得到的assignment Object结构如下图:

反序列化之后就需要从Object中获取master_code_dir属性值。这里可以通过反射的方式获取:

1 String master_code_dir = assignment.getClass().getDeclaredField("master_code_dir").get(assignment).toString();

如此实现了java代码中不import Assignment类即可从zookeeper获取clojure序列化的master_code_dir属性值

posted @ 2013-08-14 12:53  yufengof  阅读(1200)  评论(0编辑  收藏  举报