Modified: 
turbine/core/trunk/proposals/gk/log4j2/src/java/org/apache/turbine/Turbine.java
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/proposals/gk/log4j2/src/java/org/apache/turbine/Turbine.java?rev=1846641&r1=1846640&r2=1846641&view=diff
==============================================================================
--- 
turbine/core/trunk/proposals/gk/log4j2/src/java/org/apache/turbine/Turbine.java 
(original)
+++ 
turbine/core/trunk/proposals/gk/log4j2/src/java/org/apache/turbine/Turbine.java 
Thu Nov 15 11:48:08 2018
@@ -20,21 +20,18 @@ package org.apache.turbine;
  */
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.StringReader;
-import java.nio.file.FileSystems;
+import java.io.Serializable;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
-import java.util.Properties;
+import java.util.stream.Collectors;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
@@ -47,7 +44,6 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Unmarshaller;
-import javax.xml.parsers.FactoryConfigurationError;
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.PropertiesConfiguration;
@@ -60,15 +56,14 @@ import org.apache.commons.configuration2
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.commons.text.StringSubstitutor;
-import org.apache.log4j.PropertyConfigurator;
-import org.apache.log4j.xml.DOMConfigurator;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.config.Configurator;
+import org.apache.logging.log4j.core.appender.FileAppender;
+import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.turbine.modules.PageLoader;
 import org.apache.turbine.pipeline.Pipeline;
 import org.apache.turbine.pipeline.PipelineData;
@@ -85,9 +80,6 @@ import org.apache.turbine.util.ServerDat
 import org.apache.turbine.util.TurbineConfig;
 import org.apache.turbine.util.TurbineException;
 import org.apache.turbine.util.uri.URIConstants;
-//import org.apache.log4j.LogManager;
-//import org.apache.log4j.PropertyConfigurator;
-//import org.apache.log4j.xml.DOMConfigurator;
 
 /**
  * Turbine is the main servlet for the entire system. If you
@@ -120,7 +112,7 @@ import org.apache.turbine.util.uri.URICo
  * @author <a href="mailto:[email protected]";>Eric Pugh</a>
  * @author <a href="mailto:[email protected]";>Peter Courcoux</a>
  * @author <a href="mailto:[email protected]";>Thomas Vandahl</a>
- * @version $Id: Turbine.java 1845484 2018-11-01 15:15:03Z gk $
+ * @version $Id: Turbine.java 1845811 2018-11-05 15:18:22Z gk $
  */
 @WebServlet(
     name = "Turbine",
@@ -131,7 +123,7 @@ import org.apache.turbine.util.uri.URICo
                  @WebInitParam(name = TurbineConfig.PROPERTIES_PATH_KEY,
                     value = TurbineConfig.PROPERTIES_PATH_DEFAULT) } )
 @MultipartConfig
-public class TurbineLog4J2 extends HttpServlet
+public class Turbine extends HttpServlet
 {
     /** Serial version */
     private static final long serialVersionUID = -6317118078613623990L;
@@ -204,13 +196,9 @@ public class TurbineLog4J2 extends HttpS
         UNSET
     }
 
-    /** Logging class from commons.logging */
-    private static Log log = LogFactory.getLog(TurbineLog4J2.class);
-    
-    /**
-     * 
-     */
-    public static Logger log4j2Logger = LogManager.getLogger();
+    /** Logging class from commons.logging - this may still work, due to 
jcl-over-slf4j */
+    //private static Log log = LogFactory.getLog(Turbine.class);
+    public static Logger log = LogManager.getLogger();
 
     /**
      * This init method will load the default resources from a
@@ -223,7 +211,7 @@ public class TurbineLog4J2 extends HttpS
     @Override
     public void init() throws ServletException
     {
-        synchronized (TurbineLog4J2.class)
+        synchronized (Turbine.class)
         {
             super.init();
 
@@ -286,7 +274,7 @@ public class TurbineLog4J2 extends HttpS
         applicationRoot = findInitParameter(context, config,
                 TurbineConstants.APPLICATION_ROOT_KEY,
                 TurbineConstants.APPLICATION_ROOT_DEFAULT);
-
+        
         webappRoot = context.getRealPath("/");
         // log.info("Web Application root is " + webappRoot);
         // log.info("Application root is "     + applicationRoot);
@@ -327,17 +315,15 @@ public class TurbineLog4J2 extends HttpS
         // known behaviour of loading a properties file called
         // /WEB-INF/conf/TurbineResources.properties relative to the
         // web application root.
-
-        Path targetPath = configureFromConfiguration( config, context );
         
-        //
-        // Set up logging as soon as possible
-        //
-        configureLogging(targetPath);
 
-        // Now report our successful configuration to the world
-        log.info("Loaded configuration: " + configuration.toString());
+        Path confPath =  configureApplication( config, context );
 
+        configureLogging(confPath);
+        
+        //
+        // Logging with log4j2 is done via convention, finding in path
+   
         setTurbineServletConfig(config);
         setTurbineServletContext(context);
 
@@ -361,10 +347,10 @@ public class TurbineLog4J2 extends HttpS
 
         // Retrieve the pipeline class and then initialize it.  The pipeline
         // handles the processing of a webrequest/response cycle.
-           String descriptorPath =
-                       configuration.getString(
-                         "pipeline.default.descriptor",
-                                         TurbinePipeline.CLASSIC_PIPELINE);
+        String descriptorPath =
+            configuration.getString(
+              "pipeline.default.descriptor",
+                      TurbinePipeline.CLASSIC_PIPELINE);
 
         if (log.isDebugEnabled())
         {
@@ -374,7 +360,7 @@ public class TurbineLog4J2 extends HttpS
         // context resource path has to begin with slash, cft. 
context.getResource
         if (!descriptorPath.startsWith( "/" ))
         {
-               descriptorPath  = "/" + descriptorPath;
+            descriptorPath  = "/" + descriptorPath;
         }
 
         try (InputStream reader = context.getResourceAsStream(descriptorPath))
@@ -384,12 +370,22 @@ public class TurbineLog4J2 extends HttpS
             pipeline = (Pipeline) unmarshaller.unmarshal(reader);
         }
 
-               log.debug("Initializing pipeline");
+        log.debug("Initializing pipeline");
 
-               pipeline.initialize();
+        pipeline.initialize();
     }
 
-    private Path configureFromConfiguration( ServletConfig config, 
ServletContext context )
+    /**
+     * Checks configuraton style, resolves the location of the configuration 
and loads it to 
+     * internal {@link Configuration} object ({@link #configuration}).
+     *  
+     * @param config the Servlet Configuration
+     * @param context Servlet Context
+     * @return The resolved Configuration Path 
+     * @throws IOException
+     * @throws ConfigurationException
+     */
+    protected Path configureApplication( ServletConfig config, ServletContext 
context )
         throws IOException, ConfigurationException
     {
         ConfigurationStyle confStyle = ConfigurationStyle.UNSET;
@@ -420,10 +416,13 @@ public class TurbineLog4J2 extends HttpS
                     TurbineConfig.PROPERTIES_PATH_DEFAULT);
              confStyle = ConfigurationStyle.PROPERTIES;
         }
+        
+        // First report
+        log.debug("Loading configuration (" + confStyle + ") from " + 
confFile);
 
         // now begin loading
         Parameters params = new Parameters();
-        File confPath = getApplicationRootAsFile(); //.getCanonicalPath();
+        File confPath = getApplicationRootAsFile(); 
 
         if (confFile.startsWith( "/" ))
         {
@@ -438,16 +437,16 @@ public class TurbineLog4J2 extends HttpS
         Path targetPathDirectory = targetPath.getParent();
         if ( targetPathDirectory != null )
         {
-               // set the configuration path
-               confPath = targetPathDirectory.normalize().toFile();
+            // set the configuration path
+            confPath = targetPathDirectory.normalize().toFile();
 
             Path targetFilePath = targetPath.getFileName();
             if ( targetFilePath != null )
             {
-               // set the configuration file name
-               confFile = targetFilePath.toString();
+                // set the configuration file name
+                confFile = targetFilePath.toString();
             }
-               
+            
         }
 
         switch (confStyle)
@@ -478,131 +477,10 @@ public class TurbineLog4J2 extends HttpS
             default:
                 break;
         }
-        if (log4j2Logger != null) {
-            // Now report our successful configuration to the world
-            log4j2Logger.info("Loaded configuration (" + confStyle + ") from " 
+ confFile + " style: " + configuration.toString());
-        }
-        return targetPath;
-    }
-
-    /**
-     * Configure the logging facilities of Turbine
-     * @param targetPath
-     *
-     * @throws IOException if the configuration file handling fails.
-     */
-    protected void configureLogging(Path targetPath) throws IOException
-    {
-
-        Boolean useLog4j2 = configuration.getBoolean( "use.log4j2", false);
-        
-        if (useLog4j2) {
-            // Log4j" has a default configuration, as a result log4j2Logger 
will always be set
-            log4j2Logger.info("Configured log4j2");
-        } else {
-            configureLog4j1x( targetPath );
-        } 
-    }
-
-    private void configureLog4j1x( Path targetPath )
-        throws IOException
-    {
-        boolean success = false;
-        
-        
-        String log4jFile = 
configuration.getString(TurbineConstants.LOG4J_CONFIG_FILE,
-                                                   
TurbineConstants.LOG4J_CONFIG_FILE_DEFAULT);
-                        
-        if (log4jFile.startsWith( "/" ))
-        {
-            log4jFile = log4jFile.substring( 1 );
-        }
-        // log4j must either share path with configuration path or resolved 
relatively
-        Path log4jTarget = null;
-        Path logConfPath = targetPath.getParent();
-        if ( logConfPath != null )
-        {
-               Path logFilePath = logConfPath.resolve( log4jFile );
-               if ( logFilePath != null )
-               {
-                       log4jTarget = logFilePath.normalize();
-            }
-        }
-
-        if (StringUtils.isNotEmpty(log4jFile) &&
-                !log4jFile.equalsIgnoreCase("none") && log4jTarget != null && 
log4jTarget.toFile().exists() )
-        {
-            log4jFile = log4jTarget.toFile().getAbsolutePath();
-            Configurator.initialize("log4j1x_config", null, 
log4jTarget.toFile().toURI());
-            
-            LoggerContext context = (LoggerContext) 
LogManager.getContext(false);
-            org.apache.logging.log4j.core.config.Configuration log4jconf = 
context.getConfiguration();
-            String appRoot = 
log4jconf.getStrSubstitutor().getVariableResolver().lookup("applicationRoot");
-            log4jconf.getStrSubstitutor().replace( appRoot );
-            
-            
-            if (log4jFile.endsWith(".xml"))
-            {
-                // load XML type configuration
-                // NOTE: Only system property expansion available
-                try
-                {
-                    // NOTE: expand application root explicitely
-                    Map<String,String> valMap = new HashMap<>();
-                    valMap.put(TurbineConstants.APPLICATION_ROOT_KEY, 
getApplicationRoot().replace( '\\', '/' ));
-                    StringSubstitutor sub = new StringSubstitutor(valMap);
-                    String log4jTemplate = new 
String(Files.readAllBytes(Paths.get(log4jFile)));
-                    String resolvedString = sub.replace(log4jTemplate);
-                    
-                    // just always use slashes
-                    String winFS = "\\";
-                    if (FileSystems.getDefault().getSeparator().equals( winFS )
-                                    && resolvedString.contains( winFS )) {
-                        System.out.println( 
FileSystems.getDefault().getClass().getName() + " with fsep ('"+ 
FileSystems.getDefault().getSeparator() + "') found in "  + log4jFile + ", 
changing to forward slash ('/')." );
-                        resolvedString = resolvedString.replace( '\\', '/' ); 
-                    }
-                    Reader memoryConfiguration = new 
StringReader(resolvedString);
-                    DOMConfigurator log4jDOMConf = new DOMConfigurator();
-                    log4jDOMConf.doConfigure(memoryConfiguration, 
org.apache.log4j.LogManager.getLoggerRepository());
-
-                    success = true;
-                }
-                catch (FactoryConfigurationError e)
-                {
-                    System.err.println("Could not configure Log4J from 
configuration file "
-                            + log4jFile + ": ");
-                    e.printStackTrace();
-                }
-            }
-            else
-            {
-                //
-                // Load the config file above into a Properties object and
-                // fix up the Application root
-                //
-                Properties p = new Properties();
+        // Now report our successful configuration to the world
+        log.info("Loaded configuration (" + confStyle + ") from " + confFile + 
" style: " + configuration.toString());
 
-                try (FileInputStream fis = new FileInputStream(log4jFile))
-                {
-                    p.load(fis);
-                    p.setProperty(TurbineConstants.APPLICATION_ROOT_KEY, 
getApplicationRoot());
-                    PropertyConfigurator.configure(p);
-                    success = true;
-                }
-                catch (FileNotFoundException fnf)
-                {
-                    System.err.println("Could not open Log4J configuration 
file "
-                            + log4jFile + ": ");
-                    fnf.printStackTrace();
-                }
-            }
-        }
-        if (success)
-        {
-            // Rebuild our log object with a configured commons-logging
-            log = LogFactory.getLog(this.getClass());
-            log.info("Configured log4j from " + log4jFile);
-        }
+        return targetPath;
     }
 
     /**
@@ -654,7 +532,7 @@ public class TurbineLog4J2 extends HttpS
      */
     public void init(PipelineData data)
     {
-        synchronized (TurbineLog4J2.class)
+        synchronized (Turbine.class)
         {
             if (firstDoGet)
             {
@@ -670,20 +548,20 @@ public class TurbineLog4J2 extends HttpS
 
                 for (Iterator<String> i = services.getServiceNames(); 
i.hasNext();)
                 {
-                       String serviceName = i.next();
-                       Object service = services.getService(serviceName);
+                    String serviceName = i.next();
+                    Object service = services.getService(serviceName);
 
-                       if (service instanceof Initable)
-                       {
-                               try
-                               {
-                                                       
((Initable)service).init(data);
-                                               }
-                               catch (InitializationException e)
-                               {
-                                       log.warn("Could not initialize Initable 
" + serviceName + " with PipelineData", e);
-                                               }
-                       }
+                    if (service instanceof Initable)
+                    {
+                        try
+                        {
+                            ((Initable)service).init(data);
+                        }
+                        catch (InitializationException e)
+                        {
+                            log.warn("Could not initialize Initable " + 
serviceName + " with PipelineData", e);
+                        }
+                    }
                 }
 
                 // Mark that we're done.
@@ -1024,10 +902,146 @@ public class TurbineLog4J2 extends HttpS
         //
         // Bundle all the information above up into a convenient structure
         //
-        ServerData requestServerData = data.get(TurbineLog4J2.class, 
ServerData.class);
+        ServerData requestServerData = data.get(Turbine.class, 
ServerData.class);
         serverData = (ServerData) requestServerData.clone();
     }
 
+    protected void configureLogging(Path logConf) throws IOException
+    {
+        
+        LoggerContext context = (LoggerContext) LogManager.getContext(false);
+        
+        if (context.getConfiguration().getConfigurationSource().getLocation() 
== null) {
+            Path log4jFile = resolveLog4j2( logConf.getParent() );
+            // configured + no other log4j configuration already found
+            if (log4jFile != null) {
+                String log4jTemplate = new 
String(Files.readAllBytes(log4jFile));
+                // check old style applicationRoot, remove it 
+                if (log4jTemplate.contains( 
TurbineConstants.APPLICATION_ROOT_KEY )) {
+                    // NOTE: expand application root explicitely
+                    StringSubstitutor sub = getApplicationRootSubstitutor();
+                    String appRootResolvedLog4J2File = 
sub.replace(log4jTemplate);
+                    String[] fnParts = 
log4jFile.getFileName().toString().split( "\\." );
+                    String extension = (fnParts.length > 1)? fnParts[1]:"";
+                    Path targetLog4jFile = log4jFile.resolveSibling( 
log4jFile.getFileName().toString().replaceAll( "\\."+extension, 
"-gen."+extension ) );
+                    Files.write( targetLog4jFile, 
appRootResolvedLog4J2File.getBytes() );
+                    LogManager.getContext(null, false, 
targetLog4jFile.toUri());
+                } else {
+                    LogManager.getContext(null, false, log4jFile.toUri());
+                }
+            }
+        } else {
+            // default find it in classpath
+            log4j2ResolveApplicationRoot( context );
+        }
+        log.debug( "resolved log4j2 location: {}", 
context.getConfiguration().getConfigurationSource().getLocation() );
+    }
+    
+    // old style configured log4j 
+    protected Path resolveLog4j2( Path logConfPath )
+    {
+        String log4jFile = 
configuration.getString(TurbineConstants.LOG4J2_CONFIG_FILE,
+                                                   
TurbineConstants.LOG4J2_CONFIG_FILE_DEFAULT);
+                        
+        if (log4jFile.startsWith( "/" ))
+        {
+            log4jFile = log4jFile.substring( 1 );
+        }
+        Path log4jTarget = null;
+        if (StringUtils.isNotEmpty(log4jFile) && 
!log4jFile.equalsIgnoreCase("none")) {
+            // log4j must either share path with configuration path or 
resolved relatively
+            
+            if ( logConfPath != null )
+            {
+                Path logFilePath = logConfPath.resolve( log4jFile );
+                if ( logFilePath != null && Files.exists( logFilePath ))
+                {
+                    log4jTarget = logFilePath.normalize();
+                }
+            }
+        }
+        return log4jTarget;
+    }
+
+    protected StringSubstitutor getApplicationRootSubstitutor()
+    {
+        Map<String,String> valMap = new HashMap<>();
+        // always use slashes, make it configurable? 
+        valMap.put(TurbineConstants.APPLICATION_ROOT_KEY, 
getApplicationRoot().replace( '\\', '/' ));
+        StringSubstitutor sub = new StringSubstitutor(valMap);
+        return sub;
+    }
+
+    /**
+     * Checks if old style {@link TurbineConstants#APPLICATION_ROOT_KEY} 
exists in configuration file again, otherwise returns.
+     * 
+     * Log4j2 auto configures itself, this is only to handle/backport 
applicationRoot.
+     * Log4j2 has a default configuration, as a result log4j2Logger will 
always be set.
+     * Caveat: Log4j2 is already initialized already - this is too late to 
catch any logs before this.
+     * @see <a 
href="https://logging.apache.org/log4j/2.x/manual/webapp.html";>Log4j2 Manual 
Webapp</a>
+     * 
+     * @param context the log4j2 context
+     */
+    protected void log4j2ResolveApplicationRoot( LoggerContext context )
+    {
+        org.apache.logging.log4j.core.config.Configuration log4jconfig = 
context.getConfiguration();
+        Map<String, Appender> appenders =  log4jconfig.getAppenders();
+        
+        List<String> resolvedAppenderNames = appenders.values().stream().
+            filter( a ->  a instanceof FileAppender).
+            filter( a -> ( (FileAppender) a ).getFileName().contains( 
TurbineConstants.APPLICATION_ROOT_KEY ) ).
+            map(    a ->   ((FileAppender) a ).getName() ).collect( 
Collectors.toList() );
+        
+        if (resolvedAppenderNames.isEmpty()) {
+            return;
+        }
+        resolvedAppenderNames.stream().forEach( resolvableAppender -> {
+            //delete old appender/logger
+            FileAppender logFile = (FileAppender) 
log4jconfig.getAppender(resolvableAppender);
+            Layout<? extends Serializable> old_layout = logFile.getLayout();
+            String fileNameTemplate = logFile.getFileName();
+            String resolvedFileName = 
getApplicationRootSubstitutor().replace(fileNameTemplate);
+            logFile.stop(); // now no logging until restart!
+            //create new appender/logger
+            FileAppender newAppender = FileAppender.newBuilder()
+                            .withAdvertise(false)
+                            .withAdvertiseUri("")
+                            .withAppend(false)
+                            .withBufferedIo(true)
+                            .withBufferSize(8192)
+                            .setConfiguration(log4jconfig)
+                            .withFileName(resolvedFileName)
+                            .withFilter(null)
+                            .withIgnoreExceptions(true)
+                            .withImmediateFlush(true)
+                            .withLayout(old_layout)
+                            .withLocking(false)
+                            .withName(resolvableAppender)
+                            .build();
+            Map<String,LoggerConfig> loggers =log4jconfig.getLoggers();
+            // remove old/add new appender
+            loggers.values().stream().forEach( lc ->
+                { 
+                    lc.getAppenderRefs().forEach( ar -> { 
+                       if (ar.getRef().equals( resolvableAppender )) {
+                           lc.removeAppender( resolvableAppender );
+                           lc.addAppender( newAppender,lc.getLevel(), 
logFile.getFilter() );
+                       }
+                  });
+                    lc.getAppenders().keySet().stream().forEach( appName -> {
+                        if (appName.equals( resolvableAppender )) {
+                            lc.removeAppender( resolvableAppender );
+                            lc.addAppender( newAppender,lc.getLevel(), 
logFile.getFilter() );
+                        }
+                  });
+               }
+            );
+            newAppender.start();  
+        });
+        context.updateLoggers();
+        log.debug( "loggers restarted with applicationRoot is resolved" );
+    }
+
     /**
      * Set the application root for the webapp.
      *

Modified: turbine/core/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/src/changes/changes.xml?rev=1846641&r1=1846640&r2=1846641&view=diff
==============================================================================
--- turbine/core/trunk/src/changes/changes.xml (original)
+++ turbine/core/trunk/src/changes/changes.xml Thu Nov 15 11:48:08 2018
@@ -25,6 +25,9 @@
 
   <body>
     <release version="5.0" date="in Subversion">
+       <action type="update" dev="gk">
+        Update from log4j to log4j2, redirect JCL to slf4j
+      </action>
       <action type="update" dev="jp">
         Update from lang to commons-configuration2 to 2.4
       </action>

Modified: turbine/core/trunk/src/java/org/apache/turbine/Turbine.java
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/Turbine.java?rev=1846641&r1=1846640&r2=1846641&view=diff
==============================================================================
--- turbine/core/trunk/src/java/org/apache/turbine/Turbine.java (original)
+++ turbine/core/trunk/src/java/org/apache/turbine/Turbine.java Thu Nov 15 
11:48:08 2018
@@ -20,21 +20,14 @@ package org.apache.turbine;
  */
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.StringReader;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Properties;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
@@ -47,7 +40,6 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Unmarshaller;
-import javax.xml.parsers.FactoryConfigurationError;
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.PropertiesConfiguration;
@@ -55,16 +47,14 @@ import org.apache.commons.configuration2
 import 
org.apache.commons.configuration2.builder.combined.CombinedConfigurationBuilder;
 import org.apache.commons.configuration2.builder.fluent.Parameters;
 import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
+import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.commons.configuration2.io.HomeDirectoryLocationStrategy;
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.text.StringSubstitutor;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.PropertyConfigurator;
-import org.apache.log4j.xml.DOMConfigurator;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.turbine.modules.PageLoader;
 import org.apache.turbine.pipeline.Pipeline;
 import org.apache.turbine.pipeline.PipelineData;
@@ -197,8 +187,9 @@ public class Turbine extends HttpServlet
         UNSET
     }
 
-    /** Logging class from commons.logging */
-    private static Log log = LogFactory.getLog(Turbine.class);
+    /** Logging class from commons.logging - this may still work, due to 
jcl-over-slf4j */
+    //private static Log log = LogFactory.getLog(Turbine.class);
+    public static Logger log = LogManager.getLogger();
 
     /**
      * This init method will load the default resources from a
@@ -274,7 +265,7 @@ public class Turbine extends HttpServlet
         applicationRoot = findInitParameter(context, config,
                 TurbineConstants.APPLICATION_ROOT_KEY,
                 TurbineConstants.APPLICATION_ROOT_DEFAULT);
-
+        
         webappRoot = context.getRealPath("/");
         // log.info("Web Application root is " + webappRoot);
         // log.info("Application root is "     + applicationRoot);
@@ -315,7 +306,79 @@ public class Turbine extends HttpServlet
         // known behaviour of loading a properties file called
         // /WEB-INF/conf/TurbineResources.properties relative to the
         // web application root.
+        
+
+        Path confPath =  configureApplication( config, context );
+
+        configureLogging(confPath);
+        
+        //
+        // Logging with log4j 2 is done via convention, finding in path
+   
+        setTurbineServletConfig(config);
+        setTurbineServletContext(context);
 
+        getServiceManager().setApplicationRoot(applicationRoot);
+
+        // We want to set a few values in the configuration so
+        // that ${variable} interpolation will work for
+        //
+        // ${applicationRoot}
+        // ${webappRoot}
+        configuration.setProperty(TurbineConstants.APPLICATION_ROOT_KEY, 
applicationRoot);
+        configuration.setProperty(TurbineConstants.WEBAPP_ROOT_KEY, 
webappRoot);
+
+        getServiceManager().setConfiguration(configuration);
+
+        // Initialize the service manager. Services
+        // that have its 'earlyInit' property set to
+        // a value of 'true' will be started when
+        // the service manager is initialized.
+        getServiceManager().init();
+
+        // Retrieve the pipeline class and then initialize it.  The pipeline
+        // handles the processing of a webrequest/response cycle.
+        String descriptorPath =
+            configuration.getString(
+              "pipeline.default.descriptor",
+                      TurbinePipeline.CLASSIC_PIPELINE);
+
+        if (log.isDebugEnabled())
+        {
+            log.debug("Using descriptor path: " + descriptorPath);
+        }
+
+        // context resource path has to begin with slash, cft. 
context.getResource
+        if (!descriptorPath.startsWith( "/" ))
+        {
+            descriptorPath  = "/" + descriptorPath;
+        }
+
+        try (InputStream reader = context.getResourceAsStream(descriptorPath))
+        {
+            JAXBContext jaxb = JAXBContext.newInstance(TurbinePipeline.class);
+            Unmarshaller unmarshaller = jaxb.createUnmarshaller();
+            pipeline = (Pipeline) unmarshaller.unmarshal(reader);
+        }
+
+        log.debug("Initializing pipeline");
+
+        pipeline.initialize();
+    }
+
+    /**
+     * Checks configuraton style, resolves the location of the configuration 
and loads it to 
+     * internal {@link Configuration} object ({@link #configuration}).
+     *  
+     * @param config the Servlet Configuration
+     * @param context Servlet Context
+     * @return The resolved Configuration Path 
+     * @throws IOException
+     * @throws ConfigurationException
+     */
+    protected Path configureApplication( ServletConfig config, ServletContext 
context )
+        throws IOException, ConfigurationException
+    {
         ConfigurationStyle confStyle = ConfigurationStyle.UNSET;
         // first test
         String confFile= findInitParameter(context, config,
@@ -344,10 +407,13 @@ public class Turbine extends HttpServlet
                     TurbineConfig.PROPERTIES_PATH_DEFAULT);
              confStyle = ConfigurationStyle.PROPERTIES;
         }
+        
+        // First report
+        log.debug("Loading configuration (" + confStyle + ") from " + 
confFile);
 
         // now begin loading
         Parameters params = new Parameters();
-        File confPath = getApplicationRootAsFile(); //.getCanonicalPath();
+        File confPath = getApplicationRootAsFile(); 
 
         if (confFile.startsWith( "/" ))
         {
@@ -402,163 +468,10 @@ public class Turbine extends HttpServlet
             default:
                 break;
         }
-        //
-        // Set up logging as soon as possible
-        //
-        configureLogging(targetPath);
-
         // Now report our successful configuration to the world
         log.info("Loaded configuration (" + confStyle + ") from " + confFile + 
" style: " + configuration.toString());
 
-        setTurbineServletConfig(config);
-        setTurbineServletContext(context);
-
-        getServiceManager().setApplicationRoot(applicationRoot);
-
-        // We want to set a few values in the configuration so
-        // that ${variable} interpolation will work for
-        //
-        // ${applicationRoot}
-        // ${webappRoot}
-        configuration.setProperty(TurbineConstants.APPLICATION_ROOT_KEY, 
applicationRoot);
-        configuration.setProperty(TurbineConstants.WEBAPP_ROOT_KEY, 
webappRoot);
-
-        getServiceManager().setConfiguration(configuration);
-
-        // Initialize the service manager. Services
-        // that have its 'earlyInit' property set to
-        // a value of 'true' will be started when
-        // the service manager is initialized.
-        getServiceManager().init();
-
-        // Retrieve the pipeline class and then initialize it.  The pipeline
-        // handles the processing of a webrequest/response cycle.
-        String descriptorPath =
-            configuration.getString(
-              "pipeline.default.descriptor",
-                      TurbinePipeline.CLASSIC_PIPELINE);
-
-        if (log.isDebugEnabled())
-        {
-            log.debug("Using descriptor path: " + descriptorPath);
-        }
-
-        // context resource path has to begin with slash, cft. 
context.getResource
-        if (!descriptorPath.startsWith( "/" ))
-        {
-            descriptorPath  = "/" + descriptorPath;
-        }
-
-        try (InputStream reader = context.getResourceAsStream(descriptorPath))
-        {
-            JAXBContext jaxb = JAXBContext.newInstance(TurbinePipeline.class);
-            Unmarshaller unmarshaller = jaxb.createUnmarshaller();
-            pipeline = (Pipeline) unmarshaller.unmarshal(reader);
-        }
-
-        log.debug("Initializing pipeline");
-
-        pipeline.initialize();
-    }
-
-    /**
-     * Configure the logging facilities of Turbine
-     * @param targetPath
-     *
-     * @throws IOException if the configuration file handling fails.
-     */
-    protected void configureLogging(Path targetPath) throws IOException
-    {
-        String log4jFile = 
configuration.getString(TurbineConstants.LOG4J_CONFIG_FILE,
-                TurbineConstants.LOG4J_CONFIG_FILE_DEFAULT);
-
-        if (log4jFile.startsWith( "/" ))
-        {
-            log4jFile = log4jFile.substring( 1 );
-        }
-        // log4j must either share path with configuration path or resolved 
relatively
-        Path log4jTarget = null;
-        Path logConfPath = targetPath.getParent();
-        if ( logConfPath != null )
-        {
-            Path logFilePath = logConfPath.resolve( log4jFile );
-            if ( logFilePath != null )
-            {
-                log4jTarget = logFilePath.normalize();
-            }
-        }
-
-        if (StringUtils.isNotEmpty(log4jFile) &&
-                !log4jFile.equalsIgnoreCase("none") && log4jTarget != null && 
log4jTarget.toFile().exists() )
-        {
-            log4jFile = log4jTarget.toFile().getAbsolutePath();
-
-            boolean success = false;
-
-            if (log4jFile.endsWith(".xml"))
-            {
-                // load XML type configuration
-                // NOTE: Only system property expansion available
-                try
-                {
-                    // NOTE: expand application root explicitely
-                    Map<String,String> valMap = new HashMap<>();
-                    // just always use slashes, TODO make it configurable? 
-                    valMap.put(TurbineConstants.APPLICATION_ROOT_KEY, 
getApplicationRoot().replace( '\\', '/' ));
-                    StringSubstitutor sub = new StringSubstitutor(valMap);
-                    String log4jTemplate = new 
String(Files.readAllBytes(Paths.get(log4jFile)));
-                    String resolvedString = sub.replace(log4jTemplate);
-                    
-                    // just always use slashes
-                    String winFS = "\\";
-                    if (FileSystems.getDefault().getSeparator().equals( winFS )
-                                    && resolvedString.contains( winFS )) {
-                        System.out.println( 
FileSystems.getDefault().getClass().getName() + " with fsep ('"+ 
FileSystems.getDefault().getSeparator() + "') in "  + log4jFile + ", changing 
to forward slash ('/')." );
-                        resolvedString = resolvedString.replace( '\\', '/' ); 
-                    }
-                    Reader memoryConfiguration = new 
StringReader(resolvedString);
-                    DOMConfigurator log4jDOMConf = new DOMConfigurator();
-                    log4jDOMConf.doConfigure(memoryConfiguration, 
LogManager.getLoggerRepository());
-
-                    success = true;
-                }
-                catch (FactoryConfigurationError e)
-                {
-                    System.err.println("Could not configure Log4J from 
configuration file "
-                            + log4jFile + ": ");
-                    e.printStackTrace();
-                }
-            }
-            else
-            {
-                //
-                // Load the config file above into a Properties object and
-                // fix up the Application root
-                //
-                Properties p = new Properties();
-
-                try (FileInputStream fis = new FileInputStream(log4jFile))
-                {
-                    p.load(fis);
-                    p.setProperty(TurbineConstants.APPLICATION_ROOT_KEY, 
getApplicationRoot());
-                    PropertyConfigurator.configure(p);
-                    success = true;
-                }
-                catch (FileNotFoundException fnf)
-                {
-                    System.err.println("Could not open Log4J configuration 
file "
-                            + log4jFile + ": ");
-                    fnf.printStackTrace();
-                }
-            }
-
-            if (success)
-            {
-                // Rebuild our log object with a configured commons-logging
-                log = LogFactory.getLog(this.getClass());
-                log.info("Configured log4j from " + log4jFile);
-            }
-        }
+        return targetPath;
     }
 
     /**
@@ -985,6 +898,55 @@ public class Turbine extends HttpServlet
     }
 
     /**
+     * Checks Log4j 2 Context, loads log4File, if configured and configuration 
is not already located.
+     * @param logConf Configuration file path
+     * @throws IOException
+     */
+    protected void configureLogging(Path logConf) throws IOException
+    {   
+        LoggerContext context = (LoggerContext) LogManager.getContext(false);
+        
+        if (context.getConfiguration().getConfigurationSource().getLocation() 
== null) {
+            Path log4jFile = resolveLog4j2( logConf.getParent() );
+            // configured + no other log4j configuration already found
+            if (log4jFile != null) {
+                LogManager.getContext(null, false, log4jFile.toUri());
+            }
+        }
+        log.debug( "resolved log4j2 location: {}", 
context.getConfiguration().getConfigurationSource().getLocation() );
+    }
+    
+    /**
+     * Check {@value TurbineConstants#LOG4J2_CONFIG_FILE} in Turbine 
configuration.
+     * 
+     * @param logConfPath configuration directory
+     * @return Resolved log4j2 {@link Path} or null, if not found or 
configured "none".
+     */
+    protected Path resolveLog4j2( Path logConfPath )
+    {
+        String log4jFile = 
configuration.getString(TurbineConstants.LOG4J2_CONFIG_FILE,
+                                                   
TurbineConstants.LOG4J2_CONFIG_FILE_DEFAULT);
+                        
+        if (log4jFile.startsWith( "/" ))
+        {
+            log4jFile = log4jFile.substring( 1 );
+        }
+        Path log4jTarget = null;
+        if (StringUtils.isNotEmpty(log4jFile) && 
!log4jFile.equalsIgnoreCase("none")) {
+            // log4j must either share path with configuration path or 
resolved relatively
+            
+            if ( logConfPath != null )
+            {
+                Path logFilePath = logConfPath.resolve( log4jFile );
+                if ( logFilePath != null && logFilePath.toFile().exists() )
+                {
+                    log4jTarget = logFilePath.normalize();
+                }
+            }
+        }
+        return log4jTarget;
+    }
+    /**
      * Set the application root for the webapp.
      *
      * @param val New app root.

Modified: turbine/core/trunk/src/java/org/apache/turbine/TurbineConstants.java
URL: 
http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/TurbineConstants.java?rev=1846641&r1=1846640&r2=1846641&view=diff
==============================================================================
--- turbine/core/trunk/src/java/org/apache/turbine/TurbineConstants.java 
(original)
+++ turbine/core/trunk/src/java/org/apache/turbine/TurbineConstants.java Thu 
Nov 15 11:48:08 2018
@@ -48,10 +48,10 @@ public interface TurbineConstants
        String CONFIG_NAMESPACE = "org.apache.turbine";
 
        /** The key for the Log4J File */
-       String LOG4J_CONFIG_FILE = "log4j.file";
+       String LOG4J2_CONFIG_FILE = "log4j2.file";
 
        /** The default value for the Log4J File */
-       String LOG4J_CONFIG_FILE_DEFAULT = "/WEB-INF/conf/log4j.xml";
+       String LOG4J2_CONFIG_FILE_DEFAULT = "/WEB-INF/conf/log4j2.xml";
 
        /** This is the default log file to be used for logging */
        String DEFAULT_LOGGER = "turbine";


Reply via email to