diff --git a/build.gradle b/build.gradle index a4df6f1287..261dac5ec7 100644 --- a/build.gradle +++ b/build.gradle @@ -58,7 +58,7 @@ configure(allprojects) { project -> ext.httpclientVersion = "4.5.3" ext.interceptorApiVersion = "1.2" ext.jackson2Version = "2.9.0.pr2" - ext.javamailVersion = "1.5.6" + ext.javamailVersion = "1.6.0-rc1" ext.jaxbVersion = "2.2.11" ext.jaxwsVersion = "2.2.11" ext.jcaVersion = "1.7" @@ -83,20 +83,20 @@ configure(allprojects) { project -> ext.romeVersion = "1.7.1" ext.rxjavaVersion = '1.2.9' ext.rxjavaAdapterVersion = '1.2.1' - ext.rxjava2Version = '2.0.7' + ext.rxjava2Version = '2.0.8' ext.rxnettyVersion = '0.5.2' ext.servletVersion = "3.1.0" ext.slf4jVersion = "1.7.25" ext.snakeyamlVersion = "1.18" ext.testngVersion = "6.11" ext.tiles3Version = "3.0.7" - ext.tomcatVersion = "8.5.12" + ext.tomcatVersion = "8.5.13" ext.tyrusVersion = "1.13.1" - ext.undertowVersion = "1.4.11.Final" + ext.undertowVersion = "1.4.12.Final" ext.websocketVersion = "1.1" ext.woodstoxVersion = "5.0.3" ext.xmlunitVersion = "2.3.0" - ext.xnioVersion = "3.4.3.Final" + ext.xnioVersion = "3.4.5.Final" ext.xstreamVersion = "1.4.9" ext.gradleScriptDir = "${rootProject.projectDir}/gradle" @@ -188,7 +188,6 @@ configure(allprojects) { project -> } testCompile("org.hamcrest:hamcrest-all:${hamcrestVersion}") testRuntime("org.apache.logging.log4j:log4j-core:${log4jVersion}") - testRuntime("org.apache.logging.log4j:log4j-jcl:${log4jVersion}") } ext.javadocLinks = [ @@ -364,7 +363,8 @@ project("spring-core") { compile(files(cglibRepackJar)) compile(files(objenesisRepackJar)) - compile("commons-logging:commons-logging:1.2") + optional("org.apache.logging.log4j:log4j-api:${log4jVersion}") + optional("org.slf4j:slf4j-api:${slf4jVersion}") optional("net.sf.jopt-simple:jopt-simple:5.0.3") optional("org.aspectj:aspectjweaver:${aspectjVersion}") optional("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}") @@ -372,8 +372,8 @@ project("spring-core") { optional("org.reactivestreams:reactive-streams") optional("io.projectreactor:reactor-core") optional "io.reactivex:rxjava:${rxjavaVersion}" - optional "io.reactivex.rxjava2:rxjava:${rxjava2Version}" optional "io.reactivex:rxjava-reactive-streams:${rxjavaAdapterVersion}" + optional "io.reactivex.rxjava2:rxjava:${rxjava2Version}" optional("io.netty:netty-buffer:${nettyVersion}") testCompile("io.projectreactor.addons:reactor-test") testCompile("javax.xml.bind:jaxb-api:${jaxbVersion}") @@ -577,7 +577,6 @@ project("spring-messaging") { testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}") testCompile("io.netty:netty-all:${nettyVersion}") testCompile("org.xmlunit:xmlunit-matchers:${xmlunitVersion}") - testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}") testCompile("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}") testCompile("org.jetbrains.kotlin:kotlin-stdlib-jre8:${kotlinVersion}") testRuntime("javax.activation:activation:${activationApiVersion}") @@ -712,8 +711,8 @@ project("spring-web") { exclude group: 'io.reactivex', module: 'rxjava' } optional("io.reactivex:rxjava:${rxjavaVersion}") - optional "io.reactivex.rxjava2:rxjava:${rxjava2Version}" optional("io.reactivex:rxjava-reactive-streams:${rxjavaAdapterVersion}") + optional "io.reactivex.rxjava2:rxjava:${rxjava2Version}" optional("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}") optional("io.undertow:undertow-core:${undertowVersion}") optional("org.jboss.xnio:xnio-api:${xnioVersion}") @@ -759,7 +758,6 @@ project("spring-web") { testCompile("org.eclipse.jetty:jetty-servlet:${jettyVersion}") testCompile("com.squareup.okhttp3:mockwebserver:${okhttp3Version}") testCompile("org.xmlunit:xmlunit-matchers:${xmlunitVersion}") - testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}") testCompile("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}") testRuntime("com.sun.mail:javax.mail:${javamailVersion}") testRuntime("com.sun.xml.bind:jaxb-core:${jaxbVersion}") @@ -820,7 +818,6 @@ project("spring-webflux") { testCompile("org.jboss.xnio:xnio-api:${xnioVersion}") testCompile("com.fasterxml:aalto-xml:1.0.0") testCompile("org.xmlunit:xmlunit-matchers:${xmlunitVersion}") - testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}") testCompile("com.squareup.okhttp3:mockwebserver:${okhttp3Version}") testRuntime("javax.el:javax.el-api:${elApiVersion}") testRuntime("org.glassfish:javax.el:3.0.1-b08") @@ -863,7 +860,6 @@ project("spring-orm") { optional("javax.servlet:javax.servlet-api:${servletVersion}") testCompile("org.aspectj:aspectjweaver:${aspectjVersion}") testCompile("org.hsqldb:hsqldb:${hsqldbVersion}") - testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}") testRuntime("javax.xml.bind:jaxb-api:${jaxbVersion}") } } @@ -936,7 +932,6 @@ project("spring-webmvc") { testCompile("commons-fileupload:commons-fileupload:${fileuploadVersion}") testCompile("commons-io:commons-io:2.5") testCompile("joda-time:joda-time:${jodaVersion}") - testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}") testCompile("org.mozilla:rhino:1.7.7.1") testCompile("io.projectreactor:reactor-core") testCompile("io.reactivex:rxjava:${rxjavaVersion}") @@ -997,7 +992,6 @@ project("spring-websocket") { testCompile("io.projectreactor:reactor-core") testCompile("io.projectreactor.ipc:reactor-netty") testCompile("io.netty:netty-all:${nettyVersion}") - testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}") testRuntime("org.jboss.xnio:xnio-nio:${xnioVersion}") testRuntime("org.jboss.logging:jboss-logging:3.3.1.Final") } @@ -1070,7 +1064,6 @@ project("spring-test") { exclude group: "org.slf4j", module: "jcl-over-slf4j" } testCompile("org.hsqldb:hsqldb:${hsqldbVersion}") - testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}") testCompile("org.apache.httpcomponents:httpclient:${httpclientVersion}") testCompile("javax.cache:cache-api:${cacheApiVersion}") testCompile('de.bechte.junit:junit-hierarchicalcontextrunner:4.12.1') diff --git a/spring-core/src/main/java/org/apache/commons/logging/Log.java b/spring-core/src/main/java/org/apache/commons/logging/Log.java new file mode 100644 index 0000000000..5c5523d5a1 --- /dev/null +++ b/spring-core/src/main/java/org/apache/commons/logging/Log.java @@ -0,0 +1,216 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.logging; + +/** + * A simple logging interface abstracting logging APIs. In order to be + * instantiated successfully by {@link LogFactory}, classes that implement + * this interface must have a constructor that takes a single String + * parameter representing the "name" of this Log. + *
+ * The six logging levels used by Log are (in order):
+ *
+ * Performance is often a logging concern. + * By examining the appropriate property, + * a component can avoid expensive operations (producing information + * to be logged). + *
+ * For example, + *
+ * if (log.isDebugEnabled()) {
+ * ... do something expensive ...
+ * log.debug(theResult);
+ * }
+ *
+ * + * Configuration of the underlying logging system will generally be done + * external to the Logging APIs, through whatever mechanism is supported by + * that system. + * + * @version $Id: Log.java 1606045 2014-06-27 12:11:56Z tn $ + */ +public interface Log { + + /** + * Logs a message with debug log level. + * + * @param message log this message + */ + void debug(Object message); + + /** + * Logs an error with debug log level. + * + * @param message log this message + * @param t log this cause + */ + void debug(Object message, Throwable t); + + /** + * Logs a message with error log level. + * + * @param message log this message + */ + void error(Object message); + + /** + * Logs an error with error log level. + * + * @param message log this message + * @param t log this cause + */ + void error(Object message, Throwable t); + + /** + * Logs a message with fatal log level. + * + * @param message log this message + */ + void fatal(Object message); + + /** + * Logs an error with fatal log level. + * + * @param message log this message + * @param t log this cause + */ + void fatal(Object message, Throwable t); + + /** + * Logs a message with info log level. + * + * @param message log this message + */ + void info(Object message); + + /** + * Logs an error with info log level. + * + * @param message log this message + * @param t log this cause + */ + void info(Object message, Throwable t); + + /** + * Is debug logging currently enabled? + *
+ * Call this method to prevent having to perform expensive operations
+ * (for example, String concatenation)
+ * when the log level is more than debug.
+ *
+ * @return true if debug is enabled in the underlying logger.
+ */
+ boolean isDebugEnabled();
+
+ /**
+ * Is error logging currently enabled?
+ *
+ * Call this method to prevent having to perform expensive operations
+ * (for example, String concatenation)
+ * when the log level is more than error.
+ *
+ * @return true if error is enabled in the underlying logger.
+ */
+ boolean isErrorEnabled();
+
+ /**
+ * Is fatal logging currently enabled?
+ *
+ * Call this method to prevent having to perform expensive operations
+ * (for example, String concatenation)
+ * when the log level is more than fatal.
+ *
+ * @return true if fatal is enabled in the underlying logger.
+ */
+ boolean isFatalEnabled();
+
+ /**
+ * Is info logging currently enabled?
+ *
+ * Call this method to prevent having to perform expensive operations
+ * (for example, String concatenation)
+ * when the log level is more than info.
+ *
+ * @return true if info is enabled in the underlying logger.
+ */
+ boolean isInfoEnabled();
+
+ /**
+ * Is trace logging currently enabled?
+ *
+ * Call this method to prevent having to perform expensive operations
+ * (for example, String concatenation)
+ * when the log level is more than trace.
+ *
+ * @return true if trace is enabled in the underlying logger.
+ */
+ boolean isTraceEnabled();
+
+ /**
+ * Is warn logging currently enabled?
+ *
+ * Call this method to prevent having to perform expensive operations
+ * (for example, String concatenation)
+ * when the log level is more than warn.
+ *
+ * @return true if warn is enabled in the underlying logger.
+ */
+ boolean isWarnEnabled();
+
+ /**
+ * Logs a message with trace log level.
+ *
+ * @param message log this message
+ */
+ void trace(Object message);
+
+ /**
+ * Logs an error with trace log level.
+ *
+ * @param message log this message
+ * @param t log this cause
+ */
+ void trace(Object message, Throwable t);
+
+ /**
+ * Logs a message with warn log level.
+ *
+ * @param message log this message
+ */
+ void warn(Object message);
+
+ /**
+ * Logs an error with warn log level.
+ *
+ * @param message log this message
+ * @param t log this cause
+ */
+ void warn(Object message, Throwable t);
+}
diff --git a/spring-core/src/main/java/org/apache/commons/logging/LogFactory.java b/spring-core/src/main/java/org/apache/commons/logging/LogFactory.java
new file mode 100644
index 0000000000..b849364fd2
--- /dev/null
+++ b/spring-core/src/main/java/org/apache/commons/logging/LogFactory.java
@@ -0,0 +1,553 @@
+/*
+ * Copyright 2002-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.logging;
+
+import java.io.Serializable;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+import org.apache.logging.log4j.spi.LoggerContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.spi.LocationAwareLogger;
+
+/**
+ * A minimal incarnation of Apache Commons Logging's {@code LogFactory} API,
+ * providing just the two common static {@link Log} lookup methods.
+ * This should be source and binary compatible with all common use of the
+ * Commons Logging API (i.e. {@code LogFactory.getLog(Class/String)} setup).
+ *
+ *
This implementation does not support any of Commons Logging's flexible + * configuration. It rather only checks for the presence of the Log4J 2.x API + * and the SLF4J 1.7 API in the framework classpath, falling back to + * {@code java.util.logging} if none of the two is available. In that sense, + * it works as a replacement for the Log4j 2 Commons Logging bridge as well as + * the JCL-over-SLF4J bridge, both of which become irrelevant for Spring-based + * setups as a consequence (with no need for manual excludes of the standard + * Commons Logging API jar anymore either). Furthermore, for simple setups + * without an external logging provider, Spring does not require any extra jar + * on the classpath anymore since this embedded log factory automatically + * switches to {@code java.util.logging} in such a scenario. + * + *
Note that this Commons Logging variant is only meant to be used for
+ * framework logging purposes, both in the core framework and in extensions.
+ * For applications, prefer direct use of Log4J or SLF4J or {@code java.util.logging}.
+ *
+ * @author Juergen Hoeller
+ * @since 5.0
+ */
+public abstract class LogFactory {
+
+ private static LogApi logApi = LogApi.JUL;
+
+ static {
+ ClassLoader cl = LogFactory.class.getClassLoader();
+ try {
+ // Try Log4J 2.x API
+ cl.loadClass("org.apache.logging.log4j.spi.LoggerContext");
+ logApi = LogApi.LOG4J;
+ }
+ catch (ClassNotFoundException ex) {
+ try {
+ // Try SLF4J 1.7 API
+ cl.loadClass("org.slf4j.LoggerFactory");
+ logApi = LogApi.SLF4J;
+ }
+ catch (ClassNotFoundException ex2) {
+ // Keep java.util.logging as default
+ }
+ }
+ }
+
+
+ /**
+ * Convenience method to return a named logger.
+ * @param clazz containing Class from which a log name will be derived
+ */
+ public static Log getLog(Class> clazz) {
+ return getLog(clazz.getName());
+ }
+
+ /**
+ * Convenience method to return a named logger.
+ * @param name logical name of the Log instance to be returned
+ */
+ public static Log getLog(String name) {
+ switch (logApi) {
+ case LOG4J:
+ return Log4jDelegate.createLog(name);
+ case SLF4J:
+ return Slf4jDelegate.createLog(name);
+ default:
+ return new JavaUtilLog(name);
+ }
+ }
+
+
+ private enum LogApi {LOG4J, SLF4J, JUL}
+
+
+ private static class Log4jDelegate {
+
+ public static Log createLog(String name) {
+ return new Log4jLog(name);
+ }
+ }
+
+
+ private static class Slf4jDelegate {
+
+ public static Log createLog(String name) {
+ return new Slf4jLog(name);
+ }
+ }
+
+
+ @SuppressWarnings("serial")
+ private static class Log4jLog implements Log, Serializable {
+
+ private static final String FQCN = Log4jLog.class.getName();
+
+ private static final LoggerContext loggerContext = LogManager.getContext();
+
+ private final ExtendedLogger logger;
+
+ public Log4jLog(String name) {
+ this.logger = loggerContext.getLogger(name);
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return logger.isEnabled(Level.DEBUG, null, null);
+ }
+
+ @Override
+ public boolean isErrorEnabled() {
+ return logger.isEnabled(Level.ERROR, null, null);
+ }
+
+ @Override
+ public boolean isFatalEnabled() {
+ return logger.isEnabled(Level.FATAL, null, null);
+ }
+
+ @Override
+ public boolean isInfoEnabled() {
+ return logger.isEnabled(Level.INFO, null, null);
+ }
+
+ @Override
+ public boolean isTraceEnabled() {
+ return logger.isEnabled(Level.TRACE, null, null);
+ }
+
+ @Override
+ public boolean isWarnEnabled() {
+ return logger.isEnabled(Level.WARN, null, null);
+ }
+
+ @Override
+ public void debug(Object message) {
+ logger.logIfEnabled(FQCN, Level.DEBUG, null, message, null);
+ }
+
+ @Override
+ public void debug(Object message, Throwable exception) {
+ logger.logIfEnabled(FQCN, Level.DEBUG, null, message, exception);
+ }
+
+ @Override
+ public void error(Object message) {
+ logger.logIfEnabled(FQCN, Level.ERROR, null, message, null);
+ }
+
+ @Override
+ public void error(Object message, Throwable exception) {
+ logger.logIfEnabled(FQCN, Level.ERROR, null, message, exception);
+ }
+
+ @Override
+ public void fatal(Object message) {
+ logger.logIfEnabled(FQCN, Level.FATAL, null, message, null);
+ }
+
+ @Override
+ public void fatal(Object message, Throwable exception) {
+ logger.logIfEnabled(FQCN, Level.FATAL, null, message, exception);
+ }
+
+ @Override
+ public void info(Object message) {
+ logger.logIfEnabled(FQCN, Level.INFO, null, message, null);
+ }
+
+ @Override
+ public void info(Object message, Throwable exception) {
+ logger.logIfEnabled(FQCN, Level.INFO, null, message, exception);
+ }
+
+ @Override
+ public void trace(Object message) {
+ logger.logIfEnabled(FQCN, Level.TRACE, null, message, null);
+ }
+
+ @Override
+ public void trace(Object message, Throwable exception) {
+ logger.logIfEnabled(FQCN, Level.TRACE, null, message, exception);
+ }
+
+ @Override
+ public void warn(Object message) {
+ logger.logIfEnabled(FQCN, Level.WARN, null, message, null);
+ }
+
+ @Override
+ public void warn(Object message, Throwable exception) {
+ logger.logIfEnabled(FQCN, Level.WARN, null, message, exception);
+ }
+ }
+
+
+ @SuppressWarnings("serial")
+ private static class Slf4jLog implements Log, Serializable {
+
+ private static final String FQCN = Slf4jLog.class.getName();
+
+ private final String name;
+
+ private transient Logger logger;
+
+ private transient LocationAwareLogger locLogger;
+
+ public Slf4jLog(String name) {
+ this.name = name;
+ this.logger = LoggerFactory.getLogger(this.name);
+ this.locLogger = (this.logger instanceof LocationAwareLogger ? (LocationAwareLogger) this.logger : null);
+ }
+
+ public boolean isDebugEnabled() {
+ return this.logger.isDebugEnabled();
+ }
+
+ public boolean isErrorEnabled() {
+ return this.logger.isErrorEnabled();
+ }
+
+ public boolean isFatalEnabled() {
+ return this.logger.isErrorEnabled();
+ }
+
+ public boolean isInfoEnabled() {
+ return this.logger.isInfoEnabled();
+ }
+
+ public boolean isTraceEnabled() {
+ return this.logger.isTraceEnabled();
+ }
+
+ public boolean isWarnEnabled() {
+ return this.logger.isWarnEnabled();
+ }
+
+ public void debug(Object message) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, String.valueOf(message), null, null);
+ }
+ else {
+ this.logger.debug(String.valueOf(message));
+ }
+ }
+
+ public void debug(Object message, Throwable exception) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, String.valueOf(message), null, exception);
+ }
+ else {
+ this.logger.debug(String.valueOf(message), exception);
+ }
+ }
+
+ public void error(Object message) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, null);
+ }
+ else {
+ this.logger.error(String.valueOf(message));
+ }
+ }
+
+ public void error(Object message, Throwable exception) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, exception);
+ }
+ else {
+ this.logger.error(String.valueOf(message), exception);
+ }
+ }
+
+ public void fatal(Object message) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, null);
+ }
+ else {
+ this.logger.error(String.valueOf(message));
+ }
+ }
+
+ public void fatal(Object message, Throwable exception) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.ERROR_INT, String.valueOf(message), null, exception);
+ }
+ else {
+ this.logger.error(String.valueOf(message), exception);
+ }
+ }
+
+ public void info(Object message) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.INFO_INT, String.valueOf(message), null, null);
+ }
+ else {
+ this.logger.info(String.valueOf(message));
+ }
+ }
+
+ public void info(Object message, Throwable exception) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.INFO_INT, String.valueOf(message), null, exception);
+ }
+ else {
+ this.logger.info(String.valueOf(message), exception);
+ }
+ }
+
+ public void trace(Object message) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.TRACE_INT, String.valueOf(message), null, null);
+ }
+ else {
+ this.logger.trace(String.valueOf(message));
+ }
+ }
+
+ public void trace(Object message, Throwable exception) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.TRACE_INT, String.valueOf(message), null, exception);
+ }
+ else {
+ this.logger.trace(String.valueOf(message), exception);
+ }
+ }
+
+ public void warn(Object message) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.WARN_INT, String.valueOf(message), null, null);
+ }
+ else {
+ this.logger.warn(String.valueOf(message));
+ }
+ }
+
+ public void warn(Object message, Throwable exception) {
+ if (this.locLogger != null) {
+ this.locLogger.log(null, FQCN, LocationAwareLogger.WARN_INT, String.valueOf(message), null, exception);
+ }
+ else {
+ this.logger.warn(String.valueOf(message), exception);
+ }
+ }
+
+ protected Object readResolve() {
+ return new Slf4jLog(this.name);
+ }
+ }
+
+
+ @SuppressWarnings("serial")
+ private static class JavaUtilLog implements Log, Serializable {
+
+ private String name;
+
+ private transient java.util.logging.Logger logger;
+
+ public JavaUtilLog(String name) {
+ this.name = name;
+ this.logger = java.util.logging.Logger.getLogger(name);
+ }
+
+ public boolean isDebugEnabled() {
+ return this.logger.isLoggable(java.util.logging.Level.FINE);
+ }
+
+ public boolean isErrorEnabled() {
+ return this.logger.isLoggable(java.util.logging.Level.SEVERE);
+ }
+
+ public boolean isFatalEnabled() {
+ return this.logger.isLoggable(java.util.logging.Level.SEVERE);
+ }
+
+ public boolean isInfoEnabled() {
+ return this.logger.isLoggable(java.util.logging.Level.INFO);
+ }
+
+ public boolean isTraceEnabled() {
+ return this.logger.isLoggable(java.util.logging.Level.FINEST);
+ }
+
+ public boolean isWarnEnabled() {
+ return this.logger.isLoggable(java.util.logging.Level.WARNING);
+ }
+
+ public void debug(Object message) {
+ log(java.util.logging.Level.FINE, message, null);
+ }
+
+ public void debug(Object message, Throwable exception) {
+ log(java.util.logging.Level.FINE, message, exception);
+ }
+
+ public void error(Object message) {
+ log(java.util.logging.Level.SEVERE, message, null);
+ }
+
+ public void error(Object message, Throwable exception) {
+ log(java.util.logging.Level.SEVERE, message, exception);
+ }
+
+ public void fatal(Object message) {
+ log(java.util.logging.Level.SEVERE, message, null);
+ }
+
+ public void fatal(Object message, Throwable exception) {
+ log(java.util.logging.Level.SEVERE, message, exception);
+ }
+
+ public void info(Object message) {
+ log(java.util.logging.Level.INFO, message, null);
+ }
+
+ public void info(Object message, Throwable exception) {
+ log(java.util.logging.Level.INFO, message, exception);
+ }
+
+ public void trace(Object message) {
+ log(java.util.logging.Level.FINEST, message, null);
+ }
+
+ public void trace(Object message, Throwable exception) {
+ log(java.util.logging.Level.FINEST, message, exception);
+ }
+
+ public void warn(Object message) {
+ log(java.util.logging.Level.WARNING, message, null);
+ }
+
+ public void warn(Object message, Throwable exception) {
+ log(java.util.logging.Level.WARNING, message, exception);
+ }
+
+ private void log(java.util.logging.Level level, Object message, Throwable exception) {
+ if (logger.isLoggable(level)) {
+ LocationResolvingLogRecord rec = new LocationResolvingLogRecord(level, String.valueOf(message));
+ rec.setLoggerName(this.name);
+ rec.setResourceBundleName(logger.getResourceBundleName());
+ rec.setResourceBundle(logger.getResourceBundle());
+ rec.setThrown(exception);
+ logger.log(rec);
+ }
+ }
+
+ protected Object readResolve() {
+ return new JavaUtilLog(this.name);
+ }
+ }
+
+
+ @SuppressWarnings("serial")
+ private static class LocationResolvingLogRecord extends java.util.logging.LogRecord {
+
+ private static final String FQCN = JavaUtilLog.class.getName();
+
+ private volatile boolean resolved;
+
+ public LocationResolvingLogRecord(java.util.logging.Level level, String msg) {
+ super(level, msg);
+ }
+
+ public String getSourceClassName() {
+ if (!this.resolved) {
+ resolve();
+ }
+ return super.getSourceClassName();
+ }
+
+ public void setSourceClassName(String sourceClassName) {
+ super.setSourceClassName(sourceClassName);
+ this.resolved = true;
+ }
+
+ public String getSourceMethodName() {
+ if (!this.resolved) {
+ resolve();
+ }
+ return super.getSourceMethodName();
+ }
+
+ public void setSourceMethodName(String sourceMethodName) {
+ super.setSourceMethodName(sourceMethodName);
+ this.resolved = true;
+ }
+
+ private void resolve() {
+ StackTraceElement[] stack = new Throwable().getStackTrace();
+ String sourceClassName = null;
+ String sourceMethodName = null;
+ boolean found = false;
+ for (StackTraceElement element : stack) {
+ String className = element.getClassName();
+ if (FQCN.equals(className)) {
+ found = true;
+ }
+ else if (found) {
+ sourceClassName = className;
+ sourceMethodName = element.getMethodName();
+ break;
+ }
+ }
+ setSourceClassName(sourceClassName);
+ setSourceMethodName(sourceMethodName);
+ }
+
+ protected Object writeReplace() {
+ java.util.logging.LogRecord serialized = new java.util.logging.LogRecord(getLevel(), getMessage());
+ serialized.setLoggerName(getLoggerName());
+ serialized.setResourceBundle(getResourceBundle());
+ serialized.setResourceBundleName(getResourceBundleName());
+ serialized.setSourceClassName(getSourceClassName());
+ serialized.setSourceMethodName(getSourceMethodName());
+ serialized.setSequenceNumber(getSequenceNumber());
+ serialized.setParameters(getParameters());
+ serialized.setThreadID(getThreadID());
+ serialized.setMillis(getMillis());
+ serialized.setThrown(getThrown());
+ return serialized;
+ }
+ }
+
+}
diff --git a/spring-core/src/main/java/org/apache/commons/logging/package-info.java b/spring-core/src/main/java/org/apache/commons/logging/package-info.java
new file mode 100644
index 0000000000..8704c7664c
--- /dev/null
+++ b/spring-core/src/main/java/org/apache/commons/logging/package-info.java
@@ -0,0 +1,16 @@
+/**
+ * Spring's variant of the
+ * Commons Logging API
+ * (for internal use only).
+ *
+ *
{@link org.apache.commons.logging.Log} is an unmodified repackaging. + * However, {@link org.apache.commons.logging.LogFactory} is a very different + * implementation which is minimized and optimized for Spring's purposes, + * detecting Log4J 2.x and SLF4J 1.7 in the framework classpath and falling + * back to {@code java.util.logging}. + * + *
Note that this Commons Logging variant is only meant to be used for + * framework logging purposes, both in the core framework and in extensions. + * For applications, prefer direct use of Log4J or SLF4J or {@code java.util.logging}. + */ +package org.apache.commons.logging; diff --git a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java index 53d84e2988..4e6237eae6 100644 --- a/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/support/PathMatchingResourcePatternResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,10 +51,8 @@ public class PathMatchingResourcePatternResolverTests { private static final String[] TEST_CLASSES_IN_CORE_IO_SUPPORT = new String[] {"PathMatchingResourcePatternResolverTests.class"}; - private static final String[] CLASSES_IN_COMMONSLOGGING = - new String[] {"Log.class", "LogConfigurationException.class", "LogFactory.class", - "LogFactory$1.class", "LogFactory$2.class", "LogFactory$3.class", "LogFactory$4.class", - "LogFactory$5.class", "LogFactory$6.class", "LogSource.class"}; + private static final String[] CLASSES_IN_REACTIVESTREAMS = + new String[] {"Processor.class", "Publisher.class", "Subscriber.class", "Subscription.class"}; private PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); @@ -74,9 +72,9 @@ public class PathMatchingResourcePatternResolverTests { @Test public void singleResourceInJar() throws IOException { - Resource[] resources = resolver.getResources("org/apache/commons/logging/Log.class"); + Resource[] resources = resolver.getResources("org/reactivestreams/Publisher.class"); assertEquals(1, resources.length); - assertProtocolAndFilenames(resources, "jar", "Log.class"); + assertProtocolAndFilenames(resources, "jar", "Publisher.class"); } @Ignore // passes under Eclipse, fails under Ant @@ -98,14 +96,14 @@ public class PathMatchingResourcePatternResolverTests { @Test public void classpathWithPatternInJar() throws IOException { - Resource[] resources = resolver.getResources("classpath:org/apache/commons/logging/*.class"); - assertProtocolAndFilenames(resources, "jar", CLASSES_IN_COMMONSLOGGING); + Resource[] resources = resolver.getResources("classpath:org/reactivestreams/*.class"); + assertProtocolAndFilenames(resources, "jar", CLASSES_IN_REACTIVESTREAMS); } @Test - public void classpathStartWithPatternInJar() throws IOException { - Resource[] resources = resolver.getResources("classpath*:org/apache/commons/logging/*.class"); - assertProtocolAndFilenames(resources, "jar", CLASSES_IN_COMMONSLOGGING); + public void classpathStarWithPatternInJar() throws IOException { + Resource[] resources = resolver.getResources("classpath*:org/reactivestreams/*.class"); + assertProtocolAndFilenames(resources, "jar", CLASSES_IN_REACTIVESTREAMS); } @Test