用其他语言反序列化
log4j网络适配器将事件作为序列化的Java对象发送。我希望能够捕获此对象并将其反序列化为另一种语言(python)。这可能吗?
注意网络捕获很容易;它只是一个TCP套接字,并在流中读取。困难是反序列化部分
解决方案
回答
通常,不会。
本文档中定义了Java序列化的流格式,但是我们需要访问原始类定义(以及将它们加载到Java运行时中)以将流数据转换回接近原始对象的内容。例如,类可以定义writeObject()和readObject()方法以自定义其自己的序列化形式。
(编辑:lubos hasko建议使用一个小的Java程序对Python前面的对象进行反序列化,但是问题在于,要使其正常工作,"小java程序"需要加载所有相同类的相同版本。反序列化:如果我们从一个应用程序接收日志消息,这将很棘手;如果我们要多路复用一个以上的日志流,这将非常棘手;无论哪种方式,它都不再是一个小程序了。在这里,我不知道要序列化的内容。如果只是log4j类,那应该没问题。另一方面,可以记录任意异常,如果它们也被放入流中,我的观点就是如此。)
自定义log4j网络适配器并将原始序列化替换为更易于反序列化的形式会容易得多(例如,我们可以使用XStream将对象转换为XML表示形式)
回答
从理论上讲,这是可能的。现在在实践中可能有多难,取决于是否记录了Java序列化格式。我想不是。编辑:哎呀,我错了,谢谢查尔斯。
无论如何,这是我建议我们做的
- 从log4j捕获并在我们自己的小型Java程序中反序列化Java对象。
- 现在,当我们再次拥有该对象时,请使用自己的自定义格式化程序对其进行序列化。提示:也许我们甚至不必编写自己的自定义格式化程序。例如,JSON(向下滚动到libs)具有适用于Python和Java的库,因此理论上我们可以使用Java库来序列化对象,而使用Python等效库来反序列化它
- 将输出流发送到python应用程序并反序列化
Charles wrote: the problem is that for this to work, your "little java program" needs to load the same versions of all the same classes that it might deserialize. Which is tricky if you're receiving log messages from one app, and really tricky if you're multiplexing more than one log stream. Either way, it's not going to be a little program any more.
我们不能只是在自己的Java进程中简单地引用Java log4j库吗?我只是在这里提供适用于任何一对语言的一般建议(问题的名称与语言无关,因此我只提供了一种通用解决方案)。无论如何,我对log4j并不熟悉,也不知道是否可以将自己的序列化器"注入"到其中。如果可以的话,那么建议当然会更好,更清洁。
回答
我建议我们改用两种语言都可以理解并且可以轻松编组/解组的第三方格式(通过创建自己的log4j适配器等),例如XML。
回答
从理论上讲,这是可能的。就像Javaland中的几乎所有内容一样,Java序列化是标准化的。因此,我们可以根据该标准在Python中实现反序列化器。但是,Java序列化格式不是为跨语言使用而设计的,序列化格式与在JVM中表示对象的方式紧密相关。虽然用Python实现JVM当然是一个有趣的练习,但它可能并不是我们想要的(-:
还有其他(数据)序列化格式,这些格式专门设计为与语言无关。他们通常通过将数据格式剥离到最低限度(数字,字符串,序列,字典等)来工作,因此需要在两端进行一点工作才能将丰富的对象表示为哑数据结构图(反之亦然)。反之亦然)。
两个示例是JSON(JavaScript对象表示法)和YAML(YAML非标记语言)。
ASN.1(抽象语法符号1)是另一种数据序列化格式。 ASN.1可以自我描述,而不是将格式简化到容易理解的程度,这意味着对流进行解码所需的所有信息都在流本身中进行了编码。
而且,当然,XML(可扩展标记语言)也可以使用,只要它不仅用于提供Java对象的"内存转储"的文本表示,而且可以提供实际的抽象的,与语言无关的编码。
因此,总而言之:我们最好的选择是尝试以上述格式之一强迫log4j记录日志,用做到这一点的方法替换log4j或者尝试以某种方式截获对象,然后再通过在离开Javaland之前先进行连线并进行转换。
实现JSON,YAML,ASN.1和XML的库可用于Java和Python(几乎人类已知的每种编程语言)。
回答
好吧,我不是Python专家,所以我无法评论如何解决问题,但是如果我们在.NET中拥有程序,则可以使用IKVM.NET轻松地反序列化Java对象。我已经通过为写入Socket添加程序的Log4J日志消息创建.NET Client进行了试验,并且效果很好。
很抱歉,如果这个答案在这里没有意义。
回答
如果在接收端可以有一个JVM,并且可以为序列化数据提供类定义,并且只想使用Python而没有其他语言,则可以使用Jython:
- 我们将使用正确的Java方法反序列化收到的内容
- 然后处理Python代码带来的好处