[ 
https://issues.apache.org/jira/browse/LOG4J2-2034?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Leonid Bogdanov updated LOG4J2-2034:
------------------------------------
    Description: 
When async logging is configured, JsonLayout cannot serialize a log event in 
which provided Throwable has a self-reference. For example, this may be the 
case for many Spring exceptions inherited from 
{{org.springframework.core.NestedRuntimeException}} or 
{{org.springframework.core.NestedCheckedException}} classes via 
{{getMostSpecificCause()}} method.

The root cause of the bug is 
{{org.apache.logging.log4j.core.async.RingBufferLogEvent.getThrowable()}} 
method, it isn't marked as ignored by Jackson serializer, so when the Throwable 
in a log event contains a self-reference, Jackson blows up with an exception
{code}
2017-09-07 13:28:08,799 Log4j2-TF-1-AsyncLogger[AsyncContext@6bc7c054]-1 ERROR 
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct 
self-reference leading to cycle (through reference chain: 
org.apache.logging.log4j.core.async.RingBufferLogEvent["throwable"]->org.log4j.App$SelfReferencedException["mostSpecificCause"])
 com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct 
self-reference leading to cycle (through reference chain: 
org.apache.logging.log4j.core.async.RingBufferLogEvent["throwable"]->org.log4j.App$SelfReferencedException["mostSpecificCause"])
        at 
com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
        at 
com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191)
        at 
com.fasterxml.jackson.databind.ser.BeanPropertyWriter._handleSelfReference(BeanPropertyWriter.java:944)
        at 
com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:721)
        at 
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
        at 
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
        at 
com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
        at 
com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.serializeAsField(SimpleBeanPropertyFilter.java:208)
        at 
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFieldsFiltered(BeanSerializerBase.java:771)
        at 
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:153)
        at 
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
        at 
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
        at 
com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1396)
        at 
com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1120)
        at 
com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:966)
        at 
org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:213)
        at 
org.apache.logging.log4j.core.layout.JsonLayout.toSerializable(JsonLayout.java:254)
        at 
org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:193)
        at 
org.apache.logging.log4j.core.layout.JsonLayout.toSerializable(JsonLayout.java:60)
        at 
org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:34)
        at 
org.apache.logging.log4j.core.layout.AbstractStringLayout.toByteArray(AbstractStringLayout.java:299)
        at 
org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:210)
        at 
org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:37)
...
{code}

One possible workaround is to create a custom Layout which delegates necessary 
calls to the original JsonLayout catching possible {{JsonProcessingException}} 
- when the latter is actually caught, another attempt to serialize a LogEvent 
is made, but this time instead of the original log event object a 
{{Log4jLogEvent.createMemento(originalEvent)}} copy is serialized.

The potential fix for the core JsonLayout class would be to configure Jackson 
to ignore {{RingBufferLogEvent.getThrowable()}}?

  was:
When async logging is configured, JsonLayout cannot serialize a log event in 
which provided Throwable has a self-reference. For example, this may be the 
case for many Spring exceptions inherited from 
{{org.springframework.core.NestedRuntimeException}} or 
{{org.springframework.core.NestedCheckedException}} classes via 
{{getMostSpecificCause()}} method.

The root cause of the bug is 
{{org.apache.logging.log4j.core.async.RingBufferLogEvent.getThrowable()}} 
method, it isn't marked as ignored by Jackson serializer, so when the Throwable 
in a log event contains a self-reference, Jackson blows up with an exception
{code}
2017-09-07 13:28:08,799 Log4j2-TF-1-AsyncLogger[AsyncContext@6bc7c054]-1 ERROR 
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct 
self-reference leading to cycle (through reference chain: 
org.apache.logging.log4j.core.async.RingBufferLogEvent["throwable"]->org.log4j.App$SelfReferencedException["mostSpecificCause"])
 com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct 
self-reference leading to cycle (through reference chain: 
org.apache.logging.log4j.core.async.RingBufferLogEvent["throwable"]->org.log4j.App$SelfReferencedException["mostSpecificCause"])
        at 
com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
        at 
com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191)
        at 
com.fasterxml.jackson.databind.ser.BeanPropertyWriter._handleSelfReference(BeanPropertyWriter.java:944)
        at 
com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:721)
        at 
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
        at 
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
        at 
com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
        at 
com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.serializeAsField(SimpleBeanPropertyFilter.java:208)
        at 
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFieldsFiltered(BeanSerializerBase.java:771)
        at 
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:153)
        at 
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
        at 
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
        at 
com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1396)
        at 
com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1120)
        at 
com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:966)
        at 
org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:213)
        at 
org.apache.logging.log4j.core.layout.JsonLayout.toSerializable(JsonLayout.java:254)
        at 
org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:193)
        at 
org.apache.logging.log4j.core.layout.JsonLayout.toSerializable(JsonLayout.java:60)
        at 
org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:34)
        at 
org.apache.logging.log4j.core.layout.AbstractStringLayout.toByteArray(AbstractStringLayout.java:299)
        at 
org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:210)
        at 
org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:37)
...
{code}


> In async mode JsonLayout can't serialize an event with self referenced 
> throwable
> --------------------------------------------------------------------------------
>
>                 Key: LOG4J2-2034
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-2034
>             Project: Log4j 2
>          Issue Type: Bug
>          Components: Layouts
>    Affects Versions: 2.8.2, 2.9.0
>            Reporter: Leonid Bogdanov
>         Attachments: log4j-issue.zip
>
>
> When async logging is configured, JsonLayout cannot serialize a log event in 
> which provided Throwable has a self-reference. For example, this may be the 
> case for many Spring exceptions inherited from 
> {{org.springframework.core.NestedRuntimeException}} or 
> {{org.springframework.core.NestedCheckedException}} classes via 
> {{getMostSpecificCause()}} method.
> The root cause of the bug is 
> {{org.apache.logging.log4j.core.async.RingBufferLogEvent.getThrowable()}} 
> method, it isn't marked as ignored by Jackson serializer, so when the 
> Throwable in a log event contains a self-reference, Jackson blows up with an 
> exception
> {code}
> 2017-09-07 13:28:08,799 Log4j2-TF-1-AsyncLogger[AsyncContext@6bc7c054]-1 
> ERROR com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct 
> self-reference leading to cycle (through reference chain: 
> org.apache.logging.log4j.core.async.RingBufferLogEvent["throwable"]->org.log4j.App$SelfReferencedException["mostSpecificCause"])
>  com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Direct 
> self-reference leading to cycle (through reference chain: 
> org.apache.logging.log4j.core.async.RingBufferLogEvent["throwable"]->org.log4j.App$SelfReferencedException["mostSpecificCause"])
>       at 
> com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
>       at 
> com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1191)
>       at 
> com.fasterxml.jackson.databind.ser.BeanPropertyWriter._handleSelfReference(BeanPropertyWriter.java:944)
>       at 
> com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:721)
>       at 
> com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
>       at 
> com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
>       at 
> com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
>       at 
> com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.serializeAsField(SimpleBeanPropertyFilter.java:208)
>       at 
> com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFieldsFiltered(BeanSerializerBase.java:771)
>       at 
> com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:153)
>       at 
> com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
>       at 
> com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
>       at 
> com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1396)
>       at 
> com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1120)
>       at 
> com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:966)
>       at 
> org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:213)
>       at 
> org.apache.logging.log4j.core.layout.JsonLayout.toSerializable(JsonLayout.java:254)
>       at 
> org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:193)
>       at 
> org.apache.logging.log4j.core.layout.JsonLayout.toSerializable(JsonLayout.java:60)
>       at 
> org.apache.logging.log4j.core.layout.AbstractJacksonLayout.toSerializable(AbstractJacksonLayout.java:34)
>       at 
> org.apache.logging.log4j.core.layout.AbstractStringLayout.toByteArray(AbstractStringLayout.java:299)
>       at 
> org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:210)
>       at 
> org.apache.logging.log4j.core.layout.AbstractLayout.encode(AbstractLayout.java:37)
> ...
> {code}
> One possible workaround is to create a custom Layout which delegates 
> necessary calls to the original JsonLayout catching possible 
> {{JsonProcessingException}} - when the latter is actually caught, another 
> attempt to serialize a LogEvent is made, but this time instead of the 
> original log event object a {{Log4jLogEvent.createMemento(originalEvent)}} 
> copy is serialized.
> The potential fix for the core JsonLayout class would be to configure Jackson 
> to ignore {{RingBufferLogEvent.getThrowable()}}?



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to