Domanda

Sto usando Java 1.4 con Log4J.

Alcune delle mie codice prevede che la serializzazione e la deserializzazione di oggetti di valore (Pojo).

Ogni mio Pojo dichiara un logger con

private final Logger log = Logger.getLogger(getClass());

Il serializzatore si lamenta di org.apache.log4j.Logger non essere Serializzabile.

Devo usare

private final transient Logger log = Logger.getLogger(getClass());

invece?

È stato utile?

Soluzione

Come sull'utilizzo di una statica logger?O avete bisogno di una diversa logger di riferimento per ogni istanza della classe?Campi statici non sono serializzati per impostazione predefinita;è possibile dichiarare in modo esplicito i campi per serializzare con un privato, statico, array finale di ObjectStreamField nome serialPersistentFields. Vedere la documentazione di Oracle

Aggiunta di contenuto:Come si utilizza getLogger(getClass()), si utilizzerà la stessa logger in ogni istanza.Se si desidera utilizzare diversi logger per ogni istanza è necessario differenziare il nome del dispositivo nell'getLogger() -metodo.ad es.getLogger(getClass().getName() + hashCode()).Si dovrebbe quindi utilizzare il transitorio attributo per assicurarsi che lo strumento non viene serializzato.

Altri suggerimenti

Il logger deve essere statico;questo renderebbe non serializzabile.

Non c'è motivo di fare logger, non statica, a meno che non si dispone di un forte motivo per farlo.

Se si davvero vuole andare transitoria approccio, è necessario reimpostare il registro quando l'oggetto viene deserializzato.Il modo per farlo è quello di implementare il metodo:

 private void readObject(java.io.ObjectInputStream in) 
   throws IOException, ClassNotFoundException;

Il javadoc per Serializable ha informazioni su questo metodo.

L'implementazione di un qualcosa di simile a:

 private void readObject(java.io.ObjectInputStream in) 
     throws IOException, ClassNotFoundException {
   log = Logger.getLogger(...);
   in.defaultReadObject();
 }

Se non fai questo allora log sarà nulla dopo la deserializzazione di un oggetto.

Dichiarare il tuo strumento di campo statico o transitorio.

Entrambi i modi di garantire la writeObject() il metodo non tenterà di scrivere il campo per il flusso di output durante la serializzazione.

Di solito logger campi sono dichiarate static, ma se avete bisogno di essere un esempio di campo di dichiarare è transitoria, come di solito è fatto per tutti i non-serializzabile campo.Su deserializzazione il logger campo sarà null, però, così si devono implementare metodi readobject() metodo per inizializzare correttamente.

Prova a fare il Logger statico, invece.Che non hanno a cuore la serializzazione, che è gestito dalla classe loader.

Questi tipi di casi, in particolare in EJB, sono generalmente gestiti tramite thread nel territorio dello stato.Di solito il caso d'uso è qualcosa di simile a una determinata operazione, che è verificato un problema e hai bisogno di elevare la registrazione di debug per l'operazione in modo che si può generare un log dettagliato sul problema di funzionamento.Portare alcuni thread nel territorio dello stato in tutta la transazione da utilizzare per selezionare la corretta logger.Francamente non so dove sarebbe utile per impostare il livello su un'ISTANZA in questo ambiente, perché la mappatura delle istanze in la transazione dovrebbe essere un contenitore di funzione di livello, non avere il controllo di istanza che viene utilizzato in una determinata operazione comunque.

Anche nei casi in cui si abbia a che fare con un DTO non è generalmente una buona idea per progettare il sistema in modo che una determinata istanza è necessaria perché il progetto può facilmente evolvere in modi che fanno si che una cattiva scelta.Si potrebbe venire lungo un mese da oggi e decidere di considerazioni di efficienza (caching o di qualche altro ciclo di vita cambiando optimization) si rompono le ipotesi circa la mappatura delle istanze in unità di lavoro.

Se si desidera che il Logger per esempio, allora sì, si vuole fare è transitoria, se si sta andando per la serializzazione di oggetti.Log4J Logger non sono serializzabili, non nella versione di Log4J che sto utilizzando in ogni caso, quindi se non fai il tuo strumento di campi transitoria avrai eccezioni di serializzazione.

Logger non sono serializzabili quindi è necessario utilizzare transitoria, quando la loro memorizzazione in campi di istanza.Se si desidera ripristinare il logger dopo la deserializzazione è possibile memorizzare il Livello (Stringa) direttamente l'oggetto che viene serializzato.

Ci sono buone ragioni per utilizzare un'istanza logger.Un caso d'uso è così non si può dichiarare il logger in un super-classe e utilizzare in tutte le sotto-classi (l'unico aspetto negativo è che registri dal super-classe sono attribuiti ai sub-categoria, ma di solito è facile vedere che).

(Come altri hanno detto statici o temporaneo).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top