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

Scott Harrington commented on LOG4J2-745:
-----------------------------------------

Matt: 'Map.putIfAbsent' is indeed not available in Java 7. Here's a quick fix 
to PluginRegistry.getCategory:

{code:java}
        Map<String, T> result = categories.get(key);
        if (result == null) {
            categories.put(key, result = new LinkedHashMap<String, T>());
        }
        return result;
{code}

I had made the same change you did -- replace the ConcurrentMaps with 
LinkedHashMap -- but I'm concerned what works for my simple usage (where 
Log4j2Plugins.dat is read once at startup) will fail in infrequent but nasty 
ways* for folks who might dynamically add new plugins at runtime, if that's 
even possible. As I described above, the ConcurrentHashMaps were not correctly 
exposing a completely-parsed registry, but at least they would not have the 
potential to loop infinitely. There will need to be a synchronized block 
somewhere.

*HashMap.get can loop infinitely if another concurrent thread has done a put 
that causes a resize: 
http://confusion.tweakblogs.net/blog/2019/nasty-java-hashmap-race-condition.html

> Plugins can cause ConverterKeys collisions with unpredictable results
> ---------------------------------------------------------------------
>
>                 Key: LOG4J2-745
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-745
>             Project: Log4j 2
>          Issue Type: Improvement
>            Reporter: Scott Harrington
>            Assignee: Matt Sicker
>            Priority: Minor
>         Attachments: LinkedHashMap_Plugin_Manager.patch
>
>
> If I create a Converter plugin with ConverterKeys of "d" or "m" then there 
> will be a collision with the built-in DatePatternConverter or 
> MessagePatternConverter.
> It is unpredictable which plugin gets used.
> I see two resolutions:
> (1) detect collisions in PatternParser and emit a warning so we know which 
> implementation will be used
> (2) use whichever Log4j2Plugins.dat appeared first in the CLASSPATH
> Predictable iteration order is usually accomplished by replacing HashMaps 
> with LinkedHashMaps. Could easily do this for thie PluginManager.plugins 
> field. But PluginRegistry uses a ConcurrentHashMap.
> Is there a good reason to use ConcurrentHashMaps in PluginRegistry? It 
> doesn't really give you any concurrency -- a caller to 
> PluginManager.getPlugins could see a partially-loaded map if collectPlugins 
> was still running. Why not synchronize collectPlugins and/or loadPlugins, and 
> force any concurrent caller to getPlugins to wait until the loading was 
> complete.
> I would give it a stab but I see other more important changes are probably 
> underway for LOG4J2-741 and LOG4J2-673 and this can probably wait.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

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

Reply via email to