title: Custom ConfigurationFactory combined with configuration file in log4j2
body: <p>I'm trying to <a href="https://logging.apache.org/log4j/2.x/manual/customconfig.html#Initialize_Log4j_by_Combining_Configuration_File_with_Programmatic_Configuration" rel="noreferrer">Initialize Log4j by Combining Configuration File with Programmatic Configuration</a>.</p>
  
  <p>I followed the manual (though it's syntax isn't quite right and it's outdated), which resulted in the following classes:</p>
  
  <p>CustomConfigurationFactory.java:</p>
  
  <pre><code>package factory;
  
  import org.apache.logging.log4j.core.LoggerContext;
  import org.apache.logging.log4j.core.config.Configuration;
  import org.apache.logging.log4j.core.config.ConfigurationFactory;
  import org.apache.logging.log4j.core.config.ConfigurationSource;
  import org.apache.logging.log4j.core.config.Order;
  import org.apache.logging.log4j.core.config.plugins.Plugin;
  
  import java.net.URI;
  
  @Plugin(name = "CustomConfigurationFactory", category = ConfigurationFactory.CATEGORY)
  @Order(1)
  public class CustomConfigurationFactory extends ConfigurationFactory {
  
      /**
       * Valid file extensions for XML files.
       */
      private static final String[] SUFFIXES = new String[]{".xml", "*"};
  
      /**
       * Return the Configuration.
       *
       * @param source The InputSource.
       * @return The Configuration.
       */
      public Configuration getConfiguration(LoggerContext context, ConfigurationSource source) {
  
          return new CustomConfiguration(context, source);
  
      }
  
      /**
       * Returns the file suffixes for XML files.
       * @return An array of File extensions.
       */
      public String[] getSupportedTypes() {
  
          return SUFFIXES;
  
      }
  
  }
  </code></pre>
  
  <p>CustomConfiguration.java:</p>
  
  <pre><code>package factory;
  
  import org.apache.logging.log4j.Level;
  import org.apache.logging.log4j.core.Appender;
  import org.apache.logging.log4j.core.LoggerContext;
  import org.apache.logging.log4j.core.config.ConfigurationSource;
  import org.apache.logging.log4j.core.config.LoggerConfig;
  import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
  
  import java.util.Map;
  
  public class CustomConfiguration extends XmlConfiguration {
  
      CustomConfiguration(LoggerContext context, ConfigurationSource configSource) {
  
          super(context, configSource);
  
      }
  
      @Override
      protected void doConfigure() {
  
          super.doConfigure();
  
          final LoggerConfig rootLogger = getRootLogger();
  
          final Map&lt;String, Appender&gt; appenderMap = rootLogger.getAppenders();
  
          if (MainClass.DEBUG) {
  
              rootLogger.addAppender(appenderMap.get("Console"), Level.ALL, null);
  
          } else {
  
              rootLogger.addAppender(appenderMap.get("Mail"), Level.ERROR, null);
  
          }
  
      }
  }
  </code></pre>
  
  <p>Now, when running this and calling <code>ConfigurationFactory.setConfigurationFactory(new CustomConfigurationFactory())</code> before any calls to the Logging API, I'm getting output to the console in the form of</p>
  
  <pre><code>ERROR StatusLogger Reconfiguration failed: No configuration found for 'someNumbersAndChars' at 'null' in 'null'
  </code></pre>
  
  <p>While debugging this, I found out that this is printed the first time I'm acquiring a <code>Logger</code>. The reason for that is that, if a custom <code>ConfigurationFactory</code> is supplied, the implementation of <code>ConfigurationFactory.getConfiguration(LoggerContext, String, URI)</code> by <code>ConfigurationFactory</code>'s private subclass <code>Factory</code> (which is the default factory) will be overridden by <code>ConfigurationFactory</code>'s implementation.</p>
  
  <p>And <code>ConfigurationFactory</code>'s implementation simply returns <code>null</code> if the URI is so, while <code>ConfigurationFactory.Factory</code>'s implementation nevertheless returns a valid configuration.</p>
  
  <p><a href="https://github.com/apache/logging-log4j2/blob/master/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java" rel="noreferrer">(link to source)</a></p>
  
  <p>My first idea now would be to override these overloads of <code>ConfigurationFactory.getConfiguration()</code> in my custom factory, but there has to be another way, right? ;)</p>