You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@logging.apache.org by "Christophe BRETHES (JIRA)" <ji...@apache.org> on 2019/02/18 15:27:00 UTC

[jira] [Updated] (LOG4J2-2550) System properties log4j.plugin.packages is ignored

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

Christophe BRETHES updated LOG4J2-2550:
---------------------------------------
    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]:
{code:java}
@Plugin(name = "OdigoXMLConfigurationFactory", category = ConfigurationFactory.CATEGORY )
@Order(1000)
public class MyXMLConfigurationFactory extends ConfigurationFactory {
...
}
{code}
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) and is also attached to this ticket :
{code:java}
// 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));

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

  was:
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]:
{code:java}
@Plugin(name = "OdigoXMLConfigurationFactory", category = ConfigurationFactory.CATEGORY )
@Order(1000)
public class MyXMLConfigurationFactory extends ConfigurationFactory {
...
}
{code}
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) and is also attached to this ticket :
{code: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));

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


> System properties log4j.plugin.packages is ignored
> --------------------------------------------------
>
>                 Key: LOG4J2-2550
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-2550
>             Project: Log4j 2
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 2.11.1
>            Reporter: Christophe BRETHES
>            Priority: Major
>         Attachments: patch.txt
>
>
> 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]:
> {code:java}
> @Plugin(name = "OdigoXMLConfigurationFactory", category = ConfigurationFactory.CATEGORY )
> @Order(1000)
> public class MyXMLConfigurationFactory extends ConfigurationFactory {
> ...
> }
> {code}
> 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) and is also attached to this ticket :
> {code:java}
> // 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));
> {code}
> Workaround : use -Dlog4j.configurationFactory=com.test.MyXmlConfigurationFactory if there is only one factory to load.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)