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