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