Make Logger properly serializable using proxy class.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/37f85123
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/37f85123
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/37f85123

Branch: refs/heads/LOG4J2-1161
Commit: 37f8512339da826c8c0be1c4aa30ed2840e48c13
Parents: 237d9a4
Author: Matt Sicker <boa...@gmail.com>
Authored: Wed Oct 21 00:13:36 2015 -0500
Committer: Matt Sicker <boa...@gmail.com>
Committed: Wed Oct 21 00:13:36 2015 -0500

----------------------------------------------------------------------
 .../org/apache/logging/log4j/core/Logger.java   | 50 ++++++++++++++++++--
 .../log4j/core/LoggerSerializationTest.java     |  2 -
 2 files changed, 46 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/37f85123/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
index 40852a5..51b3e39 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
@@ -16,6 +16,7 @@
  */
 package org.apache.logging.log4j.core;
 
+import java.io.ObjectStreamException;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -72,10 +73,14 @@ public class Logger extends AbstractLogger implements 
Supplier<LoggerConfig> {
         privateConfig = new PrivateConfig(context.getConfiguration(), this);
     }
 
+    protected Object writeReplace() throws ObjectStreamException {
+        return new LoggerProxy(getName(), getMessageFactory());
+    }
+
     /**
      * This method is only used for 1.x compatibility. Returns the parent of 
this Logger. If it doesn't already exist
      * return a temporary Logger.
-     * 
+     *
      * @return The parent Logger.
      */
     public Logger getParent() {
@@ -285,9 +290,7 @@ public class Logger extends AbstractLogger implements 
Supplier<LoggerConfig> {
     /**
      * The binding between a Logger and its configuration.
      */
-    // TODO: Should not be Serializable per EJ item 74 (2nd Ed)?
-    protected class PrivateConfig implements Serializable {
-        private static final long serialVersionUID = 1L;
+    protected class PrivateConfig {
         // config fields are public to make them visible to Logger subclasses
         /** LoggerConfig to delegate the actual logging to. */
         public final LoggerConfig loggerConfig; // SUPPRESS CHECKSTYLE
@@ -389,6 +392,28 @@ public class Logger extends AbstractLogger implements 
Supplier<LoggerConfig> {
     }
 
     /**
+     * Serialization proxy class for Logger. Since the LoggerContext and 
config information can be reconstructed on the
+     * fly, the only information needed for a Logger are what's available in 
AbstractLogger.
+     *
+     * @since 2.5
+     */
+    protected static class LoggerProxy implements Serializable {
+        private static final long serialVersionUID = 1L;
+
+        private final String name;
+        private final MessageFactory messageFactory;
+
+        public LoggerProxy(String name, MessageFactory messageFactory) {
+            this.name = name;
+            this.messageFactory = messageFactory;
+        }
+
+        protected Object readResolve() throws ObjectStreamException {
+            return new Logger(LoggerContext.getContext(), name, 
messageFactory);
+        }
+    }
+
+    /**
      * Returns a String representation of this instance in the form {@code 
"name:level[ in context_name]"}.
      * 
      * @return A String describing this Logger instance.
@@ -402,4 +427,21 @@ public class Logger extends AbstractLogger implements 
Supplier<LoggerConfig> {
         final String contextName = context.getName();
         return contextName == null ? nameLevel : nameLevel + " in " + 
contextName;
     }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        final Logger that = (Logger) o;
+        return getName().equals(that.getName());
+    }
+
+    @Override
+    public int hashCode() {
+        return getName().hashCode();
+    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/37f85123/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerSerializationTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerSerializationTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerSerializationTest.java
index f725089..2637de5 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerSerializationTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerSerializationTest.java
@@ -22,10 +22,8 @@ import java.util.Collection;
 
 import org.apache.logging.log4j.AbstractSerializationTest;
 import org.apache.logging.log4j.LogManager;
-import org.junit.Ignore;
 import org.junit.runners.Parameterized.Parameters;
 
-@Ignore("WIP: LOG4J2-801] org.apache.logging.log4j.core.Logger should be 
serializable")
 public class LoggerSerializationTest extends AbstractSerializationTest {
 
     @Parameters

Reply via email to