Frage

Ich bin mit Java 1.4 mit Log4J.

Einige meiner Code beinhaltet die Serialisierung und Deserialisierung Wert Objekte (POJOs).

Jeder meiner POJOs erklärt einen Logger mit

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

Der Serializer klagt über org.apache.log4j.Logger nicht Serializable ist.

Sollte ich

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

statt?

War es hilfreich?

Lösung

Wie wäre es ein statisches Logger? Oder benötigen Sie eine andere Logger Referenz für jede Instanz der Klasse? Statische Felder werden standardmäßig nicht serialisiert; Sie können Felder erklären ausdrücklich, mit einer privaten, statisch, letzten Reihe von ObjectStreamField genannt serialPersistentFields serialisiert. Siehe Oracle-Dokumentation

Hinzugefügt Inhalt: Wie Sie verwenden getLogger (getClass ()) , werden Sie den gleichen Logger jeweils verwenden. Wenn Sie für jede Instanz separate Logger verwenden wollen, müssen Sie in dem getLogger () -Methode auf dem Namen des Loggers unterscheiden. z.B. getLogger (getClass (). getName () + hashCode ()). Sie sollten dann das transiente Attribut verwenden, um sicherzustellen, dass der Logger nicht serialisiert wird.

Andere Tipps

Der Logger muss statisch; dies würde es nicht serialisierbaren machen.

Es gibt keinen Grund Logger nicht statisch zu machen, wenn Sie einen guten Grund haben, es zu tun.

Wenn Sie wirklich will den transienten Ansatz gehen Sie benötigen, um das Protokoll zurückgesetzt werden, wenn das Objekt deserialisiert wird. Die Art und Weise, das zu tun ist, um die Methode zu implementieren:

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

Die javadocs für Serializable Informationen hat auf dieser Methode.

Ihre Umsetzung wird in etwa so aussehen:

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

Wenn Sie dies nicht tun, dann loggt nach Deserialisieren das Objekt null sein.

Entweder Ihr Logger Feld als statische oder als vorübergehende erklären.

gewährleisten Beide Wege der write () -Methode nicht das Feld während der Serialisierung in den Ausgabestream zu schreiben versuchen.

In der Regel Logger Felder sind statisch deklariert, aber wenn Sie es brauchen erklären es transiente nur eine Instanz Feld zu sein, wie der in der Regel für jeden Nicht-serializable Feld getan. Bei der Deserialisierung wird das Logger Feld null sein, obwohl, so dass Sie einen readObject- () -Methode implementieren müssen, um es richtig zu initialisieren.

Versuchen Sie die Logger statische stattdessen machen. Dann sind Sie nicht über die Serialisierung haben zu kümmern, weil sie von der Klassenlader gehandhabt wird.

Diese Art von Fällen, insbesondere in EJB, wird am besten im Allgemeinen über die Thread-Lokal Zustand gehandhabt. Normalerweise ist der Anwendungsfall ist so etwas wie Sie eine bestimmte Transaktion haben, die ein Problem stößt, und Sie müssen erhöhen Anmeldung für diese Operation zu debuggen, so dass Sie die detaillierte Protokollierung auf das Problem erzeugen kann. Einigen Durch Gewinde lokalen Zustand über die Transaktion und verwenden, dass die korrekten Logger auszuwählen. Ehrlich gesagt weiß ich nicht, wo es von Vorteil wäre, das Niveau auf einer Instanz in dieser Umgebung zu setzen, da die Zuordnung der Instanzen in die Transaktion ein Container-Level-Funktion sein sollte, werden Sie nicht tatsächlich haben die Kontrolle über die Instanz in eine verwendet wird gegebene Transaktion trotzdem.

Auch in Fällen, in denen Sie mit einem DTO zu tun hat es im Allgemeinen nicht eine gute Idee ist, Ihr System so zu gestalten, dass eine bestimmte spezifische Instanz ist erforderlich, weil das Design leicht in einer Weise, dass eine schlechte Wahl entwickeln kann . Sie könnten von nun entlang einem Monat kommen und dass die Effizienzüberlegungen (Caching oder eine andere Lebenszyklus ändernden Optimierung) entscheiden wird Ihre Annahme über die Zuordnung von Instanzen in Einheiten der Arbeit brechen.

Wenn Sie die Logger sein pro-Instanz wollen, dann ja, würden Sie wollen, dass es vorübergehende machen, wenn Sie gehen, um Ihre Objekte serialisieren. Log4J Loggers sind nicht serialisierbar, nicht in der Version von Log4J, die ich sowieso bin mit, wenn Sie also nicht Ihre Logger Felder transiente machen Sie Ausnahmen auf die Serialisierung erhalten werden.

Loggers sind nicht serialisierbar, so dass Sie transiente verwenden müssen, wenn sie in Instanzfelder zu speichern. Wenn Sie den Logger zur Wiederherstellung nach der Deserialisierung Sie die Ebene speichern kann (String) Indide Ihr Objekt, das serialisiert bekommt.

Es gibt gute Gründe, eine Instanz Logger zu verwenden. Ein sehr guter Anwendungsfall ist, so können Sie den Logger in einer Super-Klasse deklarieren und verwenden Sie es in allen Unterklassen (der einzige Nachteil ist, dass Protokolle von der Super-Klasse sind mit der Unterklasse zugeordnet werden, aber es ist in der Regel leicht zu sehen, dass).

(Wie andere Verwendung statische oder transiente erwähnt hat).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top