You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2016/10/10 18:20:39 UTC
[2/2] logging-log4j2 git commit: [LOG4J2-1636] Console Appender does
not pick up Oracle Java 8's sun.stdout.encoding and sun.stderr.encoding. This
is a partial fix. See discussion in Jira.
[LOG4J2-1636] Console Appender does not pick up Oracle Java 8's
sun.stdout.encoding and sun.stderr.encoding. This is a partial fix. See
discussion in Jira.
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/d65bf73c
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/d65bf73c
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/d65bf73c
Branch: refs/heads/master
Commit: d65bf73c02adbf7e82bd2dc66649bad512b944f2
Parents: eed7c07
Author: Gary Gregory <gg...@apache.org>
Authored: Mon Oct 10 11:20:32 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Mon Oct 10 11:20:32 2016 -0700
----------------------------------------------------------------------
.../logging/log4j/util/PropertiesUtil.java | 597 +-
.../log4j/core/appender/AbstractAppender.java | 8 +
.../log4j/core/appender/ConsoleAppender.java | 23 +-
.../appender/ConsoleAppenderBuilderTest.java | 80 +-
src/changes/changes.xml | 6175 +++++++++---------
5 files changed, 3477 insertions(+), 3406 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d65bf73c/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java
index 1bc4e43..af0b29e 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java
@@ -1,287 +1,310 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * <em>Consider this class private.</em>
- * <p>
- * Helps access properties. This utility provides a method to override system properties by specifying properties in a
- * properties file.
- * </p>
- */
-public final class PropertiesUtil {
-
- private static final PropertiesUtil LOG4J_PROPERTIES = new PropertiesUtil("log4j2.component.properties");
-
- private final Properties props;
-
- /**
- * Constructs a PropertiesUtil using a given Properties object as its source of defined properties.
- *
- * @param props the Properties to use by default
- */
- public PropertiesUtil(final Properties props) {
- this.props = props;
- }
-
- /**
- * Constructs a PropertiesUtil for a given properties file name on the classpath. The properties specified in this
- * file are used by default. If a property is not defined in this file, then the equivalent system property is used.
- *
- * @param propertiesFileName the location of properties file to load
- */
- public PropertiesUtil(final String propertiesFileName) {
- final Properties properties = new Properties();
- for (final URL url : LoaderUtil.findResources(propertiesFileName)) {
- try (final InputStream in = url.openStream()) {
- properties.load(in);
- } catch (final IOException ioe) {
- LowLevelLogUtil.logException("Unable to read " + url.toString(), ioe);
- }
- }
- this.props = properties;
- }
-
- /**
- * Loads and closes the given property input stream. If an error occurs, log to the status logger.
- *
- * @param in a property input stream.
- * @param source a source object describing the source, like a resource string or a URL.
- * @return a new Properties object
- */
- static Properties loadClose(final InputStream in, final Object source) {
- final Properties props = new Properties();
- if (null != in) {
- try {
- props.load(in);
- } catch (final IOException e) {
- LowLevelLogUtil.logException("Unable to read " + source, e);
- } finally {
- try {
- in.close();
- } catch (final IOException e) {
- LowLevelLogUtil.logException("Unable to close " + source, e);
- }
- }
- }
- return props;
- }
-
- /**
- * Returns the PropertiesUtil used by Log4j.
- *
- * @return the main Log4j PropertiesUtil instance.
- */
- public static PropertiesUtil getProperties() {
- return LOG4J_PROPERTIES;
- }
-
- /**
- * Gets the named property as a boolean value. If the property matches the string {@code "true"} (case-insensitive),
- * then it is returned as the boolean value {@code true}. Any other non-{@code null} text in the property is
- * considered {@code false}.
- *
- * @param name the name of the property to look up
- * @return the boolean value of the property or {@code false} if undefined.
- */
- public boolean getBooleanProperty(final String name) {
- return getBooleanProperty(name, false);
- }
-
- /**
- * Gets the named property as a boolean value.
- *
- * @param name the name of the property to look up
- * @param defaultValue the default value to use if the property is undefined
- * @return the boolean value of the property or {@code defaultValue} if undefined.
- */
- public boolean getBooleanProperty(final String name, final boolean defaultValue) {
- final String prop = getStringProperty(name);
- return (prop == null) ? defaultValue : "true".equalsIgnoreCase(prop);
- }
-
- /**
- * Gets the named property as a double.
- *
- * @param name the name of the property to look up
- * @param defaultValue the default value to use if the property is undefined
- * @return the parsed double value of the property or {@code defaultValue} if it was undefined or could not be parsed.
- */
- public double getDoubleProperty(final String name, final double defaultValue) {
- final String prop = getStringProperty(name);
- if (prop != null) {
- try {
- return Double.parseDouble(prop);
- } catch (final Exception ignored) {
- return defaultValue;
- }
- }
- return defaultValue;
- }
-
- /**
- * Gets the named property as an integer.
- *
- * @param name the name of the property to look up
- * @param defaultValue the default value to use if the property is undefined
- * @return the parsed integer value of the property or {@code defaultValue} if it was undefined or could not be
- * parsed.
- */
- public int getIntegerProperty(final String name, final int defaultValue) {
- final String prop = getStringProperty(name);
- if (prop != null) {
- try {
- return Integer.parseInt(prop);
- } catch (final Exception ignored) {
- return defaultValue;
- }
- }
- return defaultValue;
- }
-
- /**
- * Gets the named property as a long.
- *
- * @param name the name of the property to look up
- * @param defaultValue the default value to use if the property is undefined
- * @return the parsed long value of the property or {@code defaultValue} if it was undefined or could not be parsed.
- */
- public long getLongProperty(final String name, final long defaultValue) {
- final String prop = getStringProperty(name);
- if (prop != null) {
- try {
- return Long.parseLong(prop);
- } catch (final Exception ignored) {
- return defaultValue;
- }
- }
- return defaultValue;
- }
-
- /**
- * Gets the named property as a String.
- *
- * @param name the name of the property to look up
- * @return the String value of the property or {@code null} if undefined.
- */
- public String getStringProperty(final String name) {
- String prop = null;
- try {
- prop = System.getProperty(name);
- } catch (final SecurityException ignored) {
- // Ignore
- }
- return prop == null ? props.getProperty(name) : prop;
- }
-
- /**
- * Gets the named property as a String.
- *
- * @param name the name of the property to look up
- * @param defaultValue the default value to use if the property is undefined
- * @return the String value of the property or {@code defaultValue} if undefined.
- */
- public String getStringProperty(final String name, final String defaultValue) {
- final String prop = getStringProperty(name);
- return (prop == null) ? defaultValue : prop;
- }
-
- /**
- * Return the system properties or an empty Properties object if an error occurs.
- *
- * @return The system properties.
- */
- public static Properties getSystemProperties() {
- try {
- return new Properties(System.getProperties());
- } catch (final SecurityException ex) {
- LowLevelLogUtil.logException("Unable to access system properties.", ex);
- // Sandboxed - can't read System Properties
- return new Properties();
- }
- }
-
- /**
- * Extracts properties that start with or are equals to the specific prefix and returns them in a new Properties
- * object with the prefix removed.
- *
- * @param properties The Properties to evaluate.
- * @param prefix The prefix to extract.
- * @return The subset of properties.
- */
- public static Properties extractSubset(final Properties properties, final String prefix) {
- final Properties subset = new Properties();
-
- if (prefix == null || prefix.length() == 0) {
- return subset;
- }
-
- final String prefixToMatch = prefix.charAt(prefix.length() - 1) != '.' ? prefix + '.' : prefix;
-
- final List<String> keys = new ArrayList<>();
-
- for (final String key : properties.stringPropertyNames()) {
- if (key.startsWith(prefixToMatch)) {
- subset.setProperty(key.substring(prefixToMatch.length()), properties.getProperty(key));
- keys.add(key);
- }
- }
- for (final String key : keys) {
- properties.remove(key);
- }
-
- return subset;
- }
-
- /**
- * Partitions a properties map based on common key prefixes up to the first period.
- *
- * @param properties properties to partition
- * @return the partitioned properties where each key is the common prefix (minus the period) and the values are
- * new property maps without the prefix and period in the key
- * @since 2.6
- */
- public static Map<String, Properties> partitionOnCommonPrefixes(final Properties properties) {
- final Map<String, Properties> parts = new ConcurrentHashMap<>();
- for (final String key : properties.stringPropertyNames()) {
- final String prefix = key.substring(0, key.indexOf('.'));
- if (!parts.containsKey(prefix)) {
- parts.put(prefix, new Properties());
- }
- parts.get(prefix).setProperty(key.substring(key.indexOf('.') + 1), properties.getProperty(key));
- }
- return parts;
- }
-
- /**
- * Returns true if system properties tell us we are running on Windows.
- * @return true if system properties tell us we are running on Windows.
- */
- public boolean isOsWindows() {
- return getStringProperty("os.name").startsWith("Windows");
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * <em>Consider this class private.</em>
+ * <p>
+ * Helps access properties. This utility provides a method to override system properties by specifying properties in a
+ * properties file.
+ * </p>
+ */
+public final class PropertiesUtil {
+
+ private static final PropertiesUtil LOG4J_PROPERTIES = new PropertiesUtil("log4j2.component.properties");
+
+ private final Properties props;
+
+ /**
+ * Constructs a PropertiesUtil using a given Properties object as its source of defined properties.
+ *
+ * @param props the Properties to use by default
+ */
+ public PropertiesUtil(final Properties props) {
+ this.props = props;
+ }
+
+ /**
+ * Constructs a PropertiesUtil for a given properties file name on the classpath. The properties specified in this
+ * file are used by default. If a property is not defined in this file, then the equivalent system property is used.
+ *
+ * @param propertiesFileName the location of properties file to load
+ */
+ public PropertiesUtil(final String propertiesFileName) {
+ final Properties properties = new Properties();
+ for (final URL url : LoaderUtil.findResources(propertiesFileName)) {
+ try (final InputStream in = url.openStream()) {
+ properties.load(in);
+ } catch (final IOException ioe) {
+ LowLevelLogUtil.logException("Unable to read " + url.toString(), ioe);
+ }
+ }
+ this.props = properties;
+ }
+
+ /**
+ * Loads and closes the given property input stream. If an error occurs, log to the status logger.
+ *
+ * @param in a property input stream.
+ * @param source a source object describing the source, like a resource string or a URL.
+ * @return a new Properties object
+ */
+ static Properties loadClose(final InputStream in, final Object source) {
+ final Properties props = new Properties();
+ if (null != in) {
+ try {
+ props.load(in);
+ } catch (final IOException e) {
+ LowLevelLogUtil.logException("Unable to read " + source, e);
+ } finally {
+ try {
+ in.close();
+ } catch (final IOException e) {
+ LowLevelLogUtil.logException("Unable to close " + source, e);
+ }
+ }
+ }
+ return props;
+ }
+
+ /**
+ * Returns the PropertiesUtil used by Log4j.
+ *
+ * @return the main Log4j PropertiesUtil instance.
+ */
+ public static PropertiesUtil getProperties() {
+ return LOG4J_PROPERTIES;
+ }
+
+ /**
+ * Gets the named property as a boolean value. If the property matches the string {@code "true"} (case-insensitive),
+ * then it is returned as the boolean value {@code true}. Any other non-{@code null} text in the property is
+ * considered {@code false}.
+ *
+ * @param name the name of the property to look up
+ * @return the boolean value of the property or {@code false} if undefined.
+ */
+ public boolean getBooleanProperty(final String name) {
+ return getBooleanProperty(name, false);
+ }
+
+ /**
+ * Gets the named property as a boolean value.
+ *
+ * @param name the name of the property to look up
+ * @param defaultValue the default value to use if the property is undefined
+ * @return the boolean value of the property or {@code defaultValue} if undefined.
+ */
+ public boolean getBooleanProperty(final String name, final boolean defaultValue) {
+ final String prop = getStringProperty(name);
+ return (prop == null) ? defaultValue : "true".equalsIgnoreCase(prop);
+ }
+
+ /**
+ * Gets the named property as a Charset value.
+ *
+ * @param name the name of the property to look up
+ * @return the Charset value of the property or {@link Charset#defaultCharset()} if undefined.
+ */
+ public Charset getCharsetProperty(final String name) {
+ return getCharsetProperty(name, Charset.defaultCharset());
+ }
+
+ /**
+ * Gets the named property as a Charset value.
+ *
+ * @param name the name of the property to look up
+ * @param defaultValue the default value to use if the property is undefined
+ * @return the Charset value of the property or {@code defaultValue} if undefined.
+ */
+ public Charset getCharsetProperty(String name, Charset defaultValue) {
+ final String prop = getStringProperty(name);
+ return prop == null ? defaultValue : Charset.forName(name);
+ }
+
+ /**
+ * Gets the named property as a double.
+ *
+ * @param name the name of the property to look up
+ * @param defaultValue the default value to use if the property is undefined
+ * @return the parsed double value of the property or {@code defaultValue} if it was undefined or could not be parsed.
+ */
+ public double getDoubleProperty(final String name, final double defaultValue) {
+ final String prop = getStringProperty(name);
+ if (prop != null) {
+ try {
+ return Double.parseDouble(prop);
+ } catch (final Exception ignored) {
+ return defaultValue;
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Gets the named property as an integer.
+ *
+ * @param name the name of the property to look up
+ * @param defaultValue the default value to use if the property is undefined
+ * @return the parsed integer value of the property or {@code defaultValue} if it was undefined or could not be
+ * parsed.
+ */
+ public int getIntegerProperty(final String name, final int defaultValue) {
+ final String prop = getStringProperty(name);
+ if (prop != null) {
+ try {
+ return Integer.parseInt(prop);
+ } catch (final Exception ignored) {
+ return defaultValue;
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Gets the named property as a long.
+ *
+ * @param name the name of the property to look up
+ * @param defaultValue the default value to use if the property is undefined
+ * @return the parsed long value of the property or {@code defaultValue} if it was undefined or could not be parsed.
+ */
+ public long getLongProperty(final String name, final long defaultValue) {
+ final String prop = getStringProperty(name);
+ if (prop != null) {
+ try {
+ return Long.parseLong(prop);
+ } catch (final Exception ignored) {
+ return defaultValue;
+ }
+ }
+ return defaultValue;
+ }
+
+ /**
+ * Gets the named property as a String.
+ *
+ * @param name the name of the property to look up
+ * @return the String value of the property or {@code null} if undefined.
+ */
+ public String getStringProperty(final String name) {
+ String prop = null;
+ try {
+ prop = System.getProperty(name);
+ } catch (final SecurityException ignored) {
+ // Ignore
+ }
+ return prop == null ? props.getProperty(name) : prop;
+ }
+
+ /**
+ * Gets the named property as a String.
+ *
+ * @param name the name of the property to look up
+ * @param defaultValue the default value to use if the property is undefined
+ * @return the String value of the property or {@code defaultValue} if undefined.
+ */
+ public String getStringProperty(final String name, final String defaultValue) {
+ final String prop = getStringProperty(name);
+ return (prop == null) ? defaultValue : prop;
+ }
+
+ /**
+ * Return the system properties or an empty Properties object if an error occurs.
+ *
+ * @return The system properties.
+ */
+ public static Properties getSystemProperties() {
+ try {
+ return new Properties(System.getProperties());
+ } catch (final SecurityException ex) {
+ LowLevelLogUtil.logException("Unable to access system properties.", ex);
+ // Sandboxed - can't read System Properties
+ return new Properties();
+ }
+ }
+
+ /**
+ * Extracts properties that start with or are equals to the specific prefix and returns them in a new Properties
+ * object with the prefix removed.
+ *
+ * @param properties The Properties to evaluate.
+ * @param prefix The prefix to extract.
+ * @return The subset of properties.
+ */
+ public static Properties extractSubset(final Properties properties, final String prefix) {
+ final Properties subset = new Properties();
+
+ if (prefix == null || prefix.length() == 0) {
+ return subset;
+ }
+
+ final String prefixToMatch = prefix.charAt(prefix.length() - 1) != '.' ? prefix + '.' : prefix;
+
+ final List<String> keys = new ArrayList<>();
+
+ for (final String key : properties.stringPropertyNames()) {
+ if (key.startsWith(prefixToMatch)) {
+ subset.setProperty(key.substring(prefixToMatch.length()), properties.getProperty(key));
+ keys.add(key);
+ }
+ }
+ for (final String key : keys) {
+ properties.remove(key);
+ }
+
+ return subset;
+ }
+
+ /**
+ * Partitions a properties map based on common key prefixes up to the first period.
+ *
+ * @param properties properties to partition
+ * @return the partitioned properties where each key is the common prefix (minus the period) and the values are
+ * new property maps without the prefix and period in the key
+ * @since 2.6
+ */
+ public static Map<String, Properties> partitionOnCommonPrefixes(final Properties properties) {
+ final Map<String, Properties> parts = new ConcurrentHashMap<>();
+ for (final String key : properties.stringPropertyNames()) {
+ final String prefix = key.substring(0, key.indexOf('.'));
+ if (!parts.containsKey(prefix)) {
+ parts.put(prefix, new Properties());
+ }
+ parts.get(prefix).setProperty(key.substring(key.indexOf('.') + 1), properties.getProperty(key));
+ }
+ return parts;
+ }
+
+ /**
+ * Returns true if system properties tell us we are running on Windows.
+ * @return true if system properties tell us we are running on Windows.
+ */
+ public boolean isOsWindows() {
+ return getStringProperty("os.name").startsWith("Windows");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d65bf73c/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
index 71af242..94f2fec 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
@@ -17,6 +17,7 @@
package org.apache.logging.log4j.core.appender;
import java.io.Serializable;
+import java.nio.charset.Charset;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.ErrorHandler;
@@ -87,6 +88,13 @@ public abstract class AbstractAppender extends AbstractFilterable implements App
return layout;
}
+ public Layout<? extends Serializable> getOrCreateLayout(Charset charset) {
+ if (layout == null) {
+ return PatternLayout.newBuilder().withCharset(charset).build();
+ }
+ return layout;
+ }
+
}
private final String name;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d65bf73c/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
index fec5997..b865caf 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
@@ -64,9 +64,26 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
*/
public enum Target {
/** Standard output. */
- SYSTEM_OUT,
+ SYSTEM_OUT {
+ @Override
+ public Charset getDefaultCharset() {
+ return getCharset("sun.stdout.encoding");
+ }
+ },
/** Standard error output. */
- SYSTEM_ERR
+ SYSTEM_ERR {
+ @Override
+ public Charset getDefaultCharset() {
+ return getCharset("sun.stderr.encoding");
+ }
+ };
+
+ public abstract Charset getDefaultCharset();
+
+ protected Charset getCharset(String property) {
+ return new PropertiesUtil(PropertiesUtil.getSystemProperties()).getCharsetProperty(property);
+ }
+
}
private ConsoleAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
@@ -197,7 +214,7 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
if (follow && direct) {
throw new IllegalArgumentException("Cannot use both follow and direct on ConsoleAppender '" + getName() + "'");
}
- final Layout<? extends Serializable> layout = getOrCreateLayout();
+ final Layout<? extends Serializable> layout = getOrCreateLayout(target.getDefaultCharset());
return new ConsoleAppender(getName(), layout, getFilter(), getManager(target, follow, direct, layout),
isIgnoreExceptions(), target);
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/d65bf73c/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderBuilderTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderBuilderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderBuilderTest.java
index 2531a31..157b8c0 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderBuilderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderBuilderTest.java
@@ -1,31 +1,49 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.core.appender;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class ConsoleAppenderBuilderTest {
-
- /**
- * Tests https://issues.apache.org/jira/browse/LOG4J2-1620
- */
- @Test
- public void testDefaultImmediateFlush() {
- Assert.assertTrue(ConsoleAppender.newBuilder().isImmediateFlush());
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.appender;
+
+import java.nio.charset.Charset;
+
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ConsoleAppenderBuilderTest {
+
+ /**
+ * Tests https://issues.apache.org/jira/browse/LOG4J2-1620
+ */
+ @Test
+ public void testDefaultImmediateFlush() {
+ Assert.assertTrue(ConsoleAppender.newBuilder().isImmediateFlush());
+ }
+
+ /**
+ * Tests https://issues.apache.org/jira/browse/LOG4J2-1636
+ *
+ * Tested with Oracle 7 and 8 and IBM Java 8.
+ */
+ @Test
+ public void testDefaultLayoutDefaultCharset() {
+ final ConsoleAppender appender = ConsoleAppender.newBuilder().build();
+ final PatternLayout layout = (PatternLayout) appender.getLayout();
+ final String charsetName = System.getProperty("sun.stdout.encoding");
+ final String expectedName = charsetName != null ? charsetName : Charset.defaultCharset().name();
+ Assert.assertEquals(expectedName, layout.getCharset().name());
+ }
+
+}