用不同的语言反序列化

时间:2008-08-27 04:18:10

标签: java serialization log4j

log4j网络适配器将事件作为序列化java对象发送。我希望能够捕获此对象并使用其他语言(python)对其进行反序列化。这可能吗?

注意网络捕获很容易;它只是一个TCP套接字并在流中读取。困难在于反序列化部分

6 个答案:

答案 0 :(得分:5)

一般来说,没有。

Java序列化的流格式定义为in this document,但您需要访问原始类定义(以及将其加载到Java运行时)以将流数据转换回接近原始对象的内容。例如,类可以定义writeObject()和readObject()方法来自定义它们自己的序列化表单。

编辑::lubos hasko建议使用一个小程序来反序列化Python前面的对象,但问题是为了使这个工作,你的“小java程序”需要加载它可能反序列化的所有相同类的相同版本。如果你从一个应用程序接收日志消息,这是很棘手的,如果你要复用多个日志流,那真的很棘手。无论哪种方式,它都不会有点再强制编程。 edit2:我可能在这里错了,我不知道是什么序列化的。如果它只是log4j类你应该没问题。另一方面,它可以记录任意异常,如果他们被放入流中,我的观点也就是。)

自定义log4j网络适配器并使用更容易反序列化的表单替换原始序列化会更容易(例如,您可以使用XStream将对象转换为XML表示形式)

答案 1 :(得分:2)

理论上,这是可能的。 Java Serialization与Javaland中的几乎所有内容一样,都是标准化的。因此,可以根据Python中的标准实现反序列化器。但是,Java Serialization格式不是为跨语言使用而设计的,序列化格式与JVM中对象的表示方式密切相关。虽然在Python中实现JVM肯定是一个有趣的练习,但它可能不是你想要的( - :

还有其他(数据)序列化格式专门设计为与语言无关。它们通常通过将数据格式剥离到最低限度(数字,字符串,序列,字典和那就是它)来工作,因此需要在两端进行一些工作来将富对象表示为哑数据结构的图形(和副)亦然)。

两个例子是JSON (JavaScript Object Notation)YAML (YAML Ain't Markup Language)

ASN.1 (Abstract Syntax Notation One)是另一种数据序列化格式。 ASN.1不是将格式降低到易于理解的程度,而是自我描述,这意味着解码流所需的所有信息都在流本身内进行编码。

当然,XML (eXtensible Markup Language)也会起作用,前提是它不仅用于提供Java对象的“内存转储”的文本表示,而且是一种实际的抽象,语言无关的编码。

所以,长话短说:最好的办法是尝试强制log4j登录上述格式之一,用这样做的东西替换log4j或尝试以某种方式拦截对象之前在离开Javaland之前通过电线发送并转换它们。

实现JSON,YAML,ASN.1和XML的库可用于Java和Python(几乎所有人都知道的编程语言)。

答案 2 :(得分:1)

从理论上讲,这是可能的。现在实际上有多困难取决于是否记录了Java序列化格式。我猜,不是。 修改 oops, I was wrong, thanks Charles

无论如何,我建议您这样做

  1. 从log4j&在您自己的小Java程序中反序列化Java对象。

  2. 现在再次拥有该对象时,请使用您自己的自定义格式化程序对其进行序列化。

    提示: 也许您甚至不必编写自己的自定义格式化程序。例如,JSON (scroll down for libs)具有Python和Java库,因此理论上您可以使用Java库来序列化对象和Python等效库以对其进行反序列化

  3. 将输出流发送到python应用程序并反序列化

  4.   

    Charles写道:

         

    问题在于此   工作,你的“小java程序”   需要加载所有版本的相同版本   可能与它相同的类   反序列化。如果你这样,这很棘手   从一个应用程序接收日志消息,   如果你真的很狡猾   多路复用多个日志流。   无论哪种方式,它都不会是一个   小程序了。

    难道你不能只在你自己的java进程中引用Java log4j库吗?我只是在这里提供适用于任何一种语言的一般建议(问题的名称是非常语言不可知的,所以我只提供了一个通用的解决方案)。无论如何,我对log4j并不熟悉,也不知道你是否可以“注入”自己的序列化器。如果可以,那么你的建议当然要好得多,也更清洁。

答案 3 :(得分:1)

我建议移动到第三方格式(通过创建自己的log4j适配器等),两种语言都能理解并且可以轻松编组/解组,例如: XML。

答案 4 :(得分:1)

我不是Python专家所以我不能评论如何解决您的问题,但如果您有.NET程序,您可以使用IKVM.NET轻松地反序列化Java对象。我通过为写入Socket appender的Log4J日志消息创建.NET Client来实验这一点,并且它运行得非常好。

对不起,如果这个答案在这里没有意义的话。

答案 5 :(得分:0)

如果您可以在接收方拥有JVM并且序列化数据的类定义,并且您只想使用Python而不使用其他语言,那么您可以使用Jython:

  • 您将使用正确的Java方法反序列化您收到的内容
  • 然后你处理你得到的Python代码
相关问题