Domanda

L'adattatore di rete log4j invia eventi come oggetto Java serializzato.Mi piacerebbe poter catturare questo oggetto e deserializzarlo in un linguaggio diverso (python).È possibile?

NOTA L'acquisizione in rete è semplice;è solo un socket TCP e legge in un flusso.La difficoltà è la parte di deserializzazione

È stato utile?

Soluzione

In generale no.

Il formato del flusso per la serializzazione Java è definito in questo documento, ma è necessario accedere alle definizioni delle classi originali (e un runtime Java in cui caricarle) per trasformare nuovamente i dati del flusso in qualcosa che si avvicina agli oggetti originali.Ad esempio, le classi possono definire i metodi writeObject() e readObject() per personalizzare il proprio modulo serializzato.

(modificare: lubos hasko suggerisce di avere un piccolo programma Java per deserializzare gli oggetti davanti a Python, ma il problema è che affinché funzioni, il tuo "piccolo programma Java" deve caricare le stesse versioni di tutte le stesse classi che potrebbe deserializzare.Il che è complicato se ricevi messaggi di registro da un'app e davvero complicato se stai multiplexando più di un flusso di registro.In ogni caso non sarà più un programmino. modifica2: Potrei sbagliarmi qui, non so cosa venga serializzato.Se sono solo classi log4j dovresti stare bene.D'altra parte, è possibile registrare eccezioni arbitrarie e, se anche queste vengono inserite nello stream, il mio punto resta valido.)

Sarebbe molto più semplice personalizzare l'adattatore di rete log4j e sostituire la serializzazione grezza con un modulo più facilmente deserializzato (ad esempio potresti utilizzare XStream per trasformare l'oggetto in una rappresentazione XML)

Altri suggerimenti

Teoricamente, è possibile.La serializzazione Java, come praticamente tutto in Javaland, è standardizzata.Quindi tu Potevo implementare un deserializzatore secondo quello standard in Python.Tuttavia, il formato di serializzazione Java non è progettato per l'uso in più linguaggi, il formato di serializzazione è strettamente legato al modo in cui gli oggetti sono rappresentati all'interno della JVM.Sebbene implementare una JVM in Python sia sicuramente un esercizio divertente, probabilmente non è quello che stai cercando (-:

Esistono altri formati di serializzazione (dati) progettati specificamente per essere indipendenti dalla lingua.Di solito funzionano riducendo i formati dei dati al minimo indispensabile (numero, stringa, sequenza, dizionario e basta) e quindi richiedono un po' di lavoro su entrambe le estremità per rappresentare un oggetto ricco come un grafico di strutture di dati stupide (e viceversa viceversa).

Due esempi sono JSON (notazione oggetto JavaScript) E YAML (YAML non è un linguaggio di markup).

ASN.1 (Notazione di sintassi astratta uno) è un altro formato di serializzazione dei dati.Invece di ridurre il formato al punto in cui può essere facilmente compreso, ASN.1 è autodescrittivo, il che significa che tutte le informazioni necessarie per decodificare un flusso sono codificate all'interno del flusso stesso.

E naturalmente, XML (linguaggio di markup eXtensible), funzionerà, a condizione che non venga utilizzato solo per fornire una rappresentazione testuale di un "dump della memoria" di un oggetto Java, ma una vera codifica astratta e indipendente dal linguaggio.

Quindi, per farla breve:la soluzione migliore è provare a costringere log4j ad accedere in uno dei formati sopra menzionati, sostituire log4j con qualcosa che lo faccia o provare a intercettare in qualche modo gli oggetti prima che vengano inviati in rete e convertirli prima di lasciare Javaland.

Le librerie che implementano JSON, YAML, ASN.1 e XML sono disponibili sia per Java che per Python (e praticamente per tutti i linguaggi di programmazione conosciuti dall'uomo).

Consiglierei di passare a un formato di terze parti (creando i propri adattatori log4j ecc.) che entrambe le lingue comprendano e possano facilmente eseguire il marshalling/unmarshal, ad es.XML.

In teoria è possibile.Ora, quanto potrebbe essere difficile in pratica dipende dal fatto che il formato di serializzazione Java sia documentato o meno.Immagino di no. modificare: ops, mi sbagliavo, grazie Carlo.

Ad ogni modo, questo è quello che ti suggerisco di fare

  1. cattura da log4j e deserializza l'oggetto Java nel tuo piccolo programma Java.

  2. ora, quando hai di nuovo l'oggetto, serializzalo utilizzando il tuo formattatore personalizzato.

    Mancia: Forse non devi nemmeno scrivere il tuo formattatore personalizzato.Per esempio, JSON (scorrere verso il basso per le librerie) ha librerie per Python e Java, quindi in teoria potresti utilizzare la libreria Java per serializzare i tuoi oggetti e la libreria equivalente Python per deserializzarlo

  3. invia il flusso di output alla tua applicazione Python e deserializzalo

Carlo ha scritto:

Il problema è che affinché questo funzioni, il tuo "piccolo programma Java" deve caricare le stesse versioni di tutte le stesse classi che potrebbe deserializzare.Il che è complicato se ricevi messaggi di registro da un'app e davvero complicato se stai multiplexo più di un flusso di registro.Ad ogni modo, non sarà più un piccolo programma.

Non puoi semplicemente fare riferimento alle librerie Java log4j nel tuo processo Java?Qui sto solo dando consigli generali applicabili a qualsiasi coppia di lingue (il nome della domanda è piuttosto indipendente dalla lingua, quindi ho appena fornito una delle soluzioni generiche).Ad ogni modo, non ho familiarità con log4j e non so se puoi "iniettarvi" il tuo serializzatore.Se puoi, ovviamente il tuo suggerimento è molto migliore e più pulito.

Beh, non sono un esperto di Python quindi non posso commentare come risolvere il tuo problema, ma se hai un programma in .NET puoi usare IKVM.NET per deserializzare facilmente gli oggetti Java.L'ho sperimentato creando .NET Client per messaggi di registro Log4J scritti nell'appender Socket e ha funzionato davvero bene.

Mi dispiace se questa risposta non ha senso qui.

Se puoi avere una JVM sul lato ricevente e le definizioni di classe per i dati serializzati e desideri utilizzare solo Python e nessun altro linguaggio, puoi utilizzare Jython:

  • deserializzeresti ciò che hai ricevuto utilizzando i metodi Java corretti
  • e poi elabori ciò che ottieni con il tuo codice Python
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top