In the manual pages, can we mention that in previous versions the default
was SerializedLayout, but as of log4j-2.9 users need to explicitly specify
a layout since there is no default? I think it is important to document the
log4j version when this change took place.

On Wed, Jun 28, 2017 at 9:52 PM, <[email protected]> wrote:

> Repository: logging-log4j2
> Updated Branches:
>   refs/heads/LOG4J2-1958 [created] c1b90f961
>
>
> LOG4J2-1958 Deprecate SerializedLayout and remove it as default
>
>
> Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
> Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/
> commit/330a16f9
> Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/330a16f9
> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/330a16f9
>
> Branch: refs/heads/LOG4J2-1958
> Commit: 330a16f923a8eb34b983cc3fb255927dd9699323
> Parents: 3f45368
> Author: Mikael Ståldal <[email protected]>
> Authored: Wed Jun 28 14:50:52 2017 +0200
> Committer: Mikael Ståldal <[email protected]>
> Committed: Wed Jun 28 14:50:52 2017 +0200
>
> ----------------------------------------------------------------------
>  .../log4j/core/appender/SocketAppender.java     |  8 +++---
>  .../log4j/core/appender/mom/JmsAppender.java    |  7 +++--
>  .../log4j/core/layout/SerializedLayout.java     |  6 +++++
>  .../log4j/core/appender/SocketAppenderTest.java | 28 ++++++++++++++------
>  src/changes/changes.xml                         |  3 +++
>  src/site/xdoc/manual/appenders.xml              | 15 ++++++-----
>  src/site/xdoc/manual/layouts.xml.vm             |  9 +++++--
>  src/site/xdoc/manual/migration.xml              |  2 +-
>  8 files changed, 54 insertions(+), 24 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
> 330a16f9/log4j-core/src/main/java/org/apache/logging/log4j/
> core/appender/SocketAppender.java
> ----------------------------------------------------------------------
> diff --git 
> a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/
> appender/SocketAppender.java
> index 8c2b83d..b433403 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
> appender/SocketAppender.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
> appender/SocketAppender.java
> @@ -36,7 +36,6 @@ import org.apache.logging.log4j.core.
> config.plugins.PluginElement;
>  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
>  import org.apache.logging.log4j.core.config.plugins.validation.
> constraints.ValidHost;
>  import org.apache.logging.log4j.core.config.plugins.validation.
> constraints.ValidPort;
> -import org.apache.logging.log4j.core.layout.SerializedLayout;
>  import org.apache.logging.log4j.core.net.AbstractSocketManager;
>  import org.apache.logging.log4j.core.net.Advertiser;
>  import org.apache.logging.log4j.core.net.DatagramSocketManager;
> @@ -197,7 +196,8 @@ public class SocketAppender extends
> AbstractOutputStreamAppender<AbstractSocketM
>              final boolean bufferedIo = isBufferedIo();
>              Layout<? extends Serializable> layout = getLayout();
>              if (layout == null) {
> -                layout = SerializedLayout.createLayout();
> +                AbstractLifeCycle.LOGGER.error("No layout provided for
> SocketAppender");
> +                return null;
>              }
>
>              final String name = getName();
> @@ -280,7 +280,7 @@ public class SocketAppender extends
> AbstractOutputStreamAppender<AbstractSocketM
>       *            If {@code "true"} (default) exceptions encountered when
> appending events are logged; otherwise they
>       *            are propagated to the caller.
>       * @param layout
> -     *            The layout to use (defaults to SerializedLayout).
> +     *            The layout to use. Required, there is no default.
>       * @param filter
>       *            The Filter or null.
>       * @param advertise
> @@ -354,7 +354,7 @@ public class SocketAppender extends
> AbstractOutputStreamAppender<AbstractSocketM
>       *            If {@code "true"} (default) exceptions encountered when
> appending events are logged; otherwise they
>       *            are propagated to the caller.
>       * @param layout
> -     *            The layout to use (defaults to {@link
> SerializedLayout}).
> +     *            The layout to use. Required, there is no default.
>       * @param filter
>       *            The Filter or null.
>       * @param advertise
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
> 330a16f9/log4j-core/src/main/java/org/apache/logging/log4j/
> core/appender/mom/JmsAppender.java
> ----------------------------------------------------------------------
> diff --git 
> a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsAppender.java
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/
> appender/mom/JmsAppender.java
> index 84b88fa..906b36f 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
> appender/mom/JmsAppender.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
> appender/mom/JmsAppender.java
> @@ -39,7 +39,6 @@ import org.apache.logging.log4j.core.config.plugins.
> PluginBuilderAttribute;
>  import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
>  import org.apache.logging.log4j.core.config.plugins.PluginElement;
>  import org.apache.logging.log4j.core.config.plugins.validation.
> constraints.Required;
> -import org.apache.logging.log4j.core.layout.SerializedLayout;
>  import org.apache.logging.log4j.core.net.JndiManager;
>  import org.apache.logging.log4j.status.StatusLogger;
>
> @@ -88,7 +87,7 @@ public class JmsAppender extends AbstractAppender {
>          private char[] password;
>
>          @PluginElement("Layout")
> -        private Layout<? extends Serializable> layout =
> SerializedLayout.createLayout();
> +        private Layout<? extends Serializable> layout;
>
>          @PluginElement("Filter")
>          private Filter filter;
> @@ -128,6 +127,10 @@ public class JmsAppender extends AbstractAppender {
>                  // JmsManagerFactory has already logged an ERROR.
>                  return null;
>              }
> +            if (layout == null) {
> +                LOGGER.error("No layout provided for JmsAppender");
> +                return null;
> +            }
>              return new JmsAppender(name, filter, layout,
> ignoreExceptions, reconnectOnExceptionMessages,
>                      reconnectAttempts, reconnectIntervalMillis,
> actualJmsManager);
>          }
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
> 330a16f9/log4j-core/src/main/java/org/apache/logging/log4j/
> core/layout/SerializedLayout.java
> ----------------------------------------------------------------------
> diff --git 
> a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/SerializedLayout.java
> b/log4j-core/src/main/java/org/apache/logging/log4j/core/
> layout/SerializedLayout.java
> index 04b52e8..43700e0 100644
> --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/
> layout/SerializedLayout.java
> +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/
> layout/SerializedLayout.java
> @@ -29,7 +29,11 @@ import org.apache.logging.log4j.core.
> config.plugins.PluginFactory;
>
>  /**
>   * Formats a {@link LogEvent} in its Java serialized form.
> + *
> + * @deprecated Java Serialization has inherent security weaknesses, using
> this layout is no longer recommended.
> + * An alternative layout containing the same information is {@link
> JsonLayout} when configured with properties="true".
>   */
> +@Deprecated
>  @Plugin(name = "SerializedLayout", category = Node.CATEGORY, elementType
> = Layout.ELEMENT_TYPE, printObject = true)
>  public final class SerializedLayout extends AbstractLayout<LogEvent> {
>
> @@ -47,6 +51,7 @@ public final class SerializedLayout extends
> AbstractLayout<LogEvent> {
>
>      private SerializedLayout() {
>          super(null, null, null);
> +        LOGGER.warn("SerializedLayout is deprecated due to the inherent
> security weakness in Java Serialization. Consider using another layout,
> e.g. JsonLayout");
>      }
>
>      /**
> @@ -82,6 +87,7 @@ public final class SerializedLayout extends
> AbstractLayout<LogEvent> {
>       * Creates a SerializedLayout.
>       * @return A SerializedLayout.
>       */
> +    @Deprecated
>      @PluginFactory
>      public static SerializedLayout createLayout() {
>          return new SerializedLayout();
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
> 330a16f9/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/
> SocketAppenderTest.java
> ----------------------------------------------------------------------
> diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/
> appender/SocketAppenderTest.java b/log4j-core/src/test/java/
> org/apache/logging/log4j/core/appender/SocketAppenderTest.java
> index 64a29ae..b02ef76 100644
> --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/
> appender/SocketAppenderTest.java
> +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/
> appender/SocketAppenderTest.java
> @@ -21,10 +21,9 @@ import static org.junit.Assert.assertNotNull;
>  import static org.junit.Assert.assertTrue;
>  import static org.junit.Assert.fail;
>
> -import java.io.ByteArrayInputStream;
>  import java.io.EOFException;
>  import java.io.IOException;
> -import java.io.ObjectInputStream;
> +import java.io.InputStream;
>  import java.net.DatagramPacket;
>  import java.net.DatagramSocket;
>  import java.net.ServerSocket;
> @@ -36,6 +35,8 @@ import java.util.concurrent.BlockingQueue;
>  import java.util.concurrent.CountDownLatch;
>  import java.util.concurrent.TimeUnit;
>
> +import com.fasterxml.jackson.databind.MappingIterator;
> +import com.fasterxml.jackson.databind.ObjectMapper;
>  import org.apache.logging.log4j.Level;
>  import org.apache.logging.log4j.LoggingException;
>  import org.apache.logging.log4j.ThreadContext;
> @@ -43,6 +44,9 @@ import org.apache.logging.log4j.core.Appender;
>  import org.apache.logging.log4j.core.LogEvent;
>  import org.apache.logging.log4j.core.Logger;
>  import org.apache.logging.log4j.core.LoggerContext;
> +import org.apache.logging.log4j.core.impl.Log4jLogEvent;
> +import org.apache.logging.log4j.core.jackson.Log4jJsonObjectMapper;
> +import org.apache.logging.log4j.core.layout.JsonLayout;
>  import org.apache.logging.log4j.core.net.Protocol;
>  import org.apache.logging.log4j.core.util.Constants;
>  import org.apache.logging.log4j.core.util.Throwables;
> @@ -128,6 +132,7 @@ public class SocketAppenderTest {
>                  .withName("test")
>                  .withImmediateFail(false)
>                  .withBufferSize(bufferSize)
> +                .withLayout(JsonLayout.newBuilder().setProperties(
> true).build())
>                  .build();
>          // @formatter:on
>          appender.start();
> @@ -174,6 +179,7 @@ public class SocketAppenderTest {
>                  .withReconnectDelayMillis(-1)
>                  .withName("test")
>                  .withImmediateFail(false)
> +                .withLayout(JsonLayout.newBuilder().setProperties(
> true).build())
>                  .build();
>          // @formatter:on
>          assertNotNull(appender);
> @@ -195,6 +201,7 @@ public class SocketAppenderTest {
>                  .withReconnectDelayMillis(-1)
>                  .withName("test")
>                  .withImmediateFail(false)
> +                .withLayout(JsonLayout.newBuilder().setProperties(
> true).build())
>                  .build();
>          // @formatter:on
>          appender.start();
> @@ -220,6 +227,7 @@ public class SocketAppenderTest {
>                  .withReconnectDelayMillis(100)
>                  .withName("test")
>                  .withImmediateFail(false)
> +                .withLayout(JsonLayout.newBuilder().setProperties(
> true).build())
>                  .build();
>          // @formatter:on
>          appender.start();
> @@ -251,6 +259,7 @@ public class SocketAppenderTest {
>                  .withName("test")
>                  .withImmediateFail(false)
>                  .withIgnoreExceptions(false)
> +                .withLayout(JsonLayout.newBuilder().setProperties(
> true).build())
>                  .build();
>          // @formatter:on
>          appender.start();
> @@ -277,6 +286,7 @@ public class SocketAppenderTest {
>          private final CountDownLatch latch = new CountDownLatch(1);
>          private volatile int count = 0;
>          private final BlockingQueue<LogEvent> queue;
> +        private final ObjectMapper objectMapper = new
> Log4jJsonObjectMapper();
>
>          public UdpSocketTestServer() throws IOException {
>              this.sock = new DatagramSocket(PORT);
> @@ -302,10 +312,8 @@ public class SocketAppenderTest {
>                  while (!shutdown) {
>                      latch.countDown();
>                      sock.receive(packet);
> -                    final ObjectInputStream ois = new
> ObjectInputStream(new ByteArrayInputStream(packet.getData()));
>                      ++count;
> -                    final Object received = ois.readObject(); // separate
> lines for debugging
> -                    final LogEvent event = (LogEvent) received;
> +                    final LogEvent event = 
> objectMapper.readValue(packet.getData(),
> Log4jLogEvent.class);
>                      queue.add(event);
>                  }
>              } catch (final Throwable e) {
> @@ -331,6 +339,7 @@ public class SocketAppenderTest {
>          private volatile boolean shutdown = false;
>          private volatile int count = 0;
>          private final BlockingQueue<LogEvent> queue;
> +        private final ObjectMapper objectMapper = new
> Log4jJsonObjectMapper();
>
>          @SuppressWarnings("resource")
>          public TcpSocketTestServer(final int port) throws IOException {
> @@ -361,10 +370,13 @@ public class SocketAppenderTest {
>              try {
>                  try (final Socket socket = serverSocket.accept()) {
>                      if (socket != null) {
> -                        final ObjectInputStream ois = new
> ObjectInputStream(socket.getInputStream());
> +                        final InputStream is = socket.getInputStream();
>                          while (!shutdown) {
> -                            queue.add((LogEvent) ois.readObject());
> -                            ++count;
> +                            final MappingIterator<LogEvent>
> mappingIterator = objectMapper.readerFor(Log4jLogEvent.class).
> readValues(is);
> +                            while (mappingIterator.hasNextValue()) {
> +                                queue.add(mappingIterator.nextValue());
> +                                ++count;
> +                            }
>                          }
>                      }
>                  }
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
> 330a16f9/src/changes/changes.xml
> ----------------------------------------------------------------------
> diff --git a/src/changes/changes.xml b/src/changes/changes.xml
> index 91b1101..a171173 100644
> --- a/src/changes/changes.xml
> +++ b/src/changes/changes.xml
> @@ -31,6 +31,9 @@
>           - "remove" - Removed
>      -->
>      <release version="2.9.0" date="2017-MM-DD" description="GA Release
> 2.9.0">
> +      <action issue="LOG4J2-1958" dev="mikes" type="update">
> +        Deprecate SerializedLayout and remove it as default.
> +      </action>
>        <action issue="LOG4J2-1950" dev="ggregory" type="update"
> due-to="Pierrick HYMBERT">
>          Fix docker build with jdk9 requirements (#84).
>        </action>
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
> 330a16f9/src/site/xdoc/manual/appenders.xml
> ----------------------------------------------------------------------
> diff --git a/src/site/xdoc/manual/appenders.xml b/src/site/xdoc/manual/
> appenders.xml
> index ba1bf7d..bbb4c5f 100644
> --- a/src/site/xdoc/manual/appenders.xml
> +++ b/src/site/xdoc/manual/appenders.xml
> @@ -1295,8 +1295,7 @@ public class ConnectionFactory {
>                <td>layout</td>
>                <td>Layout</td>
>                <td>
> -                The Layout to use to format the LogEvent. If you do not
> specify a layout,
> -                this appender will use a <a href="layouts.html#
> SerializedLayout">SerializedLayout</a>.
> +                The Layout to use to format the LogEvent. Required, there
> is no default.
>                </td>
>              </tr>
>              <tr>
> @@ -1372,7 +1371,9 @@ public class ConnectionFactory {
>  <Configuration status="warn" name="MyApp">
>    <Appenders>
>      <JMS name="jmsQueue" destinationBindingName="MyQueue"
> -         factoryBindingName="MyQueueConnectionFactory"/>
> +         factoryBindingName="MyQueueConnectionFactory">
> +      <JsonLayout properties="true"/>
> +    </JMS>
>    </Appenders>
>    <Loggers>
>      <Root level="error">
> @@ -4302,7 +4303,7 @@ public class JpaLogEntity extends
> AbstractLogEventWrapperEntity {
>            <p>
>              The <code>SocketAppender</code> is an OutputStreamAppender
> that writes its output to a remote destination
>              specified by a host and port. The data can be sent over
> either TCP or UDP and can be sent in any format.
> -            The default format is to send a Serialized LogEvent. You can
> optionally secure communication with SSL.
> +            You can optionally secure communication with SSL.
>            </p>
>            <table>
>              <caption align="top"><code>SocketAppender</code>
> Parameters</caption>
> @@ -4369,7 +4370,7 @@ public class JpaLogEntity extends
> AbstractLogEventWrapperEntity {
>              <tr>
>                <td>layout</td>
>                <td>Layout</td>
> -              <td>The Layout to use to format the LogEvent. The default
> is SerializedLayout.</td>
> +              <td>The Layout to use to format the LogEvent. Required,
> there is no default.</td>
>              </tr>
>              <tr>
>                <td>reconnectionDelayMillis</td>
> @@ -4402,7 +4403,7 @@ public class JpaLogEntity extends
> AbstractLogEventWrapperEntity {
>  <Configuration status="warn" name="MyApp" packages="">
>    <Appenders>
>      <Socket name="socket" host="localhost" port="9500">
> -      <SerializedLayout />
> +      <JsonLayout properties="true"/>
>      </Socket>
>    </Appenders>
>    <Loggers>
> @@ -4419,7 +4420,7 @@ public class JpaLogEntity extends
> AbstractLogEventWrapperEntity {
>  <Configuration status="warn" name="MyApp" packages="">
>    <Appenders>
>      <Socket name="socket" host="localhost" port="9500">
> -      <SerializedLayout />
> +      <JsonLayout properties="true"/>
>        <SSL>
>          <KeyStore location="log4j2-keystore.jks" password="changeme"/>
>          <TrustStore location="truststore.jks" password="changeme"/>
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
> 330a16f9/src/site/xdoc/manual/layouts.xml.vm
> ----------------------------------------------------------------------
> diff --git a/src/site/xdoc/manual/layouts.xml.vm b/src/site/xdoc/manual/
> layouts.xml.vm
> index f65db0d..7d17fd1 100644
> --- a/src/site/xdoc/manual/layouts.xml.vm
> +++ b/src/site/xdoc/manual/layouts.xml.vm
> @@ -1974,8 +1974,13 @@ at org.apache.logging.log4j.core.
> pattern.ExtendedThrowableTest.testException(Ext
>          </subsection>
>          <a name="SerializedLayout"/>
>          <subsection name="Serialized Layout">
> -          <p>The SerializedLayout simply serializes the LogEvent into a
> byte array using Java Serialization. This is useful when
> -            sending messages via JMS or via a Socket connection. The
> SerializedLayout accepts no parameters.
> +          <p>The SerializedLayout simply serializes the LogEvent into a
> byte array using Java Serialization.
> +          The SerializedLayout accepts no parameters.
> +          </p>
> +          <p>
> +          Java Serialization has inherent security weaknesses, using this
> layout is no longer recommended.
> +          An alternative layout containing the same information is <a
> href="#JSONLayout">JsonLayout</a>,
> +          when configured with <code>properties="true"</code>.
>            </p>
>          </subsection>
>          <a name="SyslogLayout"/>
>
> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/
> 330a16f9/src/site/xdoc/manual/migration.xml
> ----------------------------------------------------------------------
> diff --git a/src/site/xdoc/manual/migration.xml b/src/site/xdoc/manual/
> migration.xml
> index e154f14..e503277 100644
> --- a/src/site/xdoc/manual/migration.xml
> +++ b/src/site/xdoc/manual/migration.xml
> @@ -240,7 +240,7 @@
>  <Configuration>
>    <Appenders>
>      <Socket name="A1" host="localHost" port="5000">
> -      <SerializedLayout/>
> +      <PatternLayout pattern="%t %-5p %c{2} - %m%n"/>
>      </Socket>
>      <Console name="STDOUT" target="SYSTEM_OUT">
>        <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
>
>

Reply via email to