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