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 private Log discoverLogImplementation(final String logCategory)
497 throws LogConfigurationException {
498 if (isDiagnosticsEnabled()) {
499 logDiagnostic("Discovering a Log implementation...");
500 }
501
502 initConfiguration();
503
504 Log result = null;
505
506
507 final String specifiedLogClassName = findUserSpecifiedLogClassName();
508
509 if (specifiedLogClassName != null) {
510 if (isDiagnosticsEnabled()) {
511 logDiagnostic("Attempting to load user-specified log class '" +
512 specifiedLogClassName + "'...");
513 }
514
515 result = createLogFromClass(specifiedLogClassName,
516 logCategory,
517 true);
518 if (result == null) {
519 final StringBuilder messageBuffer = new StringBuilder("User-specified log class '");
520 messageBuffer.append(specifiedLogClassName);
521 messageBuffer.append("' cannot be found or is not useable.");
522
523
524
525 informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LOG4J_LOGGER);
526 informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_JDK14_LOGGER);
527 informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LUMBERJACK_LOGGER);
528 informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_SIMPLE_LOGGER);
529 throw new LogConfigurationException(messageBuffer.toString());
530 }
531
532 return result;
533 }
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 if (isDiagnosticsEnabled()) {
564 logDiagnostic(
565 "No user-specified Log implementation; performing discovery" +
566 " using the standard supported logging implementations...");
567 }
568 for(int i=0; i<classesToDiscover.length && result == null; ++i) {
569 result = createLogFromClass(classesToDiscover[i], logCategory, true);
570 }
571
572 if (result == null) {
573 throw new LogConfigurationException
574 ("No suitable Log implementation");
575 }
576
577 return result;
578 }
579
580
581
582
583
584
585
586
587 private String findUserSpecifiedLogClassName() {
588 if (isDiagnosticsEnabled()) {
589 logDiagnostic("Trying to get log class from attribute '" + LOG_PROPERTY + "'");
590 }
591 String specifiedClass = (String) getAttribute(LOG_PROPERTY);
592
593 if (specifiedClass == null) {
594 if (isDiagnosticsEnabled()) {
595 logDiagnostic("Trying to get log class from attribute '" +
596 LOG_PROPERTY_OLD + "'");
597 }
598 specifiedClass = (String) getAttribute(LOG_PROPERTY_OLD);
599 }
600
601 if (specifiedClass == null) {
602 if (isDiagnosticsEnabled()) {
603 logDiagnostic("Trying to get log class from system property '" +
604 LOG_PROPERTY + "'");
605 }
606 try {
607 specifiedClass = getSystemProperty(LOG_PROPERTY, null);
608 } catch (final SecurityException e) {
609 if (isDiagnosticsEnabled()) {
610 logDiagnostic("No access allowed to system property '" +
611 LOG_PROPERTY + "' - " + e.getMessage());
612 }
613 }
614 }
615
616 if (specifiedClass == null) {
617 if (isDiagnosticsEnabled()) {
618 logDiagnostic("Trying to get log class from system property '" +
619 LOG_PROPERTY_OLD + "'");
620 }
621 try {
622 specifiedClass = getSystemProperty(LOG_PROPERTY_OLD, null);
623 } catch (final SecurityException e) {
624 if (isDiagnosticsEnabled()) {
625 logDiagnostic("No access allowed to system property '" +
626 LOG_PROPERTY_OLD + "' - " + e.getMessage());
627 }
628 }
629 }
630
631
632
633
634 if (specifiedClass != null) {
635 specifiedClass = specifiedClass.trim();
636 }
637
638 return specifiedClass;
639 }
640
641
642
643
644
645
646
647 @Override
648 public Object getAttribute(final String name) {
649 return attributes.get(name);
650 }
651
652
653
654
655
656
657 @Override
658 public String[] getAttributeNames() {
659 return attributes.keySet().toArray(EMPTY_STRING_ARRAY);
660 }
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679 private ClassLoader getBaseClassLoader() throws LogConfigurationException {
680 final ClassLoader thisClassLoader = getClassLoader(LogFactoryImpl.class);
681
682 if (!useTCCL) {
683 return thisClassLoader;
684 }
685
686 final ClassLoader contextClassLoader = getContextClassLoaderInternal();
687
688 final ClassLoader baseClassLoader = getLowestClassLoader(
689 contextClassLoader, thisClassLoader);
690
691 if (baseClassLoader == null) {
692
693
694
695
696 if (!allowFlawedContext) {
697 throw new LogConfigurationException("Bad class loader hierarchy; LogFactoryImpl was loaded via" +
698 " a class loader that is not related to the current context" +
699 " class loader.");
700 }
701 if (isDiagnosticsEnabled()) {
702 logDiagnostic("[WARNING] the context class loader is not part of a" +
703 " parent-child relationship with the class loader that" +
704 " loaded LogFactoryImpl.");
705 }
706
707
708
709 return contextClassLoader;
710 }
711
712 if (baseClassLoader != contextClassLoader) {
713
714
715
716
717
718 if (!allowFlawedContext) {
719 throw new LogConfigurationException(
720 "Bad class loader hierarchy; LogFactoryImpl was loaded via" +
721 " a class loader that is not related to the current context" +
722 " class loader.");
723 }
724 if (isDiagnosticsEnabled()) {
725 logDiagnostic(
726 "Warning: the context class loader is an ancestor of the" +
727 " class loader that loaded LogFactoryImpl; it should be" +
728 " the same or a descendant. The application using" +
729 " commons-logging should ensure the context class loader" +
730 " is used correctly.");
731 }
732 }
733
734 return baseClassLoader;
735 }
736
737
738
739
740
741 private boolean getBooleanConfiguration(final String key, final boolean dflt) {
742 final String val = getConfigurationValue(key);
743 if (val == null) {
744 return dflt;
745 }
746 return Boolean.parseBoolean(val);
747 }
748
749
750
751
752
753
754
755
756
757
758
759
760 private String getConfigurationValue(final String property) {
761 if (isDiagnosticsEnabled()) {
762 logDiagnostic("[ENV] Trying to get configuration for item " + property);
763 }
764
765 final Object valueObj = getAttribute(property);
766 if (valueObj != null) {
767 if (isDiagnosticsEnabled()) {
768 logDiagnostic("[ENV] Found LogFactory attribute [" + valueObj + "] for " + property);
769 }
770 return valueObj.toString();
771 }
772
773 if (isDiagnosticsEnabled()) {
774 logDiagnostic("[ENV] No LogFactory attribute found for " + property);
775 }
776
777 try {
778
779
780
781
782 final String value = getSystemProperty(property, null);
783 if (value != null) {
784 if (isDiagnosticsEnabled()) {
785 logDiagnostic("[ENV] Found system property [" + value + "] for " + property);
786 }
787 return value;
788 }
789
790 if (isDiagnosticsEnabled()) {
791 logDiagnostic("[ENV] No system property found for property " + property);
792 }
793 } catch (final SecurityException e) {
794 if (isDiagnosticsEnabled()) {
795 logDiagnostic("[ENV] Security prevented reading system property " + property);
796 }
797 }
798
799 if (isDiagnosticsEnabled()) {
800 logDiagnostic("[ENV] No configuration defined for item " + property);
801 }
802
803 return null;
804 }
805
806
807
808
809
810
811
812
813
814 @Override
815 public Log getInstance(final Class<?> clazz) throws LogConfigurationException {
816 return getInstance(clazz.getName());
817 }
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836 @Override
837 public Log getInstance(final String name) throws LogConfigurationException {
838 return instances.computeIfAbsent(name, this::newInstance);
839 }
840
841
842
843
844
845
846
847 @Deprecated
848 protected String getLogClassName() {
849 if (logClassName == null) {
850 discoverLogImplementation(getClass().getName());
851 }
852
853 return logClassName;
854 }
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870 @Deprecated
871 protected Constructor<?> getLogConstructor()
872 throws LogConfigurationException {
873
874
875 if (logConstructor == null) {
876 discoverLogImplementation(getClass().getName());
877 }
878
879 return logConstructor;
880 }
881
882
883
884
885
886
887
888
889
890
891
892
893 private ClassLoader getLowestClassLoader(final ClassLoader c1, final ClassLoader c2) {
894
895
896 if (c1 == null) {
897 return c2;
898 }
899
900 if (c2 == null) {
901 return c1;
902 }
903
904 ClassLoader current;
905
906
907 current = c1;
908 while (current != null) {
909 if (current == c2) {
910 return c1;
911 }
912
913 current = getParentClassLoader(current);
914 }
915
916
917 current = c2;
918 while (current != null) {
919 if (current == c1) {
920 return c2;
921 }
922
923 current = getParentClassLoader(current);
924 }
925
926 return null;
927 }
928
929
930
931
932
933
934
935
936 private ClassLoader getParentClassLoader(final ClassLoader cl) {
937 try {
938 return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) () -> cl.getParent());
939 } catch (final SecurityException ex) {
940 logDiagnostic("[SECURITY] Unable to obtain parent class loader");
941 return null;
942 }
943
944 }
945
946
947
948
949
950
951
952
953
954
955
956 private void handleFlawedDiscovery(final String logAdapterClassName,
957 final Throwable discoveryFlaw) {
958
959 if (isDiagnosticsEnabled()) {
960 logDiagnostic("Could not instantiate Log '" +
961 logAdapterClassName + "' -- " +
962 discoveryFlaw.getClass().getName() + ": " +
963 discoveryFlaw.getLocalizedMessage());
964
965 if (discoveryFlaw instanceof InvocationTargetException ) {
966
967
968
969 final InvocationTargetException ite = (InvocationTargetException) discoveryFlaw;
970 final Throwable cause = ite.getTargetException();
971 if (cause != null) {
972 logDiagnostic("... InvocationTargetException: " +
973 cause.getClass().getName() + ": " +
974 cause.getLocalizedMessage());
975
976 if (cause instanceof ExceptionInInitializerError) {
977 final ExceptionInInitializerError eiie = (ExceptionInInitializerError) cause;
978 final Throwable cause2 = eiie.getCause();
979 if (cause2 != null) {
980 final StringWriter sw = new StringWriter();
981 cause2.printStackTrace(new PrintWriter(sw, true));
982 logDiagnostic("... ExceptionInInitializerError: " + sw.toString());
983 }
984 }
985 }
986 }
987 }
988
989 if (!allowFlawedDiscovery) {
990 throw new LogConfigurationException(discoveryFlaw);
991 }
992 }
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020 private void handleFlawedHierarchy(final ClassLoader badClassLoader, final Class<?> badClass)
1021 throws LogConfigurationException {
1022
1023 boolean implementsLog = false;
1024 final String logInterfaceName = Log.class.getName();
1025 final Class<?>[] interfaces = badClass.getInterfaces();
1026 for (final Class<?> element : interfaces) {
1027 if (logInterfaceName.equals(element.getName())) {
1028 implementsLog = true;
1029 break;
1030 }
1031 }
1032
1033 if (implementsLog) {
1034
1035
1036 if (isDiagnosticsEnabled()) {
1037 try {
1038 final ClassLoader logInterfaceClassLoader = getClassLoader(Log.class);
1039 logDiagnostic("Class '" + badClass.getName() + "' was found in class loader " +
1040 objectId(badClassLoader) + ". It is bound to a Log interface which is not" +
1041 " the one loaded from class loader " + objectId(logInterfaceClassLoader));
1042 } catch (final Throwable t) {
1043 handleThrowable(t);
1044 logDiagnostic("Error while trying to output diagnostics about" + " bad class '" + badClass + "'");
1045 }
1046 }
1047
1048 if (!allowFlawedHierarchy) {
1049 final StringBuilder msg = new StringBuilder();
1050 msg.append("Terminating logging for this context ");
1051 msg.append("due to bad log hierarchy. ");
1052 msg.append("You have more than one version of '");
1053 msg.append(Log.class.getName());
1054 msg.append("' visible.");
1055 if (isDiagnosticsEnabled()) {
1056 logDiagnostic(msg.toString());
1057 }
1058 throw new LogConfigurationException(msg.toString());
1059 }
1060
1061 if (isDiagnosticsEnabled()) {
1062 final StringBuilder msg = new StringBuilder();
1063 msg.append("Warning: bad log hierarchy. ");
1064 msg.append("You have more than one version of '");
1065 msg.append(Log.class.getName());
1066 msg.append("' visible.");
1067 logDiagnostic(msg.toString());
1068 }
1069 } else {
1070
1071 if (!allowFlawedDiscovery) {
1072 final StringBuilder msg = new StringBuilder();
1073 msg.append("Terminating logging for this context. ");
1074 msg.append("Log class '");
1075 msg.append(badClass.getName());
1076 msg.append("' does not implement the Log interface.");
1077 if (isDiagnosticsEnabled()) {
1078 logDiagnostic(msg.toString());
1079 }
1080
1081 throw new LogConfigurationException(msg.toString());
1082 }
1083
1084 if (isDiagnosticsEnabled()) {
1085 final StringBuilder msg = new StringBuilder();
1086 msg.append("[WARNING] Log class '");
1087 msg.append(badClass.getName());
1088 msg.append("' does not implement the Log interface.");
1089 logDiagnostic(msg.toString());
1090 }
1091 }
1092 }
1093
1094
1095
1096
1097
1098
1099
1100
1101 private void informUponSimilarName(final StringBuilder messageBuffer, final String name,
1102 final String candidate) {
1103 if (name.equals(candidate)) {
1104
1105
1106 return;
1107 }
1108
1109
1110
1111
1112 if (name.regionMatches(true, 0, candidate, 0, PKG_LEN + 5)) {
1113 messageBuffer.append(" Did you mean '");
1114 messageBuffer.append(candidate);
1115 messageBuffer.append("'?");
1116 }
1117 }
1118
1119
1120
1121
1122
1123
1124
1125
1126 private void initConfiguration() {
1127 allowFlawedContext = getBooleanConfiguration(ALLOW_FLAWED_CONTEXT_PROPERTY, true);
1128 allowFlawedDiscovery = getBooleanConfiguration(ALLOW_FLAWED_DISCOVERY_PROPERTY, true);
1129 allowFlawedHierarchy = getBooleanConfiguration(ALLOW_FLAWED_HIERARCHY_PROPERTY, true);
1130 }
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144 private void initDiagnostics() {
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154 @SuppressWarnings("unchecked")
1155 final Class<LogFactoryImpl> clazz = (Class<LogFactoryImpl>) this.getClass();
1156 final ClassLoader classLoader = getClassLoader(clazz);
1157 String classLoaderName;
1158 try {
1159 if (classLoader == null) {
1160 classLoaderName = "BOOTLOADER";
1161 } else {
1162 classLoaderName = objectId(classLoader);
1163 }
1164 } catch (final SecurityException e) {
1165 classLoaderName = "UNKNOWN";
1166 }
1167 diagnosticPrefix = "[LogFactoryImpl@" + System.identityHashCode(this) + " from " + classLoaderName + "] ";
1168 }
1169
1170
1171
1172
1173
1174
1175
1176 @Deprecated
1177 protected boolean isJdk13LumberjackAvailable() {
1178 return isLogLibraryAvailable(
1179 "Jdk13Lumberjack",
1180 "org.apache.commons.logging.impl.Jdk13LumberjackLogger");
1181 }
1182
1183
1184
1185
1186
1187
1188
1189
1190 @Deprecated
1191 protected boolean isJdk14Available() {
1192 return isLogLibraryAvailable("Jdk14", "org.apache.commons.logging.impl.Jdk14Logger");
1193 }
1194
1195
1196
1197
1198
1199
1200
1201 @Deprecated
1202 protected boolean isLog4JAvailable() {
1203 return isLogLibraryAvailable("Log4J", LOGGING_IMPL_LOG4J_LOGGER);
1204 }
1205
1206
1207
1208
1209
1210
1211 private boolean isLogLibraryAvailable(final String name, final String className) {
1212 if (isDiagnosticsEnabled()) {
1213 logDiagnostic("Checking for '" + name + "'.");
1214 }
1215 try {
1216 final Log log = createLogFromClass(
1217 className,
1218 this.getClass().getName(),
1219 false);
1220
1221 if (log == null) {
1222 if (isDiagnosticsEnabled()) {
1223 logDiagnostic("Did not find '" + name + "'.");
1224 }
1225 return false;
1226 }
1227 if (isDiagnosticsEnabled()) {
1228 logDiagnostic("Found '" + name + "'.");
1229 }
1230 return true;
1231 } catch (final LogConfigurationException e) {
1232 if (isDiagnosticsEnabled()) {
1233 logDiagnostic("Logging system '" + name + "' is available but not useable.");
1234 }
1235 return false;
1236 }
1237 }
1238
1239
1240
1241
1242
1243
1244
1245
1246 protected void logDiagnostic(final String msg) {
1247 if (isDiagnosticsEnabled()) {
1248 logRawDiagnostic(diagnosticPrefix + msg);
1249 }
1250 }
1251
1252
1253
1254
1255
1256
1257
1258
1259 protected Log newInstance(final String name) throws LogConfigurationException {
1260 Log instance;
1261 try {
1262 if (logConstructor == null) {
1263 instance = discoverLogImplementation(name);
1264 }
1265 else {
1266 final Object[] params = { name };
1267 instance = (Log) logConstructor.newInstance(params);
1268 }
1269
1270 if (logMethod != null) {
1271 final Object[] params = { this };
1272 logMethod.invoke(instance, params);
1273 }
1274
1275 return instance;
1276
1277 } catch (final LogConfigurationException lce) {
1278
1279
1280
1281
1282 throw lce;
1283
1284 } catch (final InvocationTargetException e) {
1285
1286
1287 final Throwable c = e.getTargetException();
1288 throw new LogConfigurationException(c == null ? e : c);
1289 } catch (final Throwable t) {
1290 handleThrowable(t);
1291
1292
1293 throw new LogConfigurationException(t);
1294 }
1295 }
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305 @Override
1306 public void release() {
1307
1308 logDiagnostic("Releasing all known loggers");
1309 instances.clear();
1310 }
1311
1312
1313
1314
1315
1316
1317
1318 @Override
1319 public void removeAttribute(final String name) {
1320 attributes.remove(name);
1321 }
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347 @Override
1348 public void setAttribute(final String name, final Object value) {
1349 if (logConstructor != null) {
1350 logDiagnostic("setAttribute: call too late; configuration already performed.");
1351 }
1352
1353 if (value == null) {
1354 attributes.remove(name);
1355 } else {
1356 attributes.put(name, value);
1357 }
1358
1359 if (name.equals(TCCL_KEY)) {
1360 useTCCL = value != null && Boolean.parseBoolean(value.toString());
1361 }
1362 }
1363 }