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

2019-03-02 23:40|来源: 网路

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属性值


转自:http://www.cnblogs.com/yufengof/p/java-deserialize-defrecord

相关问答

更多

Java 能 反序列化Php的数据么?

理论上可以,不过你的php传过来的数据是怎么序列化的,是用php序列化的? 那需要你自己写规则和php的序列化对应的反序列化。

readfiles是序列化还是反序列化

准备工作和类设计 1 启动VS,新建C# 类库项目,并命名为KTools。 2 添加C# Winform项目,命名为Test,重命名主窗口为MainForm,并设置为启动项。同时在KTools项目添加文件夹Serializer,并在该文件夹中添加3个类:XMLSerializer、SoapSerializer和BinarySerializer,如下图: 3 该类库的设计目标是快速方便,最好把序列化和反序列化的方法做成静态方法,这样就可以省去了实例化的步骤。序列化大体上分为序列化到文件和序列化到流, ...

C#中的序列化和Java中的反序列化(Serialization in C# and de-serialization in Java)

我在这里看到3个选项。 我建议选项1,Protobufs。 看看Google的ProtoBufs 或者一些等价物。 这是Java版本。 这是一个C#端口。 Protobufs意味着这种语言交互。 它的二进制,小型,快速和语言不可知的。 它也具有向后兼容性,所以如果将来更改序列化对象,您仍然可以阅读它们。 这个特性对你来说也是透明的,只要你编写代码,理解更新的变量在反序列化旧对象时可能会丢失。 这是一个巨大的优势! 在另一种语言中实现一种语言的默认序列化 您可以尝试在C#中实现Java序列化逻辑,或 ...

没有属性的C#json序列化和反序列化(C# json serialization and deserialization without attributes)

是。 您可以使用.NET JavaScriptSerializer类,也可以使用第三方库(如Json.Net) 。 以下是使用JavaScriptSerializer的示例: using System; using System.Web.Script.Serialization; class Program { static void Main(string[] args) { DerivedClass dc = new DerivedClass ...

Clojure defrecord序列化ClassNotFoundException(Clojure defrecord serialization ClassNotFoundException)

不要在函数定义中使用def。 当您使用def时,您在命名空间中创建一个var,并可能将其作为每个函数调用的副作用进行操作。 使用let-blocks。 如果要将Clojure数据结构保存在文件中,请使用clojure.edn 。 它是安全的(例如,在您不知情的情况下,不会调用文件中定义的函数),但它允许启用自定义阅读器(请参阅下文)。 用defrecord定义的类型可以使用pr-str以(Clojure-reader-)可读方式打印(感谢@A.Web注意到)。 在你的例子中,我不明白你为什么不首先 ...

DefaultValue属性反序列化(DefaultValue properties deserialization)

DefaultValues行为(不仅仅是在protobuf-net中 - 通常在System.ComponentModel ,例如PropertyGrid , PropertyDescriptor等),这用于表示不需要序列化的东西,因为它们将默认为相同的值自动。 因此,它假定如果您的代码注释DefaultValue ,那么您的代码将分配这些默认值。 这可以在构造函数,字段初始化器或预反序列化回调中(支持所有4个标准回调点)。 从技术上讲,在反序列化之前,库不可能明确地分配这些值 - 但仅仅是:那不 ...

基于DB值的序列化和反序列化属性(Serialize and Deserialize Property Based on DB Value)

这里要注意的第一件事是[XmlIgnore]是多余的; XmlSerializer 对 get-only属性(列表除外) 不感兴趣 ,因为它知道它不能反序列化它们。 例如: public class SomeType { public string Foo { get; set; } public string Bar { get { Console.WriteLine("get_Bar"); return "abc"; } } static void Main() ...

将TimeSpan值序列化和反序列化为Object类型的属性(Serializing and deserializing TimeSpan values to a property of type Object)

Json.Net有一个TypeNameHandling设置,用于处理未知类型,以便可以正确反序列化。 启用此设置后,它会导致Json.Net在JSON中插入特殊的$type属性,然后在反序列化时将其用作提示。 不幸的是,这个设置似乎不适用于“简单”类型,如TimeSpan ,因为它们的值被序列化为字符串而不是对象。 要解决这个问题,我建议制作一个使用相同想法的自定义JsonConverter 。 转换器不是直接输出对象的字符串值,而是输出具有两个属性的子对象表示: type和value 。 子对象 ...

反序列化Java对象(Deserializing a Java object)

对此的标准解决方案是JAXB , 自JDK 1.6以来它一直是Java SE的一部分 。 特别是,它支持使用注释配置映射(或者您可以简单地依赖于合理的默认值),这比外部XML文件简单得多,并且可以从XML模式派生映射类,或者从映射中派生模式类。 它还可以根据XML Schema轻松验证文档。 此外,如果您正在使用的XML是SOAP Web服务,则JAX-WS构建在JAXB上以从WSDL(或来自带注释的接口的WSDL)创建接口,并且透明地为您处理编组和解组。 The standard solutio ...

使用转义属性的JSON到Java对象反序列化(JSON to Java object deserialization with escaped properties)

似乎没有办法配置ObjectMapper来默认处理此行为。 解决方案是创建自定义JsonDeserializer : public class Wrapper { public Delivery delivery; } public class Delivery { @JsonDeserialize(using = ProviderResponseDeserializer.class) public ProviderResponse providerResponse; } ...