Repository: logging-log4j2
Updated Branches:
  refs/heads/Lucene5 8ce676e26 -> 50823493e


Squash commit after merging from master.

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

Branch: refs/heads/Lucene5
Commit: 50823493e61a3cc574d4d8b86e24687a655c5e4c
Parents: 8ce676e
Author: Gary Gregory <[email protected]>
Authored: Wed Jul 19 14:49:34 2017 -0700
Committer: Gary Gregory <[email protected]>
Committed: Wed Jul 19 14:49:34 2017 -0700

----------------------------------------------------------------------
 .../org/apache/logging/log4j/LogManager.java    |  6 ++--
 log4j-core/pom.xml                              |  2 --
 .../core/config/ConfigurationScheduler.java     | 36 ++++++++++++-------
 .../core/layout/AbstractJacksonLayout.java      | 32 +++++++++++++++++
 .../log4j/core/layout/AbstractStringLayout.java |  2 +-
 .../logging/log4j/core/layout/JsonLayout.java   | 37 +++++++++++---------
 .../logging/log4j/core/layout/XmlLayout.java    | 16 +++++----
 .../logging/log4j/core/layout/YamlLayout.java   | 29 ++++++++-------
 .../logging/log4j/core/util/WatchManager.java   | 19 ++++++----
 .../log4j/core/layout/JsonLayoutTest.java       | 20 +++++++++++
 .../log4j/core/layout/XmlLayoutTest.java        | 20 +++++++++++
 .../log4j/core/layout/YamlLayoutTest.java       | 18 ++++++++++
 log4j-jmx-gui/pom.xml                           | 22 +++++++++++-
 pom.xml                                         | 10 ++++++
 src/changes/changes.xml                         |  3 ++
 src/site/xdoc/manual/layouts.xml.vm             | 21 +++++++++--
 toolchains-sample-win.xml                       |  2 +-
 17 files changed, 228 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
index 0981d9c..fde71aa 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java
@@ -36,9 +36,9 @@ import org.apache.logging.log4j.util.StackLocatorUtil;
 import org.apache.logging.log4j.util.Strings;
 
 /**
- * The anchor point for the logging system. The most common usage of this 
class is to obtain a named {@link Logger}. The
- * method {@link #getLogger()} is provided as the most convenient way to 
obtain a named Logger based on the calling
- * class name. This class also provides method for obtaining named Loggers 
that use
+ * The anchor point for the Log4j logging system. The most common usage of 
this class is to obtain a named
+ * {@link Logger}. The method {@link #getLogger()} is provided as the most 
convenient way to obtain a named Logger based
+ * on the calling class name. This class also provides method for obtaining 
named Loggers that use
  * {@link String#format(String, Object...)} style messages instead of the 
default type of parameterized messages. These
  * are obtained through the {@link #getFormatterLogger(Class)} family of 
methods. Other service provider methods are
  * given through the {@link #getContext()} and {@link #getFactory()} family of 
methods; these methods are not normally

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index 12b2384..0960841 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -315,13 +315,11 @@
     <dependency>
       <groupId>org.apache-extras.beanshell</groupId>
       <artifactId>bsh</artifactId>
-      <version>2.0b5</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.codehaus.groovy</groupId>
       <artifactId>groovy-all</artifactId>
-      <version>2.4.7</version>
       <scope>test</scope>
     </dependency>
     <!-- Used for testing HttpAppender -->

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java
index 6ffb29d..17e28b5 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationScheduler.java
@@ -38,9 +38,19 @@ public class ConfigurationScheduler extends 
AbstractLifeCycle {
     private static final Logger LOGGER = StatusLogger.getLogger();
     private static final String SIMPLE_NAME = "Log4j2 " + 
ConfigurationScheduler.class.getSimpleName();
     private static final int MAX_SCHEDULED_ITEMS = 5;
+    
     private ScheduledExecutorService executorService;
-
     private int scheduledItems = 0;
+    private final String name;
+
+    public ConfigurationScheduler() {
+        this(SIMPLE_NAME);
+    }
+
+    public ConfigurationScheduler(String name) {
+        super();
+        this.name = name;
+    }
 
     @Override
     public void start() {
@@ -51,7 +61,7 @@ public class ConfigurationScheduler extends AbstractLifeCycle 
{
     public boolean stop(final long timeout, final TimeUnit timeUnit) {
         setStopping();
         if (isExecutorServiceSet()) {
-            LOGGER.debug("{} shutting down threads in {}", SIMPLE_NAME, 
getExecutorService());
+            LOGGER.debug("{} shutting down threads in {}", name, 
getExecutorService());
             executorService.shutdown();
             try {
                 executorService.awaitTermination(timeout, timeUnit);
@@ -60,7 +70,7 @@ public class ConfigurationScheduler extends AbstractLifeCycle 
{
                 try {
                     executorService.awaitTermination(timeout, timeUnit);
                 } catch (final InterruptedException inner) {
-                    LOGGER.warn("ConfigurationScheduler stopped but some 
scheduled services may not have completed.");
+                    LOGGER.warn("{} stopped but some scheduled services may 
not have completed.", name);
                 }
                 // Preserve interrupt status
                 Thread.currentThread().interrupt();
@@ -79,7 +89,7 @@ public class ConfigurationScheduler extends AbstractLifeCycle 
{
      */
     public void incrementScheduledItems() {
         if (isExecutorServiceSet()) {
-            LOGGER.error("{} attempted to increment scheduled items after 
start", SIMPLE_NAME);
+            LOGGER.error("{} attempted to increment scheduled items after 
start", name);
         } else {
             ++scheduledItems;
         }
@@ -143,7 +153,7 @@ public class ConfigurationScheduler extends 
AbstractLifeCycle {
         final ScheduledFuture<?> future = schedule(runnable, 
nextFireInterval(fireDate), TimeUnit.MILLISECONDS);
         final CronScheduledFuture<?> cronScheduledFuture = new 
CronScheduledFuture<>(future, fireDate);
         runnable.setScheduledFuture(cronScheduledFuture);
-        LOGGER.debug("Scheduled cron expression {} to fire at {}", 
cronExpression.getCronExpression(), fireDate);
+        LOGGER.debug("{} scheduled cron expression {} to fire at {}", name, 
cronExpression.getCronExpression(), fireDate);
         return cronScheduledFuture;
     }
 
@@ -184,7 +194,7 @@ public class ConfigurationScheduler extends 
AbstractLifeCycle {
     private ScheduledExecutorService getExecutorService() {
         if (executorService == null) {
             if (scheduledItems > 0) {
-                LOGGER.debug("{} starting {} threads", SIMPLE_NAME, 
scheduledItems);
+                LOGGER.debug("{} starting {} threads", name, scheduledItems);
                 scheduledItems = Math.min(scheduledItems, MAX_SCHEDULED_ITEMS);
                 final ScheduledThreadPoolExecutor executor = new 
ScheduledThreadPoolExecutor(scheduledItems,
                         
Log4jThreadFactory.createDaemonThreadFactory("Scheduled"));
@@ -193,7 +203,7 @@ public class ConfigurationScheduler extends 
AbstractLifeCycle {
                 this.executorService = executor;
 
             } else {
-                LOGGER.debug("{}: No scheduled items", SIMPLE_NAME);
+                LOGGER.debug("{}: No scheduled items", name);
             }
         }
         return executorService;
@@ -219,7 +229,7 @@ public class ConfigurationScheduler extends 
AbstractLifeCycle {
             try {
                 final long millis = scheduledFuture.getFireTime().getTime() - 
System.currentTimeMillis();
                 if (millis > 0) {
-                    LOGGER.debug("Cron thread woke up {} millis early. 
Sleeping", millis);
+                    LOGGER.debug("{} Cron thread woke up {} millis early. 
Sleeping", name, millis);
                     try {
                         Thread.sleep(millis);
                     } catch (final InterruptedException ie) {
@@ -228,11 +238,11 @@ public class ConfigurationScheduler extends 
AbstractLifeCycle {
                 }
                 runnable.run();
             } catch(final Throwable ex) {
-                LOGGER.error("{} caught error running command", SIMPLE_NAME, 
ex);
+                LOGGER.error("{} caught error running command", name, ex);
             } finally {
                 final Date fireDate = cronExpression.getNextValidTimeAfter(new 
Date());
                 final ScheduledFuture<?> future = schedule(this, 
nextFireInterval(fireDate), TimeUnit.MILLISECONDS);
-                LOGGER.debug("Cron expression {} scheduled to fire again at 
{}", cronExpression.getCronExpression(),
+                LOGGER.debug("{} Cron expression {} scheduled to fire again at 
{}", name, cronExpression.getCronExpression(),
                         fireDate);
                 scheduledFuture.reset(future, fireDate);
             }
@@ -246,7 +256,9 @@ public class ConfigurationScheduler extends 
AbstractLifeCycle {
 
     @Override
     public String toString() {
-        final StringBuilder sb = new StringBuilder("ConfigurationScheduler {");
+        final StringBuilder sb = new StringBuilder("ConfigurationScheduler 
[name=");
+        sb.append(name);
+        sb.append(", [");
         final Queue<Runnable> queue = ((ScheduledThreadPoolExecutor) 
executorService).getQueue();
         boolean first = true;
         for (final Runnable runnable : queue) {
@@ -256,7 +268,7 @@ public class ConfigurationScheduler extends 
AbstractLifeCycle {
             sb.append(runnable.toString());
             first = false;
         }
-        sb.append("}");
+        sb.append("]");
         return sb.toString();
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractJacksonLayout.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractJacksonLayout.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractJacksonLayout.java
index 7115df8..989c922 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractJacksonLayout.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractJacksonLayout.java
@@ -59,6 +59,9 @@ abstract class AbstractJacksonLayout extends 
AbstractStringLayout {
         @PluginBuilderAttribute
         private boolean stacktraceAsString = false;
 
+        @PluginBuilderAttribute
+        private boolean includeNullDelimiter = false;
+
         protected String toStringOrNull(final byte[] header) {
             return header == null ? null : new String(header, 
Charset.defaultCharset());
         }
@@ -95,6 +98,8 @@ abstract class AbstractJacksonLayout extends 
AbstractStringLayout {
             return stacktraceAsString;
         }
 
+        public boolean isIncludeNullDelimiter() { return includeNullDelimiter; 
}
+
         public B setEventEol(final boolean eventEol) {
             this.eventEol = eventEol;
             return asBuilder();
@@ -130,25 +135,49 @@ abstract class AbstractJacksonLayout extends 
AbstractStringLayout {
             return asBuilder();
         }
 
+        /**
+         * Whether to format the stacktrace as a string, and not a nested 
object (optional, defaults to false).
+         *
+         * @return this builder
+         */
         public B setStacktraceAsString(boolean stacktraceAsString) {
             this.stacktraceAsString = stacktraceAsString;
             return asBuilder();
         }
+
+        /**
+         * Whether to include NULL byte as delimiter after each event 
(optional, default to false).
+         *
+         * @return this builder
+         */
+        public B setIncludeNullDelimiter(final boolean includeNullDelimiter) {
+            this.includeNullDelimiter = includeNullDelimiter;
+            return asBuilder();
+        }
     }
 
     protected final String eol;
     protected final ObjectWriter objectWriter;
     protected final boolean compact;
     protected final boolean complete;
+    protected final boolean includeNullDelimiter;
 
+    @Deprecated
     protected AbstractJacksonLayout(final Configuration config, final 
ObjectWriter objectWriter, final Charset charset,
             final boolean compact, final boolean complete, final boolean 
eventEol, final Serializer headerSerializer,
             final Serializer footerSerializer) {
+        this(config, objectWriter, charset, compact, complete, eventEol, 
headerSerializer, footerSerializer, false);
+    }
+
+    protected AbstractJacksonLayout(final Configuration config, final 
ObjectWriter objectWriter, final Charset charset,
+            final boolean compact, final boolean complete, final boolean 
eventEol, final Serializer headerSerializer,
+            final Serializer footerSerializer, final boolean 
includeNullDelimiter) {
         super(config, charset, headerSerializer, footerSerializer);
         this.objectWriter = objectWriter;
         this.compact = compact;
         this.complete = complete;
         this.eol = compact && !eventEol ? COMPACT_EOL : DEFAULT_EOL;
+        this.includeNullDelimiter = includeNullDelimiter;
     }
 
     /**
@@ -183,6 +212,9 @@ abstract class AbstractJacksonLayout extends 
AbstractStringLayout {
             throws JsonGenerationException, JsonMappingException, IOException {
         objectWriter.writeValue(writer, convertMutableToLog4jEvent(event));
         writer.write(eol);
+        if (includeNullDelimiter) {
+            writer.write('\0');
+        }
         markEvent();
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
index a2a803c..88e541c 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/AbstractStringLayout.java
@@ -148,7 +148,7 @@ public abstract class AbstractStringLayout extends 
AbstractLayout<String> implem
     /**
      * The charset for the formatted message.
      */
-    // LOG4J2-1099: charset cannot be final due to serialization needs, so we 
serialize as charset name instead
+    // LOG4J2-1099: Charset cannot be final due to serialization needs, so we 
serialize as Charset name instead
     private transient Charset charset;
 
     private final String charsetName;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
index bbe2c9c..6fcc13d 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/JsonLayout.java
@@ -29,10 +29,8 @@ import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.DefaultConfiguration;
 import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 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.PluginConfiguration;
 
 /**
  * Appends a series of JSON events as strings serialized as bytes.
@@ -84,8 +82,9 @@ public final class JsonLayout extends AbstractJacksonLayout {
             final boolean encodeThreadContextAsList = isProperties() && 
propertiesAsList;
             final String headerPattern = toStringOrNull(getHeader());
             final String footerPattern = toStringOrNull(getFooter());
-            return new JsonLayout(getConfiguration(), isLocationInfo(), 
isProperties(), encodeThreadContextAsList, isComplete(),
-                    isCompact(), getEventEol(), headerPattern, footerPattern, 
getCharset(), isIncludeStacktrace(), isStacktraceAsString());
+            return new JsonLayout(getConfiguration(), isLocationInfo(), 
isProperties(), encodeThreadContextAsList,
+                    isComplete(), isCompact(), getEventEol(), headerPattern, 
footerPattern, getCharset(),
+                    isIncludeStacktrace(), isStacktraceAsString(), 
isIncludeNullDelimiter());
         }
 
         public boolean isPropertiesAsList() {
@@ -107,21 +106,25 @@ public final class JsonLayout extends 
AbstractJacksonLayout {
             final boolean complete, final boolean compact, final boolean 
eventEol, final String headerPattern,
             final String footerPattern, final Charset charset, final boolean 
includeStacktrace) {
         super(config, new JacksonFactory.JSON(encodeThreadContextAsList, 
includeStacktrace, false).newWriter(
-            locationInfo, properties, compact),
-            charset, compact, complete, eventEol,
-            
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
-            
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build());
+                locationInfo, properties, compact),
+                charset, compact, complete, eventEol,
+                
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
+                
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build(),
+                false);
     }
 
     private JsonLayout(final Configuration config, final boolean locationInfo, 
final boolean properties,
-            final boolean encodeThreadContextAsList,
-            final boolean complete, final boolean compact, final boolean 
eventEol, final String headerPattern,
-            final String footerPattern, final Charset charset, final boolean 
includeStacktrace, final boolean stacktraceAsString) {
+                       final boolean encodeThreadContextAsList,
+                       final boolean complete, final boolean compact, final 
boolean eventEol,
+                       final String headerPattern,final String footerPattern, 
final Charset charset,
+                       final boolean includeStacktrace,final boolean 
stacktraceAsString,
+                       final boolean includeNullDelimiter) {
         super(config, new JacksonFactory.JSON(encodeThreadContextAsList, 
includeStacktrace, stacktraceAsString).newWriter(
-            locationInfo, properties, compact),
-            charset, compact, complete, eventEol,
-            
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
-            
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build());
+                locationInfo, properties, compact),
+                charset, compact, complete, eventEol,
+                
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
+                
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build(),
+                includeNullDelimiter);
     }
 
     /**
@@ -225,7 +228,7 @@ public final class JsonLayout extends AbstractJacksonLayout 
{
             final boolean includeStacktrace) {
         final boolean encodeThreadContextAsList = properties && 
propertiesAsList;
         return new JsonLayout(config, locationInfo, properties, 
encodeThreadContextAsList, complete, compact, eventEol,
-                headerPattern, footerPattern, charset, includeStacktrace, 
false);
+                headerPattern, footerPattern, charset, includeStacktrace, 
false, false);
     }
 
     @PluginBuilderFactory
@@ -240,7 +243,7 @@ public final class JsonLayout extends AbstractJacksonLayout 
{
      */
     public static JsonLayout createDefaultLayout() {
         return new JsonLayout(new DefaultConfiguration(), false, false, false, 
false, false, false,
-                DEFAULT_HEADER, DEFAULT_FOOTER, StandardCharsets.UTF_8, true, 
false);
+                DEFAULT_HEADER, DEFAULT_FOOTER, StandardCharsets.UTF_8, true, 
false, false);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
index c744acf..1e42649 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/XmlLayout.java
@@ -25,7 +25,6 @@ import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
 import org.apache.logging.log4j.core.jackson.XmlConstants;
 
@@ -69,7 +68,8 @@ public final class XmlLayout extends AbstractJacksonLayout {
         @Override
         public XmlLayout build() {
             return new XmlLayout(getConfiguration(), isLocationInfo(), 
isProperties(), isComplete(),
-                isCompact(), getCharset(), isIncludeStacktrace(), 
isStacktraceAsString());
+                    isCompact(), getCharset(), isIncludeStacktrace(), 
isStacktraceAsString(),
+                    isIncludeNullDelimiter());
         }
     }
 
@@ -79,14 +79,15 @@ public final class XmlLayout extends AbstractJacksonLayout {
     @Deprecated
     protected XmlLayout(final boolean locationInfo, final boolean properties, 
final boolean complete,
                         final boolean compact, final Charset charset, final 
boolean includeStacktrace) {
-        this(null, locationInfo, properties, complete, compact, charset, 
includeStacktrace, false);
+        this(null, locationInfo, properties, complete, compact, charset, 
includeStacktrace, false, false);
     }
 
     private XmlLayout(final Configuration config, final boolean locationInfo, 
final boolean properties,
                       final boolean complete, final boolean compact, final 
Charset charset,
-                      final boolean includeStacktrace, final boolean 
stacktraceAsString) {
+                      final boolean includeStacktrace, final boolean 
stacktraceAsString,
+                      final boolean includeNullDelimiter) {
         super(config, new JacksonFactory.XML(includeStacktrace, 
stacktraceAsString).newWriter(
-            locationInfo, properties, compact), charset, compact, complete, 
false, null, null);
+            locationInfo, properties, compact), charset, compact, complete, 
false, null, null, includeNullDelimiter);
     }
 
     /**
@@ -177,7 +178,8 @@ public final class XmlLayout extends AbstractJacksonLayout {
             final boolean compact,
             final Charset charset,
             final boolean includeStacktrace) {
-        return new XmlLayout(null, locationInfo, properties, complete, 
compact, charset, includeStacktrace, false);
+        return new XmlLayout(null, locationInfo, properties, complete, 
compact, charset, includeStacktrace, false,
+                false);
     }
 
     @PluginBuilderFactory
@@ -191,6 +193,6 @@ public final class XmlLayout extends AbstractJacksonLayout {
      * @return an XML Layout.
      */
     public static XmlLayout createDefaultLayout() {
-        return new XmlLayout(null, false, false, false, false, 
StandardCharsets.UTF_8, true, false);
+        return new XmlLayout(null, false, false, false, false, 
StandardCharsets.UTF_8, true, false, false);
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
index 8a5994e..221819d 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/YamlLayout.java
@@ -26,9 +26,7 @@ import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.DefaultConfiguration;
 import org.apache.logging.log4j.core.config.Node;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
-import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
 import org.apache.logging.log4j.util.Strings;
 
 /**
@@ -62,7 +60,8 @@ public final class YamlLayout extends AbstractJacksonLayout {
             final String headerPattern = toStringOrNull(getHeader());
             final String footerPattern = toStringOrNull(getFooter());
             return new YamlLayout(getConfiguration(), isLocationInfo(), 
isProperties(), isComplete(),
-                isCompact(), getEventEol(), headerPattern, footerPattern, 
getCharset(), isIncludeStacktrace(), isStacktraceAsString());
+                    isCompact(), getEventEol(), headerPattern, footerPattern, 
getCharset(),
+                    isIncludeStacktrace(), isStacktraceAsString(), 
isIncludeNullDelimiter());
         }
     }
 
@@ -74,18 +73,22 @@ public final class YamlLayout extends AbstractJacksonLayout 
{
             final boolean complete, final boolean compact, final boolean 
eventEol, final String headerPattern,
             final String footerPattern, final Charset charset, final boolean 
includeStacktrace) {
         super(config, new JacksonFactory.YAML(includeStacktrace, 
false).newWriter(locationInfo, properties, compact), charset, compact,
-            complete, eventEol,
-            
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
-            
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build());
+                complete, eventEol,
+                
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
+                
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build(),
+                false);
     }
 
     private YamlLayout(final Configuration config, final boolean locationInfo, 
final boolean properties,
-            final boolean complete, final boolean compact, final boolean 
eventEol, final String headerPattern,
-            final String footerPattern, final Charset charset, final boolean 
includeStacktrace, final boolean stacktraceAsString) {
+                       final boolean complete, final boolean compact, final 
boolean eventEol,
+                       final String headerPattern, final String footerPattern, 
final Charset charset,
+                       final boolean includeStacktrace, final boolean 
stacktraceAsString,
+                       final boolean includeNullDelimiter) {
         super(config, new JacksonFactory.YAML(includeStacktrace, 
stacktraceAsString).newWriter(locationInfo, properties, compact), charset, 
compact,
-            complete, eventEol,
-            
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
-            
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build());
+                complete, eventEol,
+                
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(headerPattern).setDefaultPattern(DEFAULT_HEADER).build(),
+                
PatternLayout.newSerializerBuilder().setConfiguration(config).setPattern(footerPattern).setDefaultPattern(DEFAULT_FOOTER).build(),
+                includeNullDelimiter);
     }
 
     /**
@@ -173,7 +176,7 @@ public final class YamlLayout extends AbstractJacksonLayout 
{
             final Charset charset,
             final boolean includeStacktrace) {
         return new YamlLayout(config, locationInfo, properties, false, false, 
true, headerPattern, footerPattern,
-                charset, includeStacktrace, false);
+                charset, includeStacktrace, false, false);
     }
 
     @PluginBuilderFactory
@@ -188,6 +191,6 @@ public final class YamlLayout extends AbstractJacksonLayout 
{
      */
     public static AbstractJacksonLayout createDefaultLayout() {
         return new YamlLayout(new DefaultConfiguration(), false, false, false, 
false, false, DEFAULT_HEADER,
-                DEFAULT_FOOTER, StandardCharsets.UTF_8, true, false);
+                DEFAULT_FOOTER, StandardCharsets.UTF_8, true, false, false);
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java
index b0eb943..2e0f17a 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java
@@ -98,25 +98,30 @@ public class WatchManager extends AbstractLifeCycle {
                 final FileMonitor fileMonitor = entry.getValue();
                 final long lastModfied = file.lastModified();
                 if (fileModified(fileMonitor, lastModfied)) {
-                    logger.info("File {} was modified on {}, previous 
modification was {}", file, lastModfied, fileMonitor.lastModified);
-                    fileMonitor.lastModified = lastModfied;
+                    logger.info("File {} was modified on {}, previous 
modification was {}", file, lastModfied, fileMonitor.lastModifiedMillis);
+                    fileMonitor.lastModifiedMillis = lastModfied;
                     fileMonitor.fileWatcher.fileModified(file);
                 }
             }
         }
 
-        private boolean fileModified(final FileMonitor fileMonitor, final long 
lastModfied) {
-            return lastModfied != fileMonitor.lastModified;
+        private boolean fileModified(final FileMonitor fileMonitor, final long 
lastModifiedMillis) {
+            return lastModifiedMillis != fileMonitor.lastModifiedMillis;
         }
     }
 
     private class FileMonitor {
         private final FileWatcher fileWatcher;
-        private long lastModified;
+        private long lastModifiedMillis;
 
-        public FileMonitor(final long lastModified, final FileWatcher 
fileWatcher) {
+        public FileMonitor(final long lastModifiedMillis, final FileWatcher 
fileWatcher) {
             this.fileWatcher = fileWatcher;
-            this.lastModified = lastModified;
+            this.lastModifiedMillis = lastModifiedMillis;
+        }
+
+        @Override
+        public String toString() {
+            return "FileMonitor [fileWatcher=" + fileWatcher + ", 
lastModifiedMillis=" + lastModifiedMillis + "]";
         }
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
index 6016a31..82c9eea 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/JsonLayoutTest.java
@@ -394,6 +394,26 @@ public class JsonLayoutTest {
         return layout.toSerializable(expected);
     }
 
+    @Test
+    public void testIncludeNullDelimiterTrue() throws Exception {
+        final AbstractJacksonLayout layout = JsonLayout.newBuilder()
+                .setCompact(true)
+                .setIncludeNullDelimiter(true)
+                .build();
+        final String str = 
layout.toSerializable(LogEventFixtures.createLogEvent());
+        assertTrue(str.endsWith("\0"));
+    }
+
+    @Test
+    public void testIncludeNullDelimiterFalse() throws Exception {
+        final AbstractJacksonLayout layout = JsonLayout.newBuilder()
+                .setCompact(true)
+                .setIncludeNullDelimiter(false)
+                .build();
+        final String str = 
layout.toSerializable(LogEventFixtures.createLogEvent());
+        assertFalse(str.endsWith("\0"));
+    }
+    
     private String toPropertySeparator(final boolean compact) {
         return compact ? ":" : " : ";
     }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/XmlLayoutTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/XmlLayoutTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/XmlLayoutTest.java
index bbfec57..4701b17 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/XmlLayoutTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/XmlLayoutTest.java
@@ -342,4 +342,24 @@ public class XmlLayoutTest {
         // @formatter:off
         return layout.toSerializable(expected);
     }
+
+    @Test
+    public void testIncludeNullDelimiterTrue() throws Exception {
+        final AbstractJacksonLayout layout = XmlLayout.newBuilder()
+                .setCompact(true)
+                .setIncludeNullDelimiter(true)
+                .build();
+        final String str = 
layout.toSerializable(LogEventFixtures.createLogEvent());
+        assertTrue(str.endsWith("\0"));
+    }
+
+    @Test
+    public void testIncludeNullDelimiterFalse() throws Exception {
+        final AbstractJacksonLayout layout = XmlLayout.newBuilder()
+                .setCompact(true)
+                .setIncludeNullDelimiter(false)
+                .build();
+        final String str = 
layout.toSerializable(LogEventFixtures.createLogEvent());
+        assertFalse(str.endsWith("\0"));
+    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/YamlLayoutTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/YamlLayoutTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/YamlLayoutTest.java
index a634488..3531237 100644
--- 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/YamlLayoutTest.java
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/YamlLayoutTest.java
@@ -337,6 +337,24 @@ public class YamlLayoutTest {
         return layout.toSerializable(expected);
     }
 
+    @Test
+    public void testIncludeNullDelimiterTrue() throws Exception {
+        final AbstractJacksonLayout layout = YamlLayout.newBuilder()
+                .setIncludeNullDelimiter(true)
+                .build();
+        final String str = 
layout.toSerializable(LogEventFixtures.createLogEvent());
+        assertTrue(str.endsWith("\0"));
+    }
+
+    @Test
+    public void testIncludeNullDelimiterFalse() throws Exception {
+        final AbstractJacksonLayout layout = YamlLayout.newBuilder()
+                .setIncludeNullDelimiter(false)
+                .build();
+        final String str = 
layout.toSerializable(LogEventFixtures.createLogEvent());
+        assertFalse(str.endsWith("\0"));
+    }
+
     private String toPropertySeparator(final boolean compact, final boolean 
value) {
         return value ? ": " : ":";
     }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/log4j-jmx-gui/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-jmx-gui/pom.xml b/log4j-jmx-gui/pom.xml
index 6342eb3..ed18678 100644
--- a/log4j-jmx-gui/pom.xml
+++ b/log4j-jmx-gui/pom.xml
@@ -33,6 +33,7 @@
     <log4jParentDir>${basedir}/..</log4jParentDir>
     <docLabel>JMX GUI Documentation</docLabel>
     <projectDir>/jmx-gui</projectDir>
+    <jenkins.java.home>/home/jenkins/tools/java/latest1.7</jenkins.java.home>
   </properties>
   <dependencies>
     <dependency>
@@ -180,7 +181,7 @@
   </reporting>
   <profiles>
     <profile>
-      <id>default-profile</id>
+      <id>default-jmx-profile</id>
       <activation>
         <activeByDefault>true</activeByDefault>
         <file>
@@ -220,6 +221,25 @@
         </dependency>
       </dependencies>
     </profile>
+    <profile>
+      <id>jenkins-profile</id>
+      <activation>
+        <activeByDefault>false</activeByDefault>
+        <property>
+          <name>jenkins</name>
+        </property>
+      </activation>
+      <dependencies>
+        <dependency>
+          <groupId>com.sun</groupId>
+          <artifactId>jconsole</artifactId>
+          <version>1.7.0</version>
+          <scope>system</scope>
+          <systemPath>${jenkins.java.home}/lib/jconsole.jar</systemPath>
+          <optional>true</optional>
+        </dependency>
+      </dependencies>
+    </profile>
   </profiles>
 </project>
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 001699d..6e86c8f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -795,6 +795,16 @@
         <artifactId>HdrHistogram</artifactId>
         <version>2.1.9</version>
       </dependency>
+    <dependency>
+      <groupId>org.apache-extras.beanshell</groupId>
+      <artifactId>bsh</artifactId>
+      <version>2.0b6</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.groovy</groupId>
+      <artifactId>groovy-all</artifactId>
+      <version>2.4.12</version>
+    </dependency>
     </dependencies>
   </dependencyManagement>
   <build>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 762e66a..36343d1 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-1981" dev="mikes" type="add">
+        JsonLayout, XmlLayout and YamlLayout support 0-byte termination of log 
events.
+      </action>
       <action issue="LOG4J2-1864" dev="mattsicker" type="add" due-to="Matthias 
Kappeller">
         Support capped collections for MongoDb appender.
       </action>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/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 d7eaa6b..06e93dd 100644
--- a/src/site/xdoc/manual/layouts.xml.vm
+++ b/src/site/xdoc/manual/layouts.xml.vm
@@ -452,7 +452,12 @@ logger.debug("one={}, two={}, three={}", 1, 2, 3);
             <tr>
               <td>stacktraceAsString</td>
               <td>boolean</td>
-              <td>Whether to format the stackstrace as a string, and not a 
nested object (optional, defaults to false).</td>
+              <td>Whether to format the stacktrace as a string, and not a 
nested object (optional, defaults to false).</td>
+            </tr>
+            <tr>
+              <td>includeNullDelimiter</td>
+              <td>boolean</td>
+              <td>Whether to include NULL byte as delimiter after each event 
(optional, default to false).</td>
             </tr>
             <caption align="top">JsonLayout Parameters</caption>
           </table>
@@ -2186,7 +2191,12 @@ at 
org.apache.logging.log4j.core.pattern.ExtendedThrowableTest.testException(Ext
             <tr>
               <td>stacktraceAsString</td>
               <td>boolean</td>
-              <td>Whether to format the stackstrace as a string, and not a 
nested object (optional, defaults to false).</td>
+              <td>Whether to format the stacktrace as a string, and not a 
nested object (optional, defaults to false).</td>
+            </tr>
+            <tr>
+              <td>includeNullDelimiter</td>
+              <td>boolean</td>
+              <td>Whether to include NULL byte as delimiter after each event 
(optional, default to false).</td>
             </tr>
             <caption align="top">XmlLayout Parameters</caption>
           </table>
@@ -2275,7 +2285,12 @@ source:
             <tr>
               <td>stacktraceAsString</td>
               <td>boolean</td>
-              <td>Whether to format the stackstrace as a string, and not a 
nested object (optional, defaults to false).</td>
+              <td>Whether to format the stacktrace as a string, and not a 
nested object (optional, defaults to false).</td>
+            </tr>
+            <tr>
+              <td>includeNullDelimiter</td>
+              <td>boolean</td>
+              <td>Whether to include NULL byte as delimiter after each event 
(optional, default to false).</td>
             </tr>
             <caption align="top">YamlLayout Parameters</caption>
           </table>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/50823493/toolchains-sample-win.xml
----------------------------------------------------------------------
diff --git a/toolchains-sample-win.xml b/toolchains-sample-win.xml
index 64c30ac..8993aae 100644
--- a/toolchains-sample-win.xml
+++ b/toolchains-sample-win.xml
@@ -34,7 +34,7 @@
       <vendor>sun</vendor>
     </provides>
     <configuration>
-      <jdkHome>C:\Program Files\Java\jdk1.8.0_131</jdkHome>
+      <jdkHome>C:\Program Files\Java\jdk1.8.0_141</jdkHome>
     </configuration>
   </toolchain>
   <toolchain>

Reply via email to