blob: 146bf7856822307d3a2c60bf52793c669329f036 [file] [log] [blame]
Ceki Gulcu7ba06052011-10-16 10:28:44 +02001/**
2 * Copyright (c) 2004-2011 QOS.ch
Ceki Gulcu88c4c452009-12-03 19:16:42 +01003 * All rights reserved.
Ceki Gulcu7ba06052011-10-16 10:28:44 +02004 *
Ceki Gulcu88c4c452009-12-03 19:16:42 +01005 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
Ceki Gulcu7ba06052011-10-16 10:28:44 +020012 *
Ceki Gulcu88c4c452009-12-03 19:16:42 +010013 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
Ceki Gulcu7ba06052011-10-16 10:28:44 +020015 *
Ceki Gulcu88c4c452009-12-03 19:16:42 +010016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Ceki Gulcu7ba06052011-10-16 10:28:44 +020023 *
Ceki Gulcu88c4c452009-12-03 19:16:42 +010024 */
Ceki Gulcu88c4c452009-12-03 19:16:42 +010025package org.slf4j;
26
27import java.io.IOException;
28import java.net.URL;
Hendy Irawan2f82a782013-09-11 15:28:23 +070029import java.util.Arrays;
30import java.util.Enumeration;
31import java.util.Iterator;
32import java.util.LinkedHashSet;
33import java.util.List;
34import java.util.Set;
35
36import javax.annotation.Nonnull;
Ceki Gulcu88c4c452009-12-03 19:16:42 +010037
Ceki Gulcud1d27b82010-04-06 13:57:15 +020038import org.slf4j.helpers.NOPLoggerFactory;
Ceki Gulcu8f28a832014-02-03 20:05:23 +010039import org.slf4j.helpers.SubstituteLogger;
Ceki Gulcu88c4c452009-12-03 19:16:42 +010040import org.slf4j.helpers.SubstituteLoggerFactory;
41import org.slf4j.helpers.Util;
42import org.slf4j.impl.StaticLoggerBinder;
43
44/**
45 * The <code>LoggerFactory</code> is a utility class producing Loggers for
Ceki Gulcu9f104902010-10-19 17:22:20 +020046 * various logging APIs, most notably for log4j, logback and JDK 1.4 logging.
Ceki Gulcu88c4c452009-12-03 19:16:42 +010047 * Other implementations such as {@link org.slf4j.impl.NOPLogger NOPLogger} and
48 * {@link org.slf4j.impl.SimpleLogger SimpleLogger} are also supported.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +020049 * <p/>
50 * <p/>
Ceki Gulcu88c4c452009-12-03 19:16:42 +010051 * <code>LoggerFactory</code> is essentially a wrapper around an
52 * {@link ILoggerFactory} instance bound with <code>LoggerFactory</code> at
53 * compile time.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +020054 * <p/>
55 * <p/>
Ceki Gulcu88c4c452009-12-03 19:16:42 +010056 * Please note that all methods in <code>LoggerFactory</code> are static.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +020057 *
Ceki Gulcu26b01112014-12-09 22:16:05 +010058 *
Alexander Dorokhine75527962014-12-12 15:14:21 -080059 * @author Alexander Dorokhine
Ceki Gulcu88c4c452009-12-03 19:16:42 +010060 * @author Robert Elliot
Ceki Gulcu26b01112014-12-09 22:16:05 +010061 * @author Ceki G&uuml;lc&uuml;
62 *
Ceki Gulcu88c4c452009-12-03 19:16:42 +010063 */
64public final class LoggerFactory {
65
Ceki Gulcu9ac7d3a2010-04-21 23:06:22 +020066 static final String CODES_PREFIX = "http://www.slf4j.org/codes.html";
Ceki Gulcu88c4c452009-12-03 19:16:42 +010067
Ceki Gulcue5eb0b02012-06-11 16:16:40 +020068 static final String NO_STATICLOGGERBINDER_URL = CODES_PREFIX + "#StaticLoggerBinder";
69 static final String MULTIPLE_BINDINGS_URL = CODES_PREFIX + "#multiple_bindings";
70 static final String NULL_LF_URL = CODES_PREFIX + "#null_LF";
71 static final String VERSION_MISMATCH = CODES_PREFIX + "#version_mismatch";
72 static final String SUBSTITUTE_LOGGER_URL = CODES_PREFIX + "#substituteLogger";
Ceki Gulcu4ad29d12014-12-14 00:01:24 +010073 static final String LOGGER_NAME_MISMATCH_URL = CODES_PREFIX + "#loggerNameMismatch";
Ceki Gulcue5eb0b02012-06-11 16:16:40 +020074
75 static final String UNSUCCESSFUL_INIT_URL = CODES_PREFIX + "#unsuccessfulInit";
Ceki Gulcu88c4c452009-12-03 19:16:42 +010076 static final String UNSUCCESSFUL_INIT_MSG = "org.slf4j.LoggerFactory could not be successfully initialized. See also "
Ceki Gulcud9f79d32014-12-13 19:49:05 +010077 + UNSUCCESSFUL_INIT_URL;
Ceki Gulcu88c4c452009-12-03 19:16:42 +010078
79 static final int UNINITIALIZED = 0;
Ceki Gulcue5eb0b02012-06-11 16:16:40 +020080 static final int ONGOING_INITIALIZATION = 1;
81 static final int FAILED_INITIALIZATION = 2;
82 static final int SUCCESSFUL_INITIALIZATION = 3;
83 static final int NOP_FALLBACK_INITIALIZATION = 4;
Ceki Gulcu88c4c452009-12-03 19:16:42 +010084
85 static int INITIALIZATION_STATE = UNINITIALIZED;
Ceki Gulcu88c4c452009-12-03 19:16:42 +010086 static SubstituteLoggerFactory TEMP_FACTORY = new SubstituteLoggerFactory();
Ceki Gulcud1d27b82010-04-06 13:57:15 +020087 static NOPLoggerFactory NOP_FALLBACK_FACTORY = new NOPLoggerFactory();
Ceki Gulcu88c4c452009-12-03 19:16:42 +010088
Alexander Dorokhine75527962014-12-12 15:14:21 -080089 // Support for detecting mismatched logger names.
Ceki Gulcuf0816802014-12-14 01:00:14 +010090 static final String DETECT_LOGGER_NAME_MISMATCH_PROPERTY = "slf4j.detectLoggerNameMismatch";
Ceki Gulcu1ad01912014-12-13 23:53:52 +010091 static boolean DETECT_LOGGER_NAME_MISMATCH = Boolean.getBoolean(DETECT_LOGGER_NAME_MISMATCH_PROPERTY);
Alexander Dorokhine97f96c52014-12-06 14:33:22 -080092
Ceki Gulcu88c4c452009-12-03 19:16:42 +010093 /**
94 * It is LoggerFactory's responsibility to track version changes and manage
95 * the compatibility list.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +020096 * <p/>
97 * <p/>
Ceki Gulcu581b20f2010-04-05 00:11:16 +020098 * It is assumed that all versions in the 1.6 are mutually compatible.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +020099 */
Ceki Gulcud9f79d32014-12-13 19:49:05 +0100100 static private final String[] API_COMPATIBILITY_LIST = new String[] { "1.6", "1.7" };
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100101
102 // private constructor prevents instantiation
103 private LoggerFactory() {
104 }
105
106 /**
107 * Force LoggerFactory to consider itself uninitialized.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200108 * <p/>
109 * <p/>
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100110 * This method is intended to be called by classes (in the same package) for
111 * testing purposes. This method is internal. It can be modified, renamed or
112 * removed at any time without notice.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200113 * <p/>
114 * <p/>
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100115 * You are strongly discouraged from calling this method in production code.
116 */
117 static void reset() {
118 INITIALIZATION_STATE = UNINITIALIZED;
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100119 TEMP_FACTORY = new SubstituteLoggerFactory();
120 }
121
122 private final static void performInitialization() {
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200123 bind();
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200124 if (INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION) {
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200125 versionSanityCheck();
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200126 }
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100127 }
128
Ceki Gulcu67f86a62011-08-15 19:37:08 +0200129 private static boolean messageContainsOrgSlf4jImplStaticLoggerBinder(String msg) {
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200130 if (msg == null)
Ceki Gulcu67f86a62011-08-15 19:37:08 +0200131 return false;
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200132 if (msg.indexOf("org/slf4j/impl/StaticLoggerBinder") != -1)
Ceki Gulcu8eb19122011-08-15 19:43:36 +0200133 return true;
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200134 if (msg.indexOf("org.slf4j.impl.StaticLoggerBinder") != -1)
Ceki Gulcu8eb19122011-08-15 19:43:36 +0200135 return true;
136 return false;
Ceki Gulcu67f86a62011-08-15 19:37:08 +0200137 }
138
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100139 private final static void bind() {
140 try {
Otávio Garcia9e3e9a32014-02-17 07:59:11 -0300141 Set<URL> staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200142 reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100143 // the next line does the binding
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200144 StaticLoggerBinder.getSingleton();
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200145 INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
146 reportActualBinding(staticLoggerBinderPathSet);
Chetan Mehrotra4f1bf592014-02-03 21:59:28 +0530147 fixSubstitutedLoggers();
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100148 } catch (NoClassDefFoundError ncde) {
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100149 String msg = ncde.getMessage();
Ceki Gulcu67f86a62011-08-15 19:37:08 +0200150 if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200151 INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
152 Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200153 Util.report("Defaulting to no-operation (NOP) logger implementation");
Ceki Gulcud9f79d32014-12-13 19:49:05 +0100154 Util.report("See " + NO_STATICLOGGERBINDER_URL + " for further details.");
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200155 } else {
156 failedBinding(ncde);
157 throw ncde;
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100158 }
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200159 } catch (java.lang.NoSuchMethodError nsme) {
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200160 String msg = nsme.getMessage();
161 if (msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200162 INITIALIZATION_STATE = FAILED_INITIALIZATION;
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200163 Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
164 Util.report("Your binding is version 1.5.5 or earlier.");
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200165 Util.report("Upgrade your binding to version 1.6.x.");
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200166 }
167 throw nsme;
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100168 } catch (Exception e) {
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200169 failedBinding(e);
170 throw new IllegalStateException("Unexpected initialization failure", e);
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100171 }
172 }
173
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200174 static void failedBinding(Throwable t) {
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200175 INITIALIZATION_STATE = FAILED_INITIALIZATION;
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200176 Util.report("Failed to instantiate SLF4J LoggerFactory", t);
177 }
178
Chetan Mehrotra4f1bf592014-02-03 21:59:28 +0530179 private final static void fixSubstitutedLoggers() {
Ceki Gulcu8f28a832014-02-03 20:05:23 +0100180 List<SubstituteLogger> loggers = TEMP_FACTORY.getLoggers();
Chetan Mehrotra4f1bf592014-02-03 21:59:28 +0530181
Ceki Gulcud9f79d32014-12-13 19:49:05 +0100182 if (loggers.isEmpty()) {
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100183 return;
184 }
Chetan Mehrotra4f1bf592014-02-03 21:59:28 +0530185
186 Util.report("The following set of substitute loggers may have been accessed");
Ceki Gulcu8f28a832014-02-03 20:05:23 +0100187 Util.report("during the initialization phase. Logging calls during this");
188 Util.report("phase were not honored. However, subsequent logging calls to these");
189 Util.report("loggers will work as normally expected.");
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200190 Util.report("See also " + SUBSTITUTE_LOGGER_URL);
Ceki Gulcud9f79d32014-12-13 19:49:05 +0100191 for (SubstituteLogger subLogger : loggers) {
Chetan Mehrotra4f1bf592014-02-03 21:59:28 +0530192 subLogger.setDelegate(getLogger(subLogger.getName()));
193 Util.report(subLogger.getName());
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100194 }
Chetan Mehrotra4f1bf592014-02-03 21:59:28 +0530195
196 TEMP_FACTORY.clear();
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100197 }
198
199 private final static void versionSanityCheck() {
200 try {
201 String requested = StaticLoggerBinder.REQUESTED_API_VERSION;
202
203 boolean match = false;
204 for (int i = 0; i < API_COMPATIBILITY_LIST.length; i++) {
205 if (requested.startsWith(API_COMPATIBILITY_LIST[i])) {
206 match = true;
207 }
208 }
209 if (!match) {
Ceki Gulcud9f79d32014-12-13 19:49:05 +0100210 Util.report("The requested version " + requested + " by your slf4j binding is not compatible with "
211 + Arrays.asList(API_COMPATIBILITY_LIST).toString());
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200212 Util.report("See " + VERSION_MISMATCH + " for further details.");
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100213 }
214 } catch (java.lang.NoSuchFieldError nsfe) {
215 // given our large user base and SLF4J's commitment to backward
216 // compatibility, we cannot cry here. Only for implementations
217 // which willingly declare a REQUESTED_API_VERSION field do we
218 // emit compatibility warnings.
219 } catch (Throwable e) {
220 // we should never reach here
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200221 Util.report("Unexpected problem occured during version sanity check", e);
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100222 }
223 }
224
Ceki Gulcu67f86a62011-08-15 19:37:08 +0200225 // We need to use the name of the StaticLoggerBinder class, but we can't reference
226 // the class itself.
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100227 private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
228
Otávio Garcia9e3e9a32014-02-17 07:59:11 -0300229 private static Set<URL> findPossibleStaticLoggerBinderPathSet() {
Ceki Gulcud9f79d32014-12-13 19:49:05 +0100230 // use Set instead of list in order to deal with bug #138
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200231 // LinkedHashSet appropriate here because it preserves insertion order during iteration
Otávio Garcia9e3e9a32014-02-17 07:59:11 -0300232 Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100233 try {
Ceki Gulcud9f79d32014-12-13 19:49:05 +0100234 ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
Otávio Garcia9e3e9a32014-02-17 07:59:11 -0300235 Enumeration<URL> paths;
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100236 if (loggerFactoryClassLoader == null) {
Ceki Gulcu40e51c62010-04-04 22:20:26 +0200237 paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
238 } else {
Ceki Gulcud9f79d32014-12-13 19:49:05 +0100239 paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100240 }
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100241 while (paths.hasMoreElements()) {
242 URL path = (URL) paths.nextElement();
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200243 staticLoggerBinderPathSet.add(path);
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100244 }
245 } catch (IOException ioe) {
Ceki Gulcud1d27b82010-04-06 13:57:15 +0200246 Util.report("Error getting resources from path", ioe);
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100247 }
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200248 return staticLoggerBinderPathSet;
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100249 }
250
Otávio Garcia9e3e9a32014-02-17 07:59:11 -0300251 private static boolean isAmbiguousStaticLoggerBinderPathSet(Set<URL> staticLoggerBinderPathSet) {
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200252 return staticLoggerBinderPathSet.size() > 1;
253 }
254
255 /**
256 * Prints a warning message on the console if multiple bindings were found on the class path.
257 * No reporting is done otherwise.
258 *
259 */
Otávio Garcia9e3e9a32014-02-17 07:59:11 -0300260 private static void reportMultipleBindingAmbiguity(Set<URL> staticLoggerBinderPathSet) {
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200261 if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) {
262 Util.report("Class path contains multiple SLF4J bindings.");
Otávio Garcia9e3e9a32014-02-17 07:59:11 -0300263 Iterator<URL> iterator = staticLoggerBinderPathSet.iterator();
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200264 while (iterator.hasNext()) {
265 URL path = (URL) iterator.next();
266 Util.report("Found binding in [" + path + "]");
267 }
268 Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");
269 }
270 }
271
Otávio Garcia9e3e9a32014-02-17 07:59:11 -0300272 private static void reportActualBinding(Set<URL> staticLoggerBinderPathSet) {
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200273 if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) {
Ceki Gulcud9f79d32014-12-13 19:49:05 +0100274 Util.report("Actual binding is of type [" + StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr() + "]");
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200275 }
276 }
277
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100278 /**
279 * Return a logger named according to the name parameter using the statically
280 * bound {@link ILoggerFactory} instance.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200281 *
282 * @param name The name of the logger.
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100283 * @return logger
284 */
Hendy Irawan2f82a782013-09-11 15:28:23 +0700285 @Nonnull
286 public static Logger getLogger(@Nonnull String name) {
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100287 ILoggerFactory iLoggerFactory = getILoggerFactory();
288 return iLoggerFactory.getLogger(name);
289 }
290
291 /**
292 * Return a logger named corresponding to the class passed as parameter, using
293 * the statically bound {@link ILoggerFactory} instance.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200294 *
295 * @param clazz the returned logger will be named after clazz
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100296 * @return logger
297 */
Hendy Irawan2f82a782013-09-11 15:28:23 +0700298 @Nonnull
Alexander Dorokhine97f96c52014-12-06 14:33:22 -0800299 public static Logger getLogger(@Nonnull Class<?> clazz) {
300 Logger logger = getLogger(clazz.getName());
Alexander Dorokhine75527962014-12-12 15:14:21 -0800301 if (DETECT_LOGGER_NAME_MISMATCH) {
Ceki Gulcuc0f58352014-12-08 23:24:24 +0100302 Class<?> autoComputedCallingClass = Util.getCallingClass();
303 if (nonMatchingClasses(clazz, autoComputedCallingClass)) {
Ceki Gulcuf0816802014-12-14 01:00:14 +0100304 Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".",
Ceki Gulcu1ad01912014-12-13 23:53:52 +0100305 logger.getName(), autoComputedCallingClass.getName()));
Ceki Gulcu4ad29d12014-12-14 00:01:24 +0100306 Util.report("See " + LOGGER_NAME_MISMATCH_URL + " for an explanation");
Alexander Dorokhine97f96c52014-12-06 14:33:22 -0800307 }
308 }
309 return logger;
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100310 }
311
Ceki Gulcuc0f58352014-12-08 23:24:24 +0100312 private static boolean nonMatchingClasses(Class<?> clazz, Class<?> autoComputedCallingClass) {
313 return !autoComputedCallingClass.isAssignableFrom(clazz);
314 }
315
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100316 /**
317 * Return the {@link ILoggerFactory} instance in use.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200318 * <p/>
319 * <p/>
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100320 * ILoggerFactory instance is bound with this class at compile time.
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200321 *
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100322 * @return the ILoggerFactory instance in use
323 */
Hendy Irawan2f82a782013-09-11 15:28:23 +0700324 @Nonnull
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100325 public static ILoggerFactory getILoggerFactory() {
326 if (INITIALIZATION_STATE == UNINITIALIZED) {
Ceki Gulcue5eb0b02012-06-11 16:16:40 +0200327 INITIALIZATION_STATE = ONGOING_INITIALIZATION;
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100328 performInitialization();
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100329 }
330 switch (INITIALIZATION_STATE) {
Ceki Gulcu1ad01912014-12-13 23:53:52 +0100331 case SUCCESSFUL_INITIALIZATION:
332 return StaticLoggerBinder.getSingleton().getLoggerFactory();
333 case NOP_FALLBACK_INITIALIZATION:
334 return NOP_FALLBACK_FACTORY;
335 case FAILED_INITIALIZATION:
336 throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
337 case ONGOING_INITIALIZATION:
338 // support re-entrant behavior.
339 // See also http://bugzilla.slf4j.org/show_bug.cgi?id=106
340 return TEMP_FACTORY;
Ceki Gulcu88c4c452009-12-03 19:16:42 +0100341 }
342 throw new IllegalStateException("Unreachable code");
343 }
344}