1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.logging.impl;
19
20
21 import java.lang.reflect.Constructor;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.net.URL;
25 import java.security.AccessController;
26 import java.security.PrivilegedAction;
27 import java.util.Enumeration;
28 import java.util.Hashtable;
29 import java.util.Vector;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogConfigurationException;
33 import org.apache.commons.logging.LogFactory;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class LogFactoryImpl extends LogFactory {
72
73
74
75 private static final String LOGGING_IMPL_LOG4J_LOGGER = "org.apache.commons.logging.impl.Log4JLogger";
76
77 private static final String LOGGING_IMPL_JDK14_LOGGER = "org.apache.commons.logging.impl.Jdk14Logger";
78
79 private static final String LOGGING_IMPL_LUMBERJACK_LOGGER = "org.apache.commons.logging.impl.Jdk13LumberjackLogger";
80
81 private static final String LOGGING_IMPL_SIMPLE_LOGGER = "org.apache.commons.logging.impl.SimpleLog";
82
83 private static final String PKG_IMPL="org.apache.commons.logging.impl.";
84 private static final int PKG_LEN = PKG_IMPL.length();
85
86
87
88
89
90
91
92
93 public LogFactoryImpl() {
94 super();
95 initDiagnostics();
96 if (isDiagnosticsEnabled()) {
97 logDiagnostic("Instance created.");
98 }
99 }
100
101
102
103
104
105
106
107
108
109 public static final String LOG_PROPERTY =
110 "org.apache.commons.logging.Log";
111
112
113
114
115
116
117 protected static final String LOG_PROPERTY_OLD =
118 "org.apache.commons.logging.log";
119
120
121
122
123
124
125
126
127
128
129
130
131
132 public static final String ALLOW_FLAWED_CONTEXT_PROPERTY =
133 "org.apache.commons.logging.Log.allowFlawedContext";
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 public static final String ALLOW_FLAWED_DISCOVERY_PROPERTY =
149 "org.apache.commons.logging.Log.allowFlawedDiscovery";
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 public static final String ALLOW_FLAWED_HIERARCHY_PROPERTY =
165 "org.apache.commons.logging.Log.allowFlawedHierarchy";
166
167
168
169
170
171
172
173
174
175
176 private static final String[] classesToDiscover = {
177 LOGGING_IMPL_LOG4J_LOGGER,
178 "org.apache.commons.logging.impl.Jdk14Logger",
179 "org.apache.commons.logging.impl.Jdk13LumberjackLogger",
180 "org.apache.commons.logging.impl.SimpleLog"
181 };
182
183
184
185
186
187
188
189
190 private boolean useTCCL = true;
191
192
193
194
195 private String diagnosticPrefix;
196
197
198
199
200
201 protected Hashtable attributes = new Hashtable();
202
203
204
205
206
207
208 protected Hashtable instances = new Hashtable();
209
210
211
212
213
214 private String logClassName;
215
216
217
218
219
220
221
222
223
224 protected Constructor logConstructor = null;
225
226
227
228
229
230 protected Class logConstructorSignature[] =
231 { java.lang.String.class };
232
233
234
235
236
237
238 protected Method logMethod = null;
239
240
241
242
243
244 protected Class logMethodSignature[] =
245 { LogFactory.class };
246
247
248
249
250 private boolean allowFlawedContext;
251
252
253
254
255 private boolean allowFlawedDiscovery;
256
257
258
259
260 private boolean allowFlawedHierarchy;
261
262
263
264
265
266
267
268
269
270
271 public Object getAttribute(String name) {
272
273 return (attributes.get(name));
274
275 }
276
277
278
279
280
281
282
283 public String[] getAttributeNames() {
284
285 Vector names = new Vector();
286 Enumeration keys = attributes.keys();
287 while (keys.hasMoreElements()) {
288 names.addElement((String) keys.nextElement());
289 }
290 String results[] = new String[names.size()];
291 for (int i = 0; i < results.length; i++) {
292 results[i] = (String) names.elementAt(i);
293 }
294 return (results);
295
296 }
297
298
299
300
301
302
303
304
305
306
307
308 public Log getInstance(Class clazz) throws LogConfigurationException {
309
310 return (getInstance(clazz.getName()));
311
312 }
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332 public Log getInstance(String name) throws LogConfigurationException {
333
334 Log instance = (Log) instances.get(name);
335 if (instance == null) {
336 instance = newInstance(name);
337 instances.put(name, instance);
338 }
339 return (instance);
340
341 }
342
343
344
345
346
347
348
349
350
351
352 public void release() {
353
354 logDiagnostic("Releasing all known loggers");
355 instances.clear();
356 }
357
358
359
360
361
362
363
364
365 public void removeAttribute(String name) {
366
367 attributes.remove(name);
368
369 }
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396 public void setAttribute(String name, Object value) {
397
398 if (logConstructor != null) {
399 logDiagnostic("setAttribute: call too late; configuration already performed.");
400 }
401
402 if (value == null) {
403 attributes.remove(name);
404 } else {
405 attributes.put(name, value);
406 }
407
408 if (name.equals(TCCL_KEY)) {
409 useTCCL = Boolean.valueOf(value.toString()).booleanValue();
410 }
411
412 }
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427 protected static ClassLoader getContextClassLoader() throws LogConfigurationException {
428 return LogFactory.getContextClassLoader();
429 }
430
431
432
433
434
435
436 protected static boolean isDiagnosticsEnabled() {
437 return LogFactory.isDiagnosticsEnabled();
438 }
439
440
441
442
443
444
445
446 protected static ClassLoader getClassLoader(Class clazz) {
447 return LogFactory.getClassLoader(clazz);
448 }
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465 private void initDiagnostics() {
466
467
468
469
470
471
472
473
474
475 Class clazz = this.getClass();
476 ClassLoader classLoader = getClassLoader(clazz);
477 String classLoaderName;
478 try {
479 if (classLoader == null) {
480 classLoaderName = "BOOTLOADER";
481 } else {
482 classLoaderName = objectId(classLoader);
483 }
484 } catch(SecurityException e) {
485 classLoaderName = "UNKNOWN";
486 }
487 diagnosticPrefix = "[LogFactoryImpl@" + System.identityHashCode(this) + " from " + classLoaderName + "] ";
488 }
489
490
491
492
493
494
495
496
497
498 protected void logDiagnostic(String msg) {
499 if (isDiagnosticsEnabled()) {
500 logRawDiagnostic(diagnosticPrefix + msg);
501 }
502 }
503
504
505
506
507
508
509
510
511 protected String getLogClassName() {
512
513 if (logClassName == null) {
514 discoverLogImplementation(getClass().getName());
515 }
516
517 return logClassName;
518 }
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536 protected Constructor getLogConstructor()
537 throws LogConfigurationException {
538
539
540 if (logConstructor == null) {
541 discoverLogImplementation(getClass().getName());
542 }
543
544 return logConstructor;
545 }
546
547
548
549
550
551
552
553
554 protected boolean isJdk13LumberjackAvailable() {
555 return isLogLibraryAvailable(
556 "Jdk13Lumberjack",
557 "org.apache.commons.logging.impl.Jdk13LumberjackLogger");
558 }
559
560
561
562
563
564
565
566
567
568
569
570 protected boolean isJdk14Available() {
571 return isLogLibraryAvailable(
572 "Jdk14",
573 "org.apache.commons.logging.impl.Jdk14Logger");
574 }
575
576
577
578
579
580
581
582
583 protected boolean isLog4JAvailable() {
584 return isLogLibraryAvailable(
585 "Log4J",
586 LOGGING_IMPL_LOG4J_LOGGER);
587 }
588
589
590
591
592
593
594
595
596
597
598
599 protected Log newInstance(String name) throws LogConfigurationException {
600
601 Log instance = null;
602 try {
603 if (logConstructor == null) {
604 instance = discoverLogImplementation(name);
605 }
606 else {
607 Object params[] = { name };
608 instance = (Log) logConstructor.newInstance(params);
609 }
610
611 if (logMethod != null) {
612 Object params[] = { this };
613 logMethod.invoke(instance, params);
614 }
615
616 return (instance);
617
618 } catch (LogConfigurationException lce) {
619
620
621
622
623 throw (LogConfigurationException) lce;
624
625 } catch (InvocationTargetException e) {
626
627
628 Throwable c = e.getTargetException();
629 if (c != null) {
630 throw new LogConfigurationException(c);
631 } else {
632 throw new LogConfigurationException(e);
633 }
634 } catch (Throwable t) {
635
636
637 throw new LogConfigurationException(t);
638 }
639 }
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662 private static ClassLoader getContextClassLoaderInternal()
663 throws LogConfigurationException {
664 return (ClassLoader)AccessController.doPrivileged(
665 new PrivilegedAction() {
666 public Object run() {
667 return LogFactory.directGetContextClassLoader();
668 }
669 });
670 }
671
672
673
674
675
676
677
678
679
680
681 private static String getSystemProperty(final String key, final String def)
682 throws SecurityException {
683 return (String) AccessController.doPrivileged(
684 new PrivilegedAction() {
685 public Object run() {
686 return System.getProperty(key, def);
687 }
688 });
689 }
690
691
692
693
694
695
696
697
698 private ClassLoader getParentClassLoader(final ClassLoader cl) {
699 try {
700 return (ClassLoader)AccessController.doPrivileged(
701 new PrivilegedAction() {
702 public Object run() {
703 return cl.getParent();
704 }
705 });
706 } catch(SecurityException ex) {
707 logDiagnostic("[SECURITY] Unable to obtain parent classloader");
708 return null;
709 }
710
711 }
712
713
714
715
716
717
718 private boolean isLogLibraryAvailable(String name, String classname) {
719 if (isDiagnosticsEnabled()) {
720 logDiagnostic("Checking for '" + name + "'.");
721 }
722 try {
723 Log log = createLogFromClass(
724 classname,
725 this.getClass().getName(),
726 false);
727
728 if (log == null) {
729 if (isDiagnosticsEnabled()) {
730 logDiagnostic("Did not find '" + name + "'.");
731 }
732 return false;
733 } else {
734 if (isDiagnosticsEnabled()) {
735 logDiagnostic("Found '" + name + "'.");
736 }
737 return true;
738 }
739 } catch(LogConfigurationException e) {
740 if (isDiagnosticsEnabled()) {
741 logDiagnostic("Logging system '" + name + "' is available but not useable.");
742 }
743 return false;
744 }
745 }
746
747
748
749
750
751
752
753
754
755
756
757
758 private String getConfigurationValue(String property) {
759 if (isDiagnosticsEnabled()) {
760 logDiagnostic("[ENV] Trying to get configuration for item " + property);
761 }
762
763 Object valueObj = getAttribute(property);
764 if (valueObj != null) {
765 if (isDiagnosticsEnabled()) {
766 logDiagnostic("[ENV] Found LogFactory attribute [" + valueObj + "] for " + property);
767 }
768 return valueObj.toString();
769 }
770
771 if (isDiagnosticsEnabled()) {
772 logDiagnostic("[ENV] No LogFactory attribute found for " + property);
773 }
774
775 try {
776
777
778
779
780 String value = getSystemProperty(property, null);
781 if (value != null) {
782 if (isDiagnosticsEnabled()) {
783 logDiagnostic("[ENV] Found system property [" + value + "] for " + property);
784 }
785 return value;
786 }
787
788 if (isDiagnosticsEnabled()) {
789 logDiagnostic("[ENV] No system property found for property " + property);
790 }
791 } catch (SecurityException e) {
792 if (isDiagnosticsEnabled()) {
793 logDiagnostic("[ENV] Security prevented reading system property " + property);
794 }
795 }
796
797 if (isDiagnosticsEnabled()) {
798 logDiagnostic("[ENV] No configuration defined for item " + property);
799 }
800
801 return null;
802 }
803
804
805
806
807
808 private boolean getBooleanConfiguration(String key, boolean dflt) {
809 String val = getConfigurationValue(key);
810 if (val == null)
811 return dflt;
812 return Boolean.valueOf(val).booleanValue();
813 }
814
815
816
817
818
819
820
821
822 private void initConfiguration() {
823 allowFlawedContext = getBooleanConfiguration(ALLOW_FLAWED_CONTEXT_PROPERTY, true);
824 allowFlawedDiscovery = getBooleanConfiguration(ALLOW_FLAWED_DISCOVERY_PROPERTY, true);
825 allowFlawedHierarchy = getBooleanConfiguration(ALLOW_FLAWED_HIERARCHY_PROPERTY, true);
826 }
827
828
829
830
831
832
833
834
835
836
837
838 private Log discoverLogImplementation(String logCategory)
839 throws LogConfigurationException
840 {
841 if (isDiagnosticsEnabled()) {
842 logDiagnostic("Discovering a Log implementation...");
843 }
844
845 initConfiguration();
846
847 Log result = null;
848
849
850 String specifiedLogClassName = findUserSpecifiedLogClassName();
851
852 if (specifiedLogClassName != null) {
853 if (isDiagnosticsEnabled()) {
854 logDiagnostic("Attempting to load user-specified log class '" +
855 specifiedLogClassName + "'...");
856 }
857
858 result = createLogFromClass(specifiedLogClassName,
859 logCategory,
860 true);
861 if (result == null) {
862 StringBuffer messageBuffer = new StringBuffer("User-specified log class '");
863 messageBuffer.append(specifiedLogClassName);
864 messageBuffer.append("' cannot be found or is not useable.");
865
866
867
868 if (specifiedLogClassName != null) {
869 informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LOG4J_LOGGER);
870 informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_JDK14_LOGGER);
871 informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LUMBERJACK_LOGGER);
872 informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_SIMPLE_LOGGER);
873 }
874 throw new LogConfigurationException(messageBuffer.toString());
875 }
876
877 return result;
878 }
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908 if (isDiagnosticsEnabled()) {
909 logDiagnostic(
910 "No user-specified Log implementation; performing discovery" +
911 " using the standard supported logging implementations...");
912 }
913 for(int i=0; (i<classesToDiscover.length) && (result == null); ++i) {
914 result = createLogFromClass(classesToDiscover[i], logCategory, true);
915 }
916
917 if (result == null) {
918 throw new LogConfigurationException
919 ("No suitable Log implementation");
920 }
921
922 return result;
923 }
924
925
926
927
928
929
930
931
932
933 private void informUponSimilarName(final StringBuffer messageBuffer, final String name,
934 final String candidate) {
935 if (name.equals(candidate)) {
936
937
938 return;
939 }
940
941
942
943
944 if (name.regionMatches(true, 0, candidate, 0, PKG_LEN + 5)) {
945 messageBuffer.append(" Did you mean '");
946 messageBuffer.append(candidate);
947 messageBuffer.append("'?");
948 }
949 }
950
951
952
953
954
955
956
957
958
959 private String findUserSpecifiedLogClassName()
960 {
961 if (isDiagnosticsEnabled()) {
962 logDiagnostic("Trying to get log class from attribute '" + LOG_PROPERTY + "'");
963 }
964 String specifiedClass = (String) getAttribute(LOG_PROPERTY);
965
966 if (specifiedClass == null) {
967 if (isDiagnosticsEnabled()) {
968 logDiagnostic("Trying to get log class from attribute '" +
969 LOG_PROPERTY_OLD + "'");
970 }
971 specifiedClass = (String) getAttribute(LOG_PROPERTY_OLD);
972 }
973
974 if (specifiedClass == null) {
975 if (isDiagnosticsEnabled()) {
976 logDiagnostic("Trying to get log class from system property '" +
977 LOG_PROPERTY + "'");
978 }
979 try {
980 specifiedClass = getSystemProperty(LOG_PROPERTY, null);
981 } catch (SecurityException e) {
982 if (isDiagnosticsEnabled()) {
983 logDiagnostic("No access allowed to system property '" +
984 LOG_PROPERTY + "' - " + e.getMessage());
985 }
986 }
987 }
988
989 if (specifiedClass == null) {
990 if (isDiagnosticsEnabled()) {
991 logDiagnostic("Trying to get log class from system property '" +
992 LOG_PROPERTY_OLD + "'");
993 }
994 try {
995 specifiedClass = getSystemProperty(LOG_PROPERTY_OLD, null);
996 } catch (SecurityException e) {
997 if (isDiagnosticsEnabled()) {
998 logDiagnostic("No access allowed to system property '" +
999 LOG_PROPERTY_OLD + "' - " + e.getMessage());
1000 }
1001 }
1002 }
1003
1004
1005
1006
1007 if (specifiedClass != null) {
1008 specifiedClass = specifiedClass.trim();
1009 }
1010
1011 return specifiedClass;
1012 }
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034 private Log createLogFromClass(String logAdapterClassName,
1035 String logCategory,
1036 boolean affectState)
1037 throws LogConfigurationException {
1038
1039 if (isDiagnosticsEnabled()) {
1040 logDiagnostic("Attempting to instantiate '" + logAdapterClassName + "'");
1041 }
1042
1043 Object[] params = { logCategory };
1044 Log logAdapter = null;
1045 Constructor constructor = null;
1046
1047 Class logAdapterClass = null;
1048 ClassLoader currentCL = getBaseClassLoader();
1049
1050 for(;;) {
1051
1052
1053 logDiagnostic(
1054 "Trying to load '"
1055 + logAdapterClassName
1056 + "' from classloader "
1057 + objectId(currentCL));
1058 try {
1059 if (isDiagnosticsEnabled()) {
1060
1061
1062
1063
1064 URL url;
1065 String resourceName = logAdapterClassName.replace('.', '/') + ".class";
1066 if (currentCL != null) {
1067 url = currentCL.getResource(resourceName );
1068 } else {
1069 url = ClassLoader.getSystemResource(resourceName + ".class");
1070 }
1071
1072 if (url == null) {
1073 logDiagnostic("Class '" + logAdapterClassName + "' [" + resourceName + "] cannot be found.");
1074 } else {
1075 logDiagnostic("Class '" + logAdapterClassName + "' was found at '" + url + "'");
1076 }
1077 }
1078
1079 Class c = null;
1080 try {
1081 c = Class.forName(logAdapterClassName, true, currentCL);
1082 } catch (ClassNotFoundException originalClassNotFoundException) {
1083
1084
1085
1086 String msg = "" + originalClassNotFoundException.getMessage();
1087 logDiagnostic(
1088 "The log adapter '"
1089 + logAdapterClassName
1090 + "' is not available via classloader "
1091 + objectId(currentCL)
1092 + ": "
1093 + msg.trim());
1094 try {
1095
1096
1097
1098
1099
1100
1101
1102 c = Class.forName(logAdapterClassName);
1103 } catch (ClassNotFoundException secondaryClassNotFoundException) {
1104
1105 msg = "" + secondaryClassNotFoundException.getMessage();
1106 logDiagnostic(
1107 "The log adapter '"
1108 + logAdapterClassName
1109 + "' is not available via the LogFactoryImpl class classloader: "
1110 + msg.trim());
1111 break;
1112 }
1113 }
1114
1115 constructor = c.getConstructor(logConstructorSignature);
1116 Object o = constructor.newInstance(params);
1117
1118
1119
1120
1121
1122 if (o instanceof Log) {
1123 logAdapterClass = c;
1124 logAdapter = (Log) o;
1125 break;
1126 }
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138 handleFlawedHierarchy(currentCL, c);
1139 } catch (NoClassDefFoundError e) {
1140
1141
1142
1143
1144
1145 String msg = "" + e.getMessage();
1146 logDiagnostic(
1147 "The log adapter '"
1148 + logAdapterClassName
1149 + "' is missing dependencies when loaded via classloader "
1150 + objectId(currentCL)
1151 + ": "
1152 + msg.trim());
1153 break;
1154 } catch (ExceptionInInitializerError e) {
1155
1156
1157
1158
1159
1160
1161 String msg = "" + e.getMessage();
1162 logDiagnostic(
1163 "The log adapter '"
1164 + logAdapterClassName
1165 + "' is unable to initialize itself when loaded via classloader "
1166 + objectId(currentCL)
1167 + ": "
1168 + msg.trim());
1169 break;
1170 } catch(LogConfigurationException e) {
1171
1172
1173 throw e;
1174 } catch(Throwable t) {
1175
1176
1177
1178 handleFlawedDiscovery(logAdapterClassName, currentCL, t);
1179 }
1180
1181 if (currentCL == null) {
1182 break;
1183 }
1184
1185
1186
1187 currentCL = getParentClassLoader(currentCL);
1188 }
1189
1190 if ((logAdapter != null) && affectState) {
1191
1192 this.logClassName = logAdapterClassName;
1193 this.logConstructor = constructor;
1194
1195
1196 try {
1197 this.logMethod = logAdapterClass.getMethod("setLogFactory",
1198 logMethodSignature);
1199 logDiagnostic("Found method setLogFactory(LogFactory) in '"
1200 + logAdapterClassName + "'");
1201 } catch (Throwable t) {
1202 this.logMethod = null;
1203 logDiagnostic(
1204 "[INFO] '" + logAdapterClassName
1205 + "' from classloader " + objectId(currentCL)
1206 + " does not declare optional method "
1207 + "setLogFactory(LogFactory)");
1208 }
1209
1210 logDiagnostic(
1211 "Log adapter '" + logAdapterClassName
1212 + "' from classloader " + objectId(logAdapterClass.getClassLoader())
1213 + " has been selected for use.");
1214 }
1215
1216 return logAdapter;
1217 }
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238 private ClassLoader getBaseClassLoader() throws LogConfigurationException {
1239 ClassLoader thisClassLoader = getClassLoader(LogFactoryImpl.class);
1240
1241 if (useTCCL == false) {
1242 return thisClassLoader;
1243 }
1244
1245 ClassLoader contextClassLoader = getContextClassLoaderInternal();
1246
1247 ClassLoader baseClassLoader = getLowestClassLoader(
1248 contextClassLoader, thisClassLoader);
1249
1250 if (baseClassLoader == null) {
1251
1252
1253
1254
1255 if (allowFlawedContext) {
1256 if (isDiagnosticsEnabled()) {
1257 logDiagnostic(
1258 "[WARNING] the context classloader is not part of a"
1259 + " parent-child relationship with the classloader that"
1260 + " loaded LogFactoryImpl.");
1261 }
1262
1263
1264
1265 return contextClassLoader;
1266 }
1267 else {
1268 throw new LogConfigurationException(
1269 "Bad classloader hierarchy; LogFactoryImpl was loaded via"
1270 + " a classloader that is not related to the current context"
1271 + " classloader.");
1272 }
1273 }
1274
1275 if (baseClassLoader != contextClassLoader) {
1276
1277
1278
1279
1280
1281 if (allowFlawedContext) {
1282 if (isDiagnosticsEnabled()) {
1283 logDiagnostic(
1284 "Warning: the context classloader is an ancestor of the"
1285 + " classloader that loaded LogFactoryImpl; it should be"
1286 + " the same or a descendant. The application using"
1287 + " commons-logging should ensure the context classloader"
1288 + " is used correctly.");
1289 }
1290 } else {
1291 throw new LogConfigurationException(
1292 "Bad classloader hierarchy; LogFactoryImpl was loaded via"
1293 + " a classloader that is not related to the current context"
1294 + " classloader.");
1295 }
1296 }
1297
1298 return baseClassLoader;
1299 }
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311 private ClassLoader getLowestClassLoader(ClassLoader c1, ClassLoader c2) {
1312
1313
1314 if (c1 == null)
1315 return c2;
1316
1317 if (c2 == null)
1318 return c1;
1319
1320 ClassLoader current;
1321
1322
1323 current = c1;
1324 while (current != null) {
1325 if (current == c2)
1326 return c1;
1327 current = current.getParent();
1328 }
1329
1330
1331 current = c2;
1332 while (current != null) {
1333 if (current == c1)
1334 return c2;
1335 current = current.getParent();
1336 }
1337
1338 return null;
1339 }
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356 private void handleFlawedDiscovery(String logAdapterClassName,
1357 ClassLoader classLoader,
1358 Throwable discoveryFlaw) {
1359
1360 if (isDiagnosticsEnabled()) {
1361 logDiagnostic("Could not instantiate Log '"
1362 + logAdapterClassName + "' -- "
1363 + discoveryFlaw.getClass().getName() + ": "
1364 + discoveryFlaw.getLocalizedMessage());
1365
1366 if (discoveryFlaw instanceof InvocationTargetException ) {
1367
1368
1369
1370 InvocationTargetException ite = (InvocationTargetException)discoveryFlaw;
1371 Throwable cause = ite.getTargetException();
1372 if (cause != null) {
1373 logDiagnostic("... InvocationTargetException: " +
1374 cause.getClass().getName() + ": " +
1375 cause.getLocalizedMessage());
1376
1377 if (cause instanceof ExceptionInInitializerError) {
1378 ExceptionInInitializerError eiie = (ExceptionInInitializerError)cause;
1379 Throwable cause2 = eiie.getException();
1380 if (cause2 != null) {
1381 logDiagnostic("... ExceptionInInitializerError: " +
1382 cause2.getClass().getName() + ": " +
1383 cause2.getLocalizedMessage());
1384 }
1385 }
1386 }
1387 }
1388 }
1389
1390 if (!allowFlawedDiscovery) {
1391 throw new LogConfigurationException(discoveryFlaw);
1392 }
1393 }
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422 private void handleFlawedHierarchy(ClassLoader badClassLoader, Class badClass)
1423 throws LogConfigurationException {
1424
1425 boolean implementsLog = false;
1426 String logInterfaceName = Log.class.getName();
1427 Class interfaces[] = badClass.getInterfaces();
1428 for (int i = 0; i < interfaces.length; i++) {
1429 if (logInterfaceName.equals(interfaces[i].getName())) {
1430 implementsLog = true;
1431 break;
1432 }
1433 }
1434
1435 if (implementsLog) {
1436
1437
1438 if (isDiagnosticsEnabled()) {
1439 try {
1440 ClassLoader logInterfaceClassLoader = getClassLoader(Log.class);
1441 logDiagnostic(
1442 "Class '" + badClass.getName()
1443 + "' was found in classloader "
1444 + objectId(badClassLoader)
1445 + ". It is bound to a Log interface which is not"
1446 + " the one loaded from classloader "
1447 + objectId(logInterfaceClassLoader));
1448 } catch (Throwable t) {
1449 logDiagnostic(
1450 "Error while trying to output diagnostics about"
1451 + " bad class '" + badClass + "'");
1452 }
1453 }
1454
1455 if (!allowFlawedHierarchy) {
1456 StringBuffer msg = new StringBuffer();
1457 msg.append("Terminating logging for this context ");
1458 msg.append("due to bad log hierarchy. ");
1459 msg.append("You have more than one version of '");
1460 msg.append(Log.class.getName());
1461 msg.append("' visible.");
1462 if (isDiagnosticsEnabled()) {
1463 logDiagnostic(msg.toString());
1464 }
1465 throw new LogConfigurationException(msg.toString());
1466 }
1467
1468 if (isDiagnosticsEnabled()) {
1469 StringBuffer msg = new StringBuffer();
1470 msg.append("Warning: bad log hierarchy. ");
1471 msg.append("You have more than one version of '");
1472 msg.append(Log.class.getName());
1473 msg.append("' visible.");
1474 logDiagnostic(msg.toString());
1475 }
1476 } else {
1477
1478 if (!allowFlawedDiscovery) {
1479 StringBuffer msg = new StringBuffer();
1480 msg.append("Terminating logging for this context. ");
1481 msg.append("Log class '");
1482 msg.append(badClass.getName());
1483 msg.append("' does not implement the Log interface.");
1484 if (isDiagnosticsEnabled()) {
1485 logDiagnostic(msg.toString());
1486 }
1487
1488 throw new LogConfigurationException(msg.toString());
1489 }
1490
1491 if (isDiagnosticsEnabled()) {
1492 StringBuffer msg = new StringBuffer();
1493 msg.append("[WARNING] Log class '");
1494 msg.append(badClass.getName());
1495 msg.append("' does not implement the Log interface.");
1496 logDiagnostic(msg.toString());
1497 }
1498 }
1499 }
1500 }