Вопрос

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

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

Это было полезно?

Решение

В общем, нет.

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

(редактировать: Любос Хаско предлагает иметь небольшую Java-программу для десериализации объектов перед Python, но проблема в том, что для того, чтобы это работало, ваша «маленькая Java-программа» должна загружать одни и те же версии всех тех же классов, которые она может десериализовать.Это сложно, если вы получаете сообщения журнала из одного приложения, и очень сложно, если вы мультиплексируете более одного потока журналов.В любом случае, это больше не будет маленькой программой. редактировать2: Я могу ошибаться, я не знаю, что сериализуется.Если это просто классы log4j, все будет в порядке.С другой стороны, можно регистрировать произвольные исключения, и если они также попадают в поток, моя точка зрения остается в силе.)

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • вы бы десериализовали полученное, используя правильные методы Java.
  • а затем вы обрабатываете то, что получаете, с кодом Python
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top