You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2020/02/15 20:00:55 UTC
[logging-log4j2] branch release-2.x updated (edb3b5d -> 61d5c06)
This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a change to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git.
from edb3b5d LOG4J2-2760 - Always write header to new files
new 65565d1 LOG4J2-2703 Complex data type support for the default MapMessage JSON formatter. (#339)
new 61d5c06 LOG4J2-2703 - MapMessage.getFormattedMesssage() would incorrectly format objects.
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../apache/logging/log4j/message/MapMessage.java | 17 +-
.../log4j/message/MapMessageJsonFormatter.java | 419 +++++++++++++++++++++
.../logging/log4j/message/MapMessageTest.java | 98 ++++-
src/changes/changes.xml | 3 +
4 files changed, 516 insertions(+), 21 deletions(-)
create mode 100644 log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java
[logging-log4j2] 02/02: LOG4J2-2703 -
MapMessage.getFormattedMesssage() would incorrectly format objects.
Posted by rg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 61d5c06098f16f7a39e483f0cd4bc750067bed7a
Author: Ralph Goers <rg...@apache.org>
AuthorDate: Sat Feb 15 13:00:41 2020 -0700
LOG4J2-2703 - MapMessage.getFormattedMesssage() would incorrectly format objects.
---
.../logging/log4j/message/MapMessageJsonFormatter.java | 16 ++++++++++++++++
src/changes/changes.xml | 3 +++
2 files changed, 19 insertions(+)
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java
index 7c40233..3887f97 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java
@@ -1,3 +1,19 @@
+/*
+ * 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.message;
import org.apache.logging.log4j.util.IndexedStringMap;
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 5abb369..fefb702 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -30,6 +30,9 @@
- "remove" - Removed
-->
<release version="2.13.1" date="2019-MM-DD" description="GA Release 2.13.1">
+ <action issue="LOG4J2-2703" dev="goers" type="fix" due-to="Volkan Yazici">
+ MapMessage.getFormattedMesssage() would incorrectly format objects.
+ </action>
<action issue="LOG4J2-2760" dev="rgoers" type="fix" due-to="Christoph Kaser">
Always write header on a new OutputStream.
</action>
[logging-log4j2] 01/02: LOG4J2-2703 Complex data type support for
the default MapMessage JSON formatter. (#339)
Posted by rg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 65565d1043033a15c57efd5bab27e0f88e595e8e
Author: Volkan Yazıcı <vo...@gmail.com>
AuthorDate: Sat Feb 15 20:27:56 2020 +0100
LOG4J2-2703 Complex data type support for the default MapMessage JSON formatter. (#339)
---
.../apache/logging/log4j/message/MapMessage.java | 17 +-
.../log4j/message/MapMessageJsonFormatter.java | 403 +++++++++++++++++++++
.../logging/log4j/message/MapMessageTest.java | 98 ++++-
3 files changed, 497 insertions(+), 21 deletions(-)
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
index 3e183c6..60c5d22 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
@@ -413,22 +413,7 @@ public class MapMessage<M extends MapMessage<M, V>, V> implements MultiFormatStr
}
protected void asJson(final StringBuilder sb) {
- sb.append('{');
- for (int i = 0; i < data.size(); i++) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append(Chars.DQUOTE);
- int start = sb.length();
- sb.append(data.getKeyAt(i));
- StringBuilders.escapeJson(sb, start);
- sb.append(Chars.DQUOTE).append(':').append(Chars.DQUOTE);
- start = sb.length();
- ParameterFormatter.recursiveDeepToString(data.getValueAt(i), sb, null);
- StringBuilders.escapeJson(sb, start);
- sb.append(Chars.DQUOTE);
- }
- sb.append('}');
+ MapMessageJsonFormatter.format(sb, data);
}
protected void asJavaUnquoted(final StringBuilder sb) {
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java
new file mode 100644
index 0000000..7c40233
--- /dev/null
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java
@@ -0,0 +1,403 @@
+package org.apache.logging.log4j.message;
+
+import org.apache.logging.log4j.util.IndexedStringMap;
+import org.apache.logging.log4j.util.PropertiesUtil;
+import org.apache.logging.log4j.util.StringBuilderFormattable;
+import org.apache.logging.log4j.util.StringBuilders;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The default JSON formatter for {@link MapMessage}s.
+ * <p>
+ * The following types have specific handlers:
+ * <p>
+ * <ul>
+ * <li>{@link Map}
+ * <li>{@link Collection} ({@link List}, {@link Set}, etc.)
+ * <li>{@link Number} ({@link BigDecimal}, {@link Double}, {@link Long}, {@link Byte}, etc.)
+ * <li>{@link Boolean}
+ * <li>{@link StringBuilderFormattable}
+ * <li><tt>char/boolean/byte/short/int/long/float/double/Object</tt> arrays
+ * <li>{@link String}
+ * </ul>
+ * <p>
+ * It supports nesting up to a maximum depth of 8, which is set by
+ * <tt>log4j2.mapMessage.jsonFormatter.maxDepth</tt> property.
+ */
+enum MapMessageJsonFormatter {;
+
+ public static final int MAX_DEPTH = readMaxDepth();
+
+ private static final char DQUOTE = '"';
+
+ private static final char RBRACE = ']';
+
+ private static final char LBRACE = '[';
+
+ private static final char COMMA = ',';
+
+ private static final char RCURLY = '}';
+
+ private static final char LCURLY = '{';
+
+ private static final char COLON = ':';
+
+ private static int readMaxDepth() {
+ final int maxDepth = PropertiesUtil
+ .getProperties()
+ .getIntegerProperty("log4j2.mapMessage.jsonFormatter.maxDepth", 8);
+ if (maxDepth < 0) {
+ throw new IllegalArgumentException(
+ "was expecting a positive maxDepth, found: " + maxDepth);
+ }
+ return maxDepth;
+ }
+
+ static void format(final StringBuilder sb, final Object object) {
+ format(sb, object, 0);
+ }
+
+ private static void format(
+ final StringBuilder sb,
+ final Object object,
+ final int depth) {
+
+ if (depth >= MAX_DEPTH) {
+ throw new IllegalArgumentException("maxDepth has been exceeded");
+ }
+
+ // null
+ if (object == null) {
+ sb.append("null");
+ }
+
+ // map
+ else if (object instanceof IndexedStringMap) {
+ final IndexedStringMap map = (IndexedStringMap) object;
+ formatIndexedStringMap(sb, map, depth);
+ } else if (object instanceof Map) {
+ @SuppressWarnings("unchecked")
+ final Map<Object, Object> map = (Map<Object, Object>) object;
+ formatMap(sb, map, depth);
+ }
+
+ // list & collection
+ else if (object instanceof List) {
+ @SuppressWarnings("unchecked")
+ final List<Object> list = (List<Object>) object;
+ formatList(sb, list, depth);
+ } else if (object instanceof Collection) {
+ @SuppressWarnings("unchecked")
+ final Collection<Object> collection = (Collection<Object>) object;
+ formatCollection(sb, collection, depth);
+ }
+
+ // number & boolean
+ else if (object instanceof Number) {
+ final Number number = (Number) object;
+ formatNumber(sb, number);
+ } else if (object instanceof Boolean) {
+ final boolean booleanValue = (boolean) object;
+ formatBoolean(sb, booleanValue);
+ }
+
+ // formattable
+ else if (object instanceof StringBuilderFormattable) {
+ final StringBuilderFormattable formattable = (StringBuilderFormattable) object;
+ formatFormattable(sb, formattable);
+ }
+
+ // arrays
+ else if (object instanceof char[]) {
+ final char[] charValues = (char[]) object;
+ formatCharArray(sb, charValues);
+ } else if (object instanceof boolean[]) {
+ final boolean[] booleanValues = (boolean[]) object;
+ formatBooleanArray(sb, booleanValues);
+ } else if (object instanceof byte[]) {
+ final byte[] byteValues = (byte[]) object;
+ formatByteArray(sb, byteValues);
+ } else if (object instanceof short[]) {
+ final short[] shortValues = (short[]) object;
+ formatShortArray(sb, shortValues);
+ } else if (object instanceof int[]) {
+ final int[] intValues = (int[]) object;
+ formatIntArray(sb, intValues);
+ } else if (object instanceof long[]) {
+ final long[] longValues = (long[]) object;
+ formatLongArray(sb, longValues);
+ } else if (object instanceof float[]) {
+ final float[] floatValues = (float[]) object;
+ formatFloatArray(sb, floatValues);
+ } else if (object instanceof double[]) {
+ final double[] doubleValues = (double[]) object;
+ formatDoubleArray(sb, doubleValues);
+ } else if (object instanceof Object[]) {
+ final Object[] objectValues = (Object[]) object;
+ formatObjectArray(sb, objectValues, depth);
+ }
+
+ // string
+ else {
+ formatString(sb, object);
+ }
+
+ }
+
+ private static void formatIndexedStringMap(
+ final StringBuilder sb,
+ final IndexedStringMap map,
+ final int depth) {
+ sb.append(LCURLY);
+ final int nextDepth = depth + 1;
+ for (int entryIndex = 0; entryIndex < map.size(); entryIndex++) {
+ final String key = map.getKeyAt(entryIndex);
+ final Object value = map.getValueAt(entryIndex);
+ if (entryIndex > 0) {
+ sb.append(COMMA);
+ }
+ sb.append(DQUOTE);
+ final int keyStartIndex = sb.length();
+ sb.append(key);
+ StringBuilders.escapeJson(sb, keyStartIndex);
+ sb.append(DQUOTE).append(COLON);
+ format(sb, value, nextDepth);
+ }
+ sb.append(RCURLY);
+ }
+
+ private static void formatMap(
+ final StringBuilder sb,
+ final Map<Object, Object> map,
+ final int depth) {
+ sb.append(LCURLY);
+ final int nextDepth = depth + 1;
+ final boolean[] firstEntry = {true};
+ map.forEach((final Object key, final Object value) -> {
+ if (key == null) {
+ throw new IllegalArgumentException("null keys are not allowed");
+ }
+ if (firstEntry[0]) {
+ firstEntry[0] = false;
+ } else {
+ sb.append(COMMA);
+ }
+ sb.append(DQUOTE);
+ final String keyString = String.valueOf(key);
+ final int keyStartIndex = sb.length();
+ sb.append(keyString);
+ StringBuilders.escapeJson(sb, keyStartIndex);
+ sb.append(DQUOTE).append(COLON);
+ format(sb, value, nextDepth);
+ });
+ sb.append(RCURLY);
+ }
+
+ private static void formatList(
+ final StringBuilder sb,
+ final List<Object> items,
+ final int depth) {
+ sb.append(LBRACE);
+ final int nextDepth = depth + 1;
+ for (int itemIndex = 0; itemIndex < items.size(); itemIndex++) {
+ if (itemIndex > 0) {
+ sb.append(COMMA);
+ }
+ final Object item = items.get(itemIndex);
+ format(sb, item, nextDepth);
+ }
+ sb.append(RBRACE);
+ }
+
+ private static void formatCollection(
+ final StringBuilder sb,
+ final Collection<Object> items,
+ final int depth) {
+ sb.append(LBRACE);
+ final int nextDepth = depth + 1;
+ final boolean[] firstItem = {true};
+ items.forEach((final Object item) -> {
+ if (firstItem[0]) {
+ firstItem[0] = false;
+ } else {
+ sb.append(COMMA);
+ }
+ format(sb, item, nextDepth);
+ });
+ sb.append(RBRACE);
+ }
+
+ private static void formatNumber(final StringBuilder sb, final Number number) {
+ if (number instanceof BigDecimal) {
+ final BigDecimal decimalNumber = (BigDecimal) number;
+ sb.append(decimalNumber.toString());
+ } else if (number instanceof Double) {
+ final double doubleNumber = (Double) number;
+ sb.append(doubleNumber);
+ } else if (number instanceof Float) {
+ final float floatNumber = (float) number;
+ sb.append(floatNumber);
+ } else if (number instanceof Byte ||
+ number instanceof Short ||
+ number instanceof Integer ||
+ number instanceof Long) {
+ final long longNumber = number.longValue();
+ sb.append(longNumber);
+ } else {
+ final long longNumber = number.longValue();
+ final double doubleValue = number.doubleValue();
+ if (Double.compare(longNumber, doubleValue) == 0) {
+ sb.append(longNumber);
+ } else {
+ sb.append(doubleValue);
+ }
+ }
+ }
+
+ private static void formatBoolean(final StringBuilder sb, final boolean booleanValue) {
+ sb.append(booleanValue);
+ }
+
+ private static void formatFormattable(
+ final StringBuilder sb,
+ final StringBuilderFormattable formattable) {
+ sb.append(DQUOTE);
+ final int startIndex = sb.length();
+ formattable.formatTo(sb);
+ StringBuilders.escapeJson(sb, startIndex);
+ sb.append(DQUOTE);
+ }
+
+ private static void formatCharArray(final StringBuilder sb, final char[] items) {
+ sb.append(LBRACE);
+ for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
+ if (itemIndex > 0) {
+ sb.append(COMMA);
+ }
+ final char item = items[itemIndex];
+ sb.append(DQUOTE);
+ final int startIndex = sb.length();
+ sb.append(item);
+ StringBuilders.escapeJson(sb, startIndex);
+ sb.append(DQUOTE);
+ }
+ sb.append(RBRACE);
+ }
+
+ private static void formatBooleanArray(final StringBuilder sb, final boolean[] items) {
+ sb.append(LBRACE);
+ for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
+ if (itemIndex > 0) {
+ sb.append(COMMA);
+ }
+ final boolean item = items[itemIndex];
+ sb.append(item);
+ }
+ sb.append(RBRACE);
+ }
+
+ private static void formatByteArray(final StringBuilder sb, final byte[] items) {
+ sb.append(LBRACE);
+ for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
+ if (itemIndex > 0) {
+ sb.append(COMMA);
+ }
+ final byte item = items[itemIndex];
+ sb.append(item);
+ }
+ sb.append(RBRACE);
+ }
+
+ private static void formatShortArray(final StringBuilder sb, final short[] items) {
+ sb.append(LBRACE);
+ for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
+ if (itemIndex > 0) {
+ sb.append(COMMA);
+ }
+ final short item = items[itemIndex];
+ sb.append(item);
+ }
+ sb.append(RBRACE);
+ }
+
+ private static void formatIntArray(final StringBuilder sb, final int[] items) {
+ sb.append(LBRACE);
+ for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
+ if (itemIndex > 0) {
+ sb.append(COMMA);
+ }
+ final int item = items[itemIndex];
+ sb.append(item);
+ }
+ sb.append(RBRACE);
+ }
+
+ private static void formatLongArray(final StringBuilder sb, final long[] items) {
+ sb.append(LBRACE);
+ for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
+ if (itemIndex > 0) {
+ sb.append(COMMA);
+ }
+ final long item = items[itemIndex];
+ sb.append(item);
+ }
+ sb.append(RBRACE);
+ }
+
+ private static void formatFloatArray(final StringBuilder sb, final float[] items) {
+ sb.append(LBRACE);
+ for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
+ if (itemIndex > 0) {
+ sb.append(COMMA);
+ }
+ final float item = items[itemIndex];
+ sb.append(item);
+ }
+ sb.append(RBRACE);
+ }
+
+ private static void formatDoubleArray(
+ final StringBuilder sb,
+ final double[] items) {
+ sb.append(LBRACE);
+ for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
+ if (itemIndex > 0) {
+ sb.append(COMMA);
+ }
+ final double item = items[itemIndex];
+ sb.append(item);
+ }
+ sb.append(RBRACE);
+ }
+
+ private static void formatObjectArray(
+ final StringBuilder sb,
+ final Object[] items,
+ final int depth) {
+ sb.append(LBRACE);
+ final int nextDepth = depth + 1;
+ for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
+ if (itemIndex > 0) {
+ sb.append(COMMA);
+ }
+ final Object item = items[itemIndex];
+ format(sb, item, nextDepth);
+ }
+ sb.append(RBRACE);
+ }
+
+ private static void formatString(final StringBuilder sb, final Object value) {
+ sb.append(DQUOTE);
+ final int startIndex = sb.length();
+ final String valueString = String.valueOf(value);
+ sb.append(valueString);
+ StringBuilders.escapeJson(sb, startIndex);
+ sb.append(DQUOTE);
+ }
+
+}
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
index d6c5cf7..850024e 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
@@ -16,10 +16,18 @@
*/
package org.apache.logging.log4j.message;
+import com.google.common.base.Strings;
import org.apache.logging.log4j.util.StringBuilderFormattable;
import org.junit.Test;
-import static org.junit.Assert.*;
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
/**
*
@@ -79,7 +87,7 @@ public class MapMessageTest {
msg.put("message", testMsg);
msg.put("project", "Log4j");
final String result = msg.getFormattedMessage(new String[]{"JSON"});
- final String expected = "{\"message\":\"Test message {}\", \"project\":\"Log4j\"}";
+ final String expected = "{'message':'Test message {}','project':'Log4j'}".replace('\'', '"');
assertEquals(expected, result);
}
@@ -105,6 +113,87 @@ public class MapMessageTest {
}
@Test
+ public void testJsonFormatterNestedObjectSupport() {
+ final String actualJson = new ObjectMapMessage()
+ .with("key1", "val1")
+ .with("key2", Collections.singletonMap("key2.1", "val2.1"))
+ .with("key3", Arrays.asList(
+ 3,
+ (byte) 127,
+ 4.5D,
+ 4.6F,
+ Arrays.asList(true, false),
+ new BigDecimal(30),
+ Collections.singletonMap("key3.3", "val3.3")))
+ .with("key4", new LinkedHashMap<String, Object>() {{
+ put("chars", new char[]{'a', 'b', 'c'});
+ put("booleans", new boolean[]{true, false});
+ put("bytes", new byte[]{1, 2});
+ put("shorts", new short[]{3, 4});
+ put("ints", new int[]{256, 257});
+ put("longs", new long[]{2147483648L, 2147483649L});
+ put("floats", new float[]{1.0F, 1.1F});
+ put("doubles", new double[]{2.0D, 2.1D});
+ put("objects", new Object[]{"foo", "bar"});
+ }})
+ .getFormattedMessage(new String[]{"JSON"});
+ final String expectedJson = ("{" +
+ "'key1':'val1'," +
+ "'key2':{'key2.1':'val2.1'}," +
+ "'key3':[3,127,4.5,4.6,[true,false],30,{'key3.3':'val3.3'}]," +
+ "'key4':{" +
+ "'chars':['a','b','c']," +
+ "'booleans':[true,false]," +
+ "'bytes':[1,2]," +
+ "'shorts':[3,4]," +
+ "'ints':[256,257]," +
+ "'longs':[2147483648,2147483649]," +
+ "'floats':[1.0,1.1]," +
+ "'doubles':[2.0,2.1]," +
+ "'objects':['foo','bar']" +
+ "}}").replace('\'', '"');
+ assertEquals(expectedJson, actualJson);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testJsonFormatterInfiniteRecursionPrevention() {
+ final List<Object> recursiveValue = Arrays.asList(1, null);
+ // noinspection CollectionAddedToSelf
+ recursiveValue.set(1, recursiveValue);
+ new ObjectMapMessage()
+ .with("key", recursiveValue)
+ .getFormattedMessage(new String[]{"JSON"});
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testJsonFormatterMaxDepthViolation() {
+ testJsonFormatterMaxDepth(MapMessageJsonFormatter.MAX_DEPTH - 1);
+ }
+
+ @Test
+ public void testJsonFormatterMaxDepthConformance() {
+ int depth = MapMessageJsonFormatter.MAX_DEPTH - 2;
+ String expectedJson = String
+ .format("{'key':%s1%s}",
+ Strings.repeat("[", depth),
+ Strings.repeat("]", depth))
+ .replace('\'', '"');
+ String actualJson = testJsonFormatterMaxDepth(depth);
+ assertEquals(expectedJson, actualJson);
+ }
+
+ public static String testJsonFormatterMaxDepth(int depth) {
+ List<Object> list = new LinkedList<>();
+ list.add(1);
+ while (--depth > 0) {
+ list = new LinkedList<>(Collections.singletonList(list));
+ }
+ return new ObjectMapMessage()
+ .with("key", list)
+ .getFormattedMessage(new String[]{"JSON"});
+ }
+
+ @Test
public void testJava() {
final String testMsg = "Test message {}";
final StringMapMessage msg = new StringMapMessage();
@@ -151,10 +240,9 @@ public class MapMessageTest {
@Test
public void testJSONFormatNonStringValue() {
- final ObjectMapMessage msg = new ObjectMapMessage()
- .with("key", 1L);
+ final ObjectMapMessage msg = new ObjectMapMessage().with("key", 1L);
final String result = msg.getFormattedMessage(new String[]{"JSON"});
- final String expected = "{\"key\":\"1\"}";
+ final String expected = "{'key':1}".replace('\'', '"');
assertEquals(expected, result);
}