From 4743d1803cb2e4a9c7c946db1cf256884ccbad6a Mon Sep 17 00:00:00 2001
From: Phillip Webb
Date: Wed, 8 May 2013 14:24:06 -0700
Subject: [PATCH] Update JavaLoggerConfigurer to use AC ClassLoader
Update JavaLoggerConfigurer to use the ApplicationContext classloader
rather then the default classloader. Also refactored to introduce
LoggingSystem enum to act as a strategy for the specific logging
systems.
---
.../logging/JavaLoggerConfigurer.java | 1 -
.../bootstrap/logging/LogbackConfigurer.java | 1 -
.../bootstrap/logging/LoggingInitializer.java | 210 +++++++++++-------
.../logging/LoggingInitializerTests.java | 1 -
4 files changed, 124 insertions(+), 89 deletions(-)
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/JavaLoggerConfigurer.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/JavaLoggerConfigurer.java
index 7a9c712fcbd..a5c726b5ae6 100644
--- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/JavaLoggerConfigurer.java
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/JavaLoggerConfigurer.java
@@ -26,7 +26,6 @@ import org.springframework.util.SystemPropertyUtils;
* Logging initializer for {@link Logger java.util.logging}.
*
* @author Dave Syer
- *
*/
public abstract class JavaLoggerConfigurer {
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/LogbackConfigurer.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/LogbackConfigurer.java
index e77fd4c4153..fe2f6735f4a 100644
--- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/LogbackConfigurer.java
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/LogbackConfigurer.java
@@ -30,7 +30,6 @@ import ch.qos.logback.core.joran.spi.JoranException;
* Logging initializer for logback.
*
* @author Dave Syer
- *
*/
public abstract class LogbackConfigurer {
diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/LoggingInitializer.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/LoggingInitializer.java
index a67f29baaaf..f7a1a231a1e 100644
--- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/LoggingInitializer.java
+++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/logging/LoggingInitializer.java
@@ -13,29 +13,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.bootstrap.logging;
import java.lang.management.ManagementFactory;
+import java.util.HashMap;
+import java.util.Map;
+import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ClassUtils;
import org.springframework.util.Log4jConfigurer;
/**
- *
* An {@link ApplicationContextInitializer} that configures a logging framework depending
* on what it finds on the classpath and in the {@link Environment}. If the environment
* contains a property logging.config then that will be used to initialize
* the logging system, otherwise a default location is used. The classpath is probed for
* log4j and logback and if those are present they will be reconfigured, otherwise vanilla
- * java.util.logging will be used.
- *
+ * java.util.logging will be used.
*
*
* The default config locations are classpath:log4j.properties or
@@ -57,12 +58,21 @@ import org.springframework.util.Log4jConfigurer;
*
PID is set to the value of the current process ID if it can be
* determined
*
- * @author Dave Syer
*
+ * @author Dave Syer
+ * @author Phillip Webb
*/
public class LoggingInitializer implements
ApplicationContextInitializer, Ordered {
+ private static final Map ENVIRONMENT_SYSTEM_PROPERTY_MAPPING;
+ static {
+ ENVIRONMENT_SYSTEM_PROPERTY_MAPPING = new HashMap();
+ ENVIRONMENT_SYSTEM_PROPERTY_MAPPING.put("logging.file", "LOG_FILE");
+ ENVIRONMENT_SYSTEM_PROPERTY_MAPPING.put("logging.path", "LOG_PATH");
+ ENVIRONMENT_SYSTEM_PROPERTY_MAPPING.put("PID", "PID");
+ }
+
private int order = Integer.MIN_VALUE + 1;
/**
@@ -72,94 +82,22 @@ public class LoggingInitializer implements
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
- String configLocation = getDefaultConfigLocation();
-
ConfigurableEnvironment environment = applicationContext.getEnvironment();
- if (environment.containsProperty("logging.config")) {
- configLocation = environment.getProperty("logging.config");
+ for (Map.Entry mapping : ENVIRONMENT_SYSTEM_PROPERTY_MAPPING
+ .entrySet()) {
+ if (environment.containsProperty(mapping.getKey())) {
+ System.setProperty(mapping.getValue(),
+ environment.getProperty(mapping.getKey()));
+ }
}
- if (environment.containsProperty("logging.file")) {
- String location = environment.getProperty("logging.file");
- System.setProperty("LOG_FILE", location);
- }
-
- if (environment.containsProperty("logging.path")) {
- String location = environment.getProperty("logging.path");
- System.setProperty("LOG_PATH", location);
- }
-
- if (!environment.containsProperty("PID")) {
+ if (System.getProperty("PID") == null) {
System.setProperty("PID", getPid());
}
- initLogging(applicationContext, configLocation);
-
- }
-
- private void initLogging(ResourceLoader resourceLoader, String configLocation) {
- try {
- if (isLog4jPresent()) {
- Log4jConfigurer.initLogging(configLocation);
- } else {
- if (isLogbackPresent()) {
- LogbackConfigurer.initLogging(configLocation);
- } else {
- JavaLoggerConfigurer.initLogging(configLocation);
- }
- }
- } catch (RuntimeException e) {
- throw e;
-
- } catch (Exception e) {
- throw new IllegalStateException("Cannot initialize logging from "
- + configLocation, e);
- }
- }
-
- private boolean isLogbackPresent() {
- return ClassUtils.isPresent("ch.qos.logback.core.Appender",
- ClassUtils.getDefaultClassLoader());
- }
-
- private boolean isLog4jPresent() {
- return ClassUtils.isPresent("org.apache.log4j.PropertyConfigurator",
- ClassUtils.getDefaultClassLoader());
- }
-
- private String getDefaultConfigLocation() {
-
- String defaultPath = ClassUtils.getPackageName(LoggingInitializer.class).replace(
- ".", "/")
- + "/";
-
- if (isLog4jPresent()) {
- String path = "log4j.xml";
- if (!new ClassPathResource(path).exists()) {
- path = "log4j.properties";
- if (!new ClassPathResource(path).exists()) {
- path = defaultPath + path;
- }
- }
- return "classpath:" + path;
- }
-
- if (isLogbackPresent()) {
- String path = "logback.xml";
- if (!new ClassPathResource(path).exists()) {
- path = defaultPath + path;
- }
- return "classpath:" + path;
- }
-
- String path = "logging.properties";
- if (!new ClassPathResource(path).exists()) {
- path = defaultPath + path;
- }
-
- return "classpath:" + path;
-
+ LoggingSystem system = LoggingSystem.get(applicationContext.getClassLoader());
+ system.init(applicationContext);
}
private String getPid() {
@@ -178,4 +116,104 @@ public class LoggingInitializer implements
public int getOrder() {
return this.order;
}
+
+ private static enum LoggingSystem {
+
+ /**
+ * Log4J
+ */
+ LOG4J("org.apache.log4j.PropertyConfigurator", "log4j.xml", "log4j.properties") {
+
+ @Override
+ protected void doInit(ApplicationContext applicationContext,
+ String configLocation) throws Exception {
+ Log4jConfigurer.initLogging(configLocation);
+ }
+ },
+
+ /**
+ * Logback
+ */
+ LOGBACK("ch.qos.logback.core.Appender", "logback.xml") {
+
+ @Override
+ protected void doInit(ApplicationContext applicationContext,
+ String configLocation) throws Exception {
+ LogbackConfigurer.initLogging(configLocation);
+ }
+ },
+
+ /**
+ * Java Util Logging
+ */
+ JAVA(null, "logging.properties") {
+
+ @Override
+ protected void doInit(ApplicationContext applicationContext,
+ String configLocation) throws Exception {
+ JavaLoggerConfigurer.initLogging(configLocation);
+ }
+ };
+
+ private final String className;
+
+ private final String[] paths;
+
+ private LoggingSystem(String className, String... paths) {
+ this.className = className;
+ this.paths = paths;
+ }
+
+ public void init(ApplicationContext applicationContext) {
+ String configLocation = getConfigLocation(applicationContext);
+ try {
+ doInit(applicationContext, configLocation);
+ } catch (RuntimeException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new IllegalStateException("Cannot initialize logging from "
+ + configLocation, ex);
+ }
+
+ }
+
+ protected abstract void doInit(ApplicationContext applicationContext,
+ String configLocation) throws Exception;
+
+ private String getConfigLocation(ApplicationContext applicationContext) {
+ Environment environment = applicationContext.getEnvironment();
+ ClassLoader classLoader = applicationContext.getClassLoader();
+
+ // User specified config
+ if (environment.containsProperty("logging.config")) {
+ return environment.getProperty("logging.config");
+ }
+
+ // Common patterns
+ for (String path : this.paths) {
+ ClassPathResource resource = new ClassPathResource(path, classLoader);
+ if (resource.exists()) {
+ return "classpath:" + path;
+ }
+ }
+
+ // Fallback to the default
+ String defaultPath = ClassUtils.getPackageName(LoggingInitializer.class);
+ defaultPath = defaultPath.replace(".", "/");
+ defaultPath = defaultPath + "/" + this.paths[this.paths.length - 1];
+ return "classpath:" + defaultPath;
+ }
+
+ public static LoggingSystem get(ClassLoader classLoader) {
+ for (LoggingSystem loggingSystem : values()) {
+ String className = loggingSystem.className;
+ if (className == null || ClassUtils.isPresent(className, classLoader)) {
+ return loggingSystem;
+ }
+ }
+ return JAVA;
+ }
+
+ }
+
}
diff --git a/spring-bootstrap/src/test/java/org/springframework/bootstrap/logging/LoggingInitializerTests.java b/spring-bootstrap/src/test/java/org/springframework/bootstrap/logging/LoggingInitializerTests.java
index 93f444bff9f..8ed3bfc9f01 100644
--- a/spring-bootstrap/src/test/java/org/springframework/bootstrap/logging/LoggingInitializerTests.java
+++ b/spring-bootstrap/src/test/java/org/springframework/bootstrap/logging/LoggingInitializerTests.java
@@ -31,7 +31,6 @@ import static org.junit.Assert.assertTrue;
/**
* @author Dave Syer
- *
*/
public class LoggingInitializerTests {