Uploaded image for project: 'Log4j 2'
  1. Log4j 2
  2. LOG4J2-2550

System properties log4j.plugin.packages is ignored

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 2.11.1
    • None
    • Core
    • None

    Description

      I want to define my own ConfigurationFactory (com.test.MyXmlConfigurationFactory) and make it loaded by log4j using the Plugin mechanism as described in https://logging.apache.org/log4j/2.x/manual/extending.html#ConfigurationFactory:

      @Plugin(name = "OdigoXMLConfigurationFactory", category = ConfigurationFactory.CATEGORY )
      @Order(1000)
      public class MyXMLConfigurationFactory extends ConfigurationFactory {
      ...
      }
      

      According to https://logging.apache.org/log4j/log4j-2.1/manual/plugins.html#Introduction I try to launch my test project with -Dlog4j.plugin.packages=com.test but log4j doesnt see my ConfigurationFactory

      Note : packages attribute of configuration node in log4j2.xml can't be used because factory is yet instanciated to read this file...

      I saw that there is no code to handle this property, so I wrote it down (the patch is quite simple) to update class PluginManager.java (patch also attached to this ticket) :

      // update of org/apache/logging/log4j/core/config/plugins/util/PluginManager.java
      +import java.util.Arrays;
       import java.util.Collection;
       import java.util.HashMap;
       import java.util.LinkedHashMap;
      @@ -35,11 +36,14 @@
       
           private static final CopyOnWriteArrayList<String> PACKAGES = new CopyOnWriteArrayList<>();
           private static final String LOG4J_PACKAGES = "org.apache.logging.log4j.core";
      -
      +    private static final String LOG4J_PLUGIN_PACKAGES_PROPERTY="log4j.plugin.packages" ;
      +    private static final CopyOnWriteArrayList<String> PROPERTY_PACKAGES = new CopyOnWriteArrayList<>();
           private static final Logger LOGGER = StatusLogger.getLogger();
       
           private Map<String, PluginType<?>> plugins = new HashMap<>();
           private final String category;
      +    //just a boolean to know if system property  if log4j.plugin.packages has been processed
      +    private static Boolean pluginSystemPropertiesHandled = false ;
       
           /**
            * Constructs a PluginManager for the plugin category name given.
      @@ -141,7 +145,28 @@
               for (final Map<String, List<PluginType<?>>> pluginsByCategory : PluginRegistry.getInstance().getPluginsByCategoryByBundleId().values()) {
                   mergeByName(newPlugins, pluginsByCategory.get(categoryLowerCase));
               }
      -
      +        // load packages defined by system property log4j.plugin.packages        
      +        if( ! pluginSystemPropertiesHandled ) {
      +            synchronized (pluginSystemPropertiesHandled) {
      +                //clear in case of synchronization issue has we synchronized inside if to avoid too many synchronization
      +                PROPERTY_PACKAGES.clear();
      +                final String pluginPackagesStr = System.getProperty(LOG4J_PLUGIN_PACKAGES_PROPERTY);
      +                if (pluginPackagesStr != null && pluginPackagesStr.trim().length()>1) {
      +                    if(pluginPackagesStr.indexOf(',')>0) {
      +                        PluginManager.PROPERTY_PACKAGES.addAll(Arrays.asList(pluginPackagesStr.split(",")));
      +                    }
      +                    else {
      +                        PluginManager.PROPERTY_PACKAGES.add(pluginPackagesStr);
      +                    }
      +                }
      +                pluginSystemPropertiesHandled = Boolean.TRUE ;
      +            }
      +        }
      +        // Next, iterate any package defined by system property log4j.plugin.packages
      +        for (final String pkg : PROPERTY_PACKAGES) {
      +            mergeByName(newPlugins, PluginRegistry.getInstance().loadFromPackage(pkg).get(categoryLowerCase));
      +        }
      +        
               // Next iterate any packages passed to the static addPackage method.
               for (final String pkg : PACKAGES) {
                   mergeByName(newPlugins, PluginRegistry.getInstance().loadFromPackage(pkg).get(categoryLowerCase));
      
      

      Workaround : use -Dlog4j.configurationFactory=com.test.MyXmlConfigurationFactory if there is only one factory to load.

      Attachments

        1. patch.txt
          3 kB
          Christophe BRETHES

        Activity

          People

            Unassigned Unassigned
            cbrethes Christophe BRETHES
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: