Сведения о вопросе

profi

08:28, 3rd August, 2020

Теги

java   serialization   log4j    

Десериализация на другом языке

Просмотров: 506   Ответов: 6

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

Обратите внимание, что захват сети прост; это просто сокет TCP и чтение в потоке. Трудность заключается в десериализующей части



  Сведения об ответе

repe

12:33, 25th August, 2020

В общем, нет.

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

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

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


  Сведения об ответе

DINO

00:02, 17th August, 2020

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

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

Два примера - это JSON (обозначение объекта JavaScript) и YAML (язык YAML-это не язык Markup) .

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

И, конечно , XML (язык eXtensible Markup) тоже будет работать, при условии, что он используется не только для обеспечения текстового представления "memory dump" объекта Java, но и для реальной абстрактной, языковой агностической кодировки.

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

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


  Сведения об ответе

VCe znayu

11:44, 24th August, 2020

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

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

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

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

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

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

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

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

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


  Сведения об ответе

COOL

21:23, 11th August, 2020

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


  Сведения об ответе

PAGE

17:03, 13th August, 2020

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

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


  Сведения об ответе

DINO

03:30, 28th August, 2020

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

  • вы бы десериализовали то, что вы получили, используя правильные методы Java
  • а потом вы обрабатываете то, что получаете с собой Python код


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться