You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by "Remko Popma (JIRA)" <ji...@apache.org> on 2013/10/03 11:42:42 UTC

[jira] [Comment Edited] (LOG4J2-416) ConcurrentModificationException when logging maps that are being worked on

    [ https://issues.apache.org/jira/browse/LOG4J2-416?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13784947#comment-13784947 ] 

Remko Popma edited comment on LOG4J2-416 at 10/3/13 9:41 AM:
-------------------------------------------------------------

I'm not sure if it is possible to do this in a generic way.

Essentially if you pass an Object to one of the logger methods, the logger will turn that object into a String. We assume that the {{toString}} method will not throw any exceptions. (Which raises another, different, issue: should Log4J catch exceptions thrown by {{toString}}, if if so, how should they be handled?)

Back to your request: the logger methods take an Object argument. Log4J would have to do an instanceof on that Object and create a copy, distinguishing between HashMap, and TreeMap (because their toString gives different results), and all other known implementation of the java.util collections classes. But this would not cover any alternative collection classes like [1]...

Personally I think creating a copy is the responsibility of the application, not the logging library.

[1] http://java.dzone.com/articles/java-collections-%E2%80%93-are-there


was (Author: remkop@yahoo.com):
I'm not sure if it is possible to do this in a generic way.

Essentially if you pass an Object to one of the logger methods, the logger will turn that object into a String. We assume that the {{toString}} method will not throw any exceptions. (Which raises another, different, issue: should we catch exceptions thrown by {{toString}}, if if so, how should they be handled?)

Back to your request: the logger methods take an Object argument. Log4J would have to do an instanceof on that Object and create a copy, distinguishing between HashMap, and TreeMap (because their toString gives different results), and all other known implementation of the java.util collections classes. But this would not cover any alternative collection classes like [1]...

Personally I think creating a copy is the responsibility of the application, not the logging library.

[1] http://java.dzone.com/articles/java-collections-%E2%80%93-are-there

> ConcurrentModificationException when logging maps that are being worked on
> --------------------------------------------------------------------------
>
>                 Key: LOG4J2-416
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-416
>             Project: Log4j 2
>          Issue Type: Bug
>          Components: API
>    Affects Versions: 2.0-beta9
>            Reporter: Dimitry Declercq
>
> We run a multi-thread application which logs Maps, after log.debug(map) we continue to add items to the map, resulting in a ConcurrentModificationException on the logging side.
> e.g
> thread1 adds 4 items to the map
> thread1 logs the map 
> thread2 receives map and adds 2 extra items
> thread2 logs the map as well (not needed to trigger this issue)
> The logging of the map in thread 1 will sometimes fail with a ConcurrentModificationException.
> This is solved by logging a copy instead of the working variable, but I think it would be good if Log4J does this out of the box
> Stacktrace:
> Exception in thread "Thread-38" java.util.ConcurrentModificationException
>         at java.util.HashMap$HashIterator.nextEntry(HashMap.java:894)
>         at java.util.HashMap$EntryIterator.next(HashMap.java:934)
>         at java.util.HashMap$EntryIterator.next(HashMap.java:932)
>         at org.apache.logging.log4j.message.ParameterizedMessage.recursiveDeepToString(ParameterizedMessage.java:463)
>         at org.apache.logging.log4j.message.ParameterizedMessage.deepToString(ParameterizedMessage.java:378)
>         at org.apache.logging.log4j.message.ParameterizedMessage.parseArguments(ParameterizedMessage.java:164)
>         at org.apache.logging.log4j.message.ParameterizedMessage.<init>(ParameterizedMessage.java:117)
>         at org.apache.logging.log4j.message.ParameterizedMessage.<init>(ParameterizedMessage.java:126)
>         at org.slf4j.impl.SLF4JLogger.debug(SLF4JLogger.java:145)
>         at com.lynx.api.rest.service.PriceResource.getPrice(PriceResource.java:74)
>         at com.lynx.api.rest.service.PriceResourceTest$1.run(PriceResourceTest.java:166)
>         at java.lang.Thread.run(Thread.java:722)



--
This message was sent by Atlassian JIRA
(v6.1#6144)

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org