Десериализовать на другом языке - PullRequest
5 голосов
/ 27 августа 2008

Сетевой адаптер log4j отправляет события в виде сериализованного объекта Java. Я хотел бы иметь возможность захватить этот объект и десериализовать его на другом языке (Python). Возможно ли это?

ПРИМЕЧАНИЕ Захват сети прост; это просто сокет TCP и чтение в потоке. Трудность заключается в десериализации части

Ответы [ 6 ]

5 голосов
/ 27 августа 2008

Как правило, нет.

Формат потока для сериализации Java определен в этом документе , но вам нужен доступ к исходным определениям классов (и среде выполнения Java для их загрузки), чтобы превратить данные потока обратно в нечто, приближающееся к оригинальные предметы. Например, классы могут определять методы writeObject () и readObject () для настройки своей собственной сериализованной формы.

( edit: lubos hasko предлагает использовать небольшую java-программу для десериализации объектов перед Python, но проблема в том, что для того, чтобы это работало, ваша "маленькая java-программа" должна загрузить то же самое версии всех тех же классов, которые он может десериализовать. Это сложно, если вы получаете сообщения журнала из одного приложения, и действительно сложно, если вы мультиплексируете более одного потока журнала. В любом случае, это не будет маленькой программой больше. edit2: Я могу ошибаться здесь, я не знаю, что сериализуется. Если это просто классы log4j, то у вас все будет хорошо. С другой стороны, возможно регистрировать произвольные исключения, и если они попадают в поток, а моя точка зрения стоит.)

Было бы намного проще настроить сетевой адаптер log4j и заменить необработанную сериализацию более упрощенной десериализацией (например, вы можете использовать XStream, чтобы превратить объект в представление XML)

2 голосов
/ 27 августа 2008

Теоретически , это возможно. Сериализация Java, как и почти все в Javaland, стандартизирована. Таким образом, вы можете реализовать десериализатор в соответствии с этим стандартом в Python. Однако формат сериализации Java не предназначен для использования на нескольких языках, формат сериализации тесно связан с тем, как объекты представляются внутри JVM. Хотя реализация JVM в Python, безусловно, является увлекательным занятием, оно, вероятно, не то, что вы ищете (-:

Существуют и другие форматы сериализации (данных), специально разработанные с учетом языка. Обычно они работают, сокращая форматы данных до минимума (число, строка, последовательность, словарь и все) и, таким образом, требуют немного работы с обоих концов, чтобы представить богатый объект в виде графа глупых структур данных (и наоборот). Versa).

Два примера: JSON (нотация объектов JavaScript) и YAML (язык разметки YAML) .

ASN.1 (Абстрактная синтаксическая нотация номер один) - это другой формат сериализации данных. Вместо того, чтобы придавать формату форму, до которой его легко понять, ASN.1 самоописывает себя, то есть вся информация, необходимая для декодирования потока, кодируется в самом потоке.

И, конечно, XML (расширяемый язык разметки) также будет работать при условии, что он используется не только для предоставления текстового представления «дампа памяти» объекта Java, но и фактического абстрактное, не зависящее от языка кодирование.

Итак, короче говоря: лучше всего попытаться принудить log4j войти в один из вышеупомянутых форматов, заменить log4j чем-то, что делает это, или попытаться каким-то образом перехватить объекты, прежде чем они будут послал по телеграфу и переделал их перед тем как покинуть Джаваланд.

Библиотеки, в которых реализованы JSON, YAML, ASN.1 и XML, доступны как для Java, так и для Python (и почти для всех языков программирования, известных человеку).

1 голос
/ 27 августа 2008

Ну, я не эксперт по Python, поэтому я не могу комментировать, как решить вашу проблему, но если у вас есть программа на .NET, вы можете использовать IKVM.NET для простой десериализации объектов Java. Я экспериментировал с этим, создавая .NET Client для сообщений журнала Log4J, написанных для приложения Socket, и это работало очень хорошо.

Извините, если этот ответ здесь не имеет смысла.

1 голос
/ 27 августа 2008

Я бы порекомендовал перейти на сторонний формат (путем создания собственных адаптеров log4j и т. Д.), Который понятен обоим языкам и может легко маршалировать / демаршировать, например. XML.

1 голос
/ 27 августа 2008

Теоретически это возможно. Насколько это трудно на практике, зависит от того, задокументирован ли формат сериализации Java или нет. Я думаю, это не так. edit: упс, я был не прав, спасибо Чарльз .

Во всяком случае, это то, что я предлагаю вам сделать

  1. захват из log4j и десериализация Java-объекта в вашей собственной маленькой Java-программе.

  2. теперь, когда у вас снова есть объект, сериализуйте его, используя свой собственный форматтер.

    Подсказка: Может быть, вам даже не нужно писать свой собственный форматер. например, JSON (прокрутка вниз для библиотек) имеет библиотеки для Python и Java, поэтому теоретически вы можете использовать библиотеку Java для сериализации ваших объектов и эквивалентную библиотеку Python для ее десериализации

  3. отправить поток вывода в приложение Python и десериализовать его

Чарльз писал:

проблема в том, что для этого работать, ваша "маленькая Java-программа" нужно загружать одинаковые версии всех те же классы, что это может десериализации. Что сложно, если ты получение сообщений журнала из одного приложения, и действительно сложно, если вы мультиплексирование более одного потока журнала. В любом случае, это не будет маленькая программа больше.

Разве вы не можете просто ссылаться на библиотеки Java log4j в своем собственном процессе Java? Я просто даю общие советы, которые применимы к любой паре языков (название вопроса довольно не зависит от языка, поэтому я просто предоставил одно из общих решений). Во всяком случае, я не знаком с log4j и не знаю, сможете ли вы «внедрить» в него свой собственный сериализатор. Если вы можете, то, конечно, ваше предложение намного лучше и чище.

0 голосов
/ 20 февраля 2009

Если у вас есть JVM на принимающей стороне и определения классов для сериализованных данных, и вы хотите использовать только Python и никакой другой язык, то вы можете использовать Jython:

  • вы бы десериализовали то, что получили, используя правильные методы Java
  • и затем вы обрабатываете то, что получаете с помощью кода Python
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...