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