1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.slf4j;
26
27 import java.io.IOException;
28 import java.net.URL;
29 import java.util.*;
30
31 import org.slf4j.helpers.NOPLoggerFactory;
32 import org.slf4j.helpers.SubstituteLoggerFactory;
33 import org.slf4j.helpers.Util;
34 import org.slf4j.impl.StaticLoggerBinder;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public final class LoggerFactory {
54
55 static final String CODES_PREFIX = "http://www.slf4j.org/codes.html";
56
57 static final String NO_STATICLOGGERBINDER_URL = CODES_PREFIX+"#StaticLoggerBinder";
58 static final String MULTIPLE_BINDINGS_URL = CODES_PREFIX+"#multiple_bindings";
59 static final String NULL_LF_URL = CODES_PREFIX+"#null_LF";
60 static final String VERSION_MISMATCH = CODES_PREFIX+"#version_mismatch";
61 static final String SUBSTITUTE_LOGGER_URL = CODES_PREFIX+"#substituteLogger";
62
63 static final String UNSUCCESSFUL_INIT_URL = CODES_PREFIX+"#unsuccessfulInit";
64 static final String UNSUCCESSFUL_INIT_MSG = "org.slf4j.LoggerFactory could not be successfully initialized. See also "
65 + UNSUCCESSFUL_INIT_URL;
66
67 static final int UNINITIALIZED = 0;
68 static final int ONGOING_INITILIZATION = 1;
69 static final int FAILED_INITILIZATION = 2;
70 static final int SUCCESSFUL_INITILIZATION = 3;
71 static final int NOP_FALLBACK_INITILIZATION = 4;
72
73 static int INITIALIZATION_STATE = UNINITIALIZED;
74 static SubstituteLoggerFactory TEMP_FACTORY = new SubstituteLoggerFactory();
75 static NOPLoggerFactory NOP_FALLBACK_FACTORY = new NOPLoggerFactory();
76
77
78
79
80
81
82
83
84 static private final String[] API_COMPATIBILITY_LIST = new String[] { "1.6" };
85
86
87 private LoggerFactory() {
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101 static void reset() {
102 INITIALIZATION_STATE = UNINITIALIZED;
103 TEMP_FACTORY = new SubstituteLoggerFactory();
104 }
105
106 private final static void performInitialization() {
107 singleImplementationSanityCheck();
108 bind();
109 if (INITIALIZATION_STATE == SUCCESSFUL_INITILIZATION) {
110 versionSanityCheck();
111
112 }
113 }
114
115 private static boolean messageContainsOrgSlf4jImplStaticLoggerBinder(String msg) {
116 if(msg == null)
117 return false;
118 if(msg.indexOf("org/slf4j/impl/StaticLoggerBinder") != -1)
119 return true;
120 if(msg.indexOf("org.slf4j.impl.StaticLoggerBinder") != -1)
121 return true;
122 return false;
123 }
124
125 private final static void bind() {
126 try {
127
128 StaticLoggerBinder.getSingleton();
129 INITIALIZATION_STATE = SUCCESSFUL_INITILIZATION;
130 emitSubstituteLoggerWarning();
131 } catch (NoClassDefFoundError ncde) {
132 String msg = ncde.getMessage();
133 if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
134 INITIALIZATION_STATE = NOP_FALLBACK_INITILIZATION;
135 Util
136 .report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
137 Util.report("Defaulting to no-operation (NOP) logger implementation");
138 Util.report("See " + NO_STATICLOGGERBINDER_URL
139 + " for further details.");
140 } else {
141 failedBinding(ncde);
142 throw ncde;
143 }
144 } catch(java.lang.NoSuchMethodError nsme) {
145 String msg = nsme.getMessage();
146 if (msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
147 INITIALIZATION_STATE = FAILED_INITILIZATION;
148 Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
149 Util.report("Your binding is version 1.5.5 or earlier.");
150 Util.report("Upgrade your binding to version 1.6.x. or 2.0.x");
151 }
152 throw nsme;
153 } catch (Exception e) {
154 failedBinding(e);
155 throw new IllegalStateException("Unexpected initialization failure", e);
156 }
157 }
158
159 static void failedBinding(Throwable t) {
160 INITIALIZATION_STATE = FAILED_INITILIZATION;
161 Util.report("Failed to instantiate SLF4J LoggerFactory", t);
162 }
163
164 private final static void emitSubstituteLoggerWarning() {
165 List loggerNameList = TEMP_FACTORY.getLoggerNameList();
166 if (loggerNameList.size() == 0) {
167 return;
168 }
169 Util
170 .report("The following loggers will not work because they were created");
171 Util
172 .report("during the default configuration phase of the underlying logging system.");
173 Util.report("See also " + SUBSTITUTE_LOGGER_URL);
174 for (int i = 0; i < loggerNameList.size(); i++) {
175 String loggerName = (String) loggerNameList.get(i);
176 Util.report(loggerName);
177 }
178 }
179
180 private final static void versionSanityCheck() {
181 try {
182 String requested = StaticLoggerBinder.REQUESTED_API_VERSION;
183
184 boolean match = false;
185 for (int i = 0; i < API_COMPATIBILITY_LIST.length; i++) {
186 if (requested.startsWith(API_COMPATIBILITY_LIST[i])) {
187 match = true;
188 }
189 }
190 if (!match) {
191 Util.report("The requested version " + requested
192 + " by your slf4j binding is not compatible with "
193 + Arrays.asList(API_COMPATIBILITY_LIST).toString());
194 Util.report("See " + VERSION_MISMATCH + " for further details.");
195 }
196 } catch (java.lang.NoSuchFieldError nsfe) {
197
198
199
200
201 } catch (Throwable e) {
202
203 Util.report("Unexpected problem occured during version sanity check", e);
204 }
205 }
206
207
208
209 private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
210
211 private static void singleImplementationSanityCheck() {
212 try {
213 ClassLoader loggerFactoryClassLoader = LoggerFactory.class
214 .getClassLoader();
215 Enumeration paths;
216 if (loggerFactoryClassLoader == null) {
217 paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
218 } else {
219 paths = loggerFactoryClassLoader
220 .getResources(STATIC_LOGGER_BINDER_PATH);
221 }
222
223
224 Set implementationSet = new LinkedHashSet();
225 while (paths.hasMoreElements()) {
226 URL path = (URL) paths.nextElement();
227 implementationSet.add(path);
228 }
229 if (implementationSet.size() > 1) {
230 Util.report("Class path contains multiple SLF4J bindings.");
231 Iterator iterator = implementationSet.iterator();
232 while(iterator.hasNext()) {
233 URL path = (URL) iterator.next();
234 Util.report("Found binding in [" + path + "]");
235 }
236 Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");
237 }
238 } catch (IOException ioe) {
239 Util.report("Error getting resources from path", ioe);
240 }
241 }
242
243
244
245
246
247
248
249
250
251 public static Logger getLogger(String name) {
252 ILoggerFactory iLoggerFactory = getILoggerFactory();
253 return iLoggerFactory.getLogger(name);
254 }
255
256
257
258
259
260
261
262
263
264 public static Logger getLogger(Class clazz) {
265 return getLogger(clazz.getName());
266 }
267
268
269
270
271
272
273
274
275
276 public static ILoggerFactory getILoggerFactory() {
277 if (INITIALIZATION_STATE == UNINITIALIZED) {
278 INITIALIZATION_STATE = ONGOING_INITILIZATION;
279 performInitialization();
280
281 }
282 switch (INITIALIZATION_STATE) {
283 case SUCCESSFUL_INITILIZATION:
284 return StaticLoggerBinder.getSingleton().getLoggerFactory();
285 case NOP_FALLBACK_INITILIZATION:
286 return NOP_FALLBACK_FACTORY;
287 case FAILED_INITILIZATION:
288 throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
289 case ONGOING_INITILIZATION:
290
291
292 return TEMP_FACTORY;
293 }
294 throw new IllegalStateException("Unreachable code");
295 }
296 }