2008-08-27 26 views
5

El adaptador de red log4j envía eventos como un objeto java serializado. Me gustaría poder capturar este objeto y deserializarlo en un lenguaje diferente (python). es posible?Deserializar en un idioma diferente

NOTA La captura de red es fácil; es solo un socket TCP y leyendo en una secuencia. La dificultad es la parte deserializante

Respuesta

5

Generalmente, no. El formato de secuencia para la serialización de Java se define como in this document, pero necesita acceder a las definiciones de clase originales (y un tiempo de ejecución de Java para cargarlas) para volver a convertir los datos de la secuencia en algo que se acerque a los objetos originales. Por ejemplo, las clases pueden definir los métodos writeObject() y readObject() para personalizar su propio formulario serializado.

(de edición: lubos Hasko sugiere tener un pequeño programa Java para deserializar los objetos en frente de Python, pero el problema es que para que esto funcione, el "pequeño programa en Java" tiene que cargar las mismas versiones de todos las mismas clases que podría deserializar. Lo cual es complicado si recibes mensajes de registro de una aplicación, y realmente complicado si estás multiplexando más de una secuencia de registro. De cualquier manera, ya no será un pequeño programa. edit2: Podría estar equivocado aquí, no sé qué se serializa. Si solo se trata de clases log4j, debería estar bien. Por otro lado, es posible registrar excepciones arbitrarias, y si se ponen en la transmisión como bueno, mi punto es.)

Sería mucho más fácil personalizar el adaptador de red log4j y reemplazar la serialización sin procesar con una forma más fácilmente deserializada (por ejemplo, podría usar XStream para convertir el objeto en una representación XML)

+0

serialización enlace especificación ahora conduce a una página general. Creo que este es el enlace correcto: https://docs.oracle.com/javase/7/docs/platform/serialization/spec/serialTOC.html – nacho4d

1

En teoría es posible. Ahora, lo difícil que puede ser en la práctica depender de si el formato de serialización de Java está documentado o no. Supongo que no lo es. editar:oops, I was wrong, thanks Charles.

De todos modos, esto es lo que sugiero que hagas

  1. captura de log4j & deserializar objetos Java en su propio pequeño programa en Java.

  2. ahora cuando vuelva a tener el objeto, serialícelo usando su propio formateador personalizado.

    Consejo: Quizás ni siquiera tenga que escribir su propio formateador personalizado.por ejemplo, JSON (scroll down for libs) tiene librerías para Python y Java, por lo que en teoría podría utilizar la biblioteca de Java para serializar los objetos y Python biblioteca equivalente a deserializar que la corriente de salida

  3. enviar a la aplicación de pitón y deserializar que

Charles escribió:

el problema es que para este funcione, el "pequeño programa en java" necesita cargar las mismas versiones de todas las las mismas clases que podría deserializar. Lo cual es complicado si está recibiendo mensajes de registro de una aplicación, y realmente complicado si está multiplexando más de una secuencia de registro. De cualquier manera, ya no va a ser un pequeño programa .

¿No puede simplemente hacer referencia a las bibliotecas de Java log4j en su propio proceso de Java? Solo estoy dando consejos generales que se aplican a cualquier par de idiomas (el nombre de la pregunta es bastante independiente del idioma, así que acabo de proporcionar una de las soluciones genéricas). De todos modos, no estoy familiarizado con log4j y no sé si puede "inyectar" su propio serializador en él. Si puede, entonces, por supuesto, su sugerencia es mucho mejor y más clara.

1

Recomendaría cambiar a un formato de terceros (mediante la creación de sus propios adaptadores log4j, etc.) que ambos idiomas entiendan y puedan alinearse/desemparejarse fácilmente, p. Ej. XML.

+0

JSON también funcionaría. –

2

Teóricamente, es posible. La serialización Java, como casi todo en Javaland, está estandarizada. Entonces, usted podría implementar un deserializador según ese estándar en Python. Sin embargo, el formato de serialización de Java no está diseñado para uso en varios idiomas, el formato de serialización está estrechamente relacionado con la forma en que se representan los objetos dentro de la JVM. Si bien la implementación de una JVM en Python es seguramente un ejercicio divertido, probablemente no sea lo que estás buscando (-:

Existen otros formatos de serialización (de datos) que están específicamente diseñados para ser independientes del idioma. los formatos de datos hasta el mínimo (número, cadena, secuencia, diccionario y eso es todo) y por lo tanto requiere un poco de trabajo en ambos extremos para representar un objeto rico como un gráfico de estructuras de datos tontas (y viceversa).

Dos ejemplos son JSON (JavaScript Object Notation) y YAML (YAML Ain't Markup Language).

ASN.1 (Abstract Syntax Notation One) es otro formato de serialización de datos. En lugar de dumbing la fo Hasta el punto en que se puede entender fácilmente, ASN.1 es autodescriptivo, lo que significa que toda la información necesaria para decodificar una transmisión está codificada dentro de la misma transmisión.

Y, por supuesto, XML (eXtensible Markup Language), también funcionará, siempre que no solo se utilice para proporcionar una representación textual de un "volcado de memoria" de un objeto Java, sino una codificación abstracta abstracta, independiente del lenguaje.

Por lo tanto, para resumir: su mejor opción es intentar obligar a log4j a iniciar sesión en uno de los formatos mencionados anteriormente, reemplazar log4j con algo que hace eso o intentar interceptar de alguna manera los objetos antes de que se envían por el cable y los convierten antes de salir de Javaland.

Las bibliotecas que implementan JSON, YAML, ASN.1 y XML están disponibles tanto para Java como para Python (y casi todos los lenguajes de programación conocidos por el hombre).

1

Bueno, no soy un experto en Python, así que no puedo comentar sobre cómo resolver su problema, pero si tiene un programa en .NET, puede usar IKVM.NET para deserializar objetos Java fácilmente. Experimenté esto creando .NET Client para Log4J, mensajes de registro escritos en Socket appender y funcionó muy bien.

Lo siento, si esta respuesta no tiene sentido aquí.

0

Si usted puede tener una JVM en el lado receptor y las definiciones de clase para los datos serializados, y sólo desea utilizar Python y ningún otro idioma, entonces puede usar Jython:

  • que habría deserializar lo que recibió utilizando los métodos de Java correctos
  • y luego procesar lo que se obtiene con el código Python que
Cuestiones relacionadas