1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.pool2.impl;
18
19 import java.io.PrintWriter;
20 import java.lang.ref.WeakReference;
21 import java.security.AccessController;
22 import java.security.PrivilegedAction;
23 import java.text.DateFormat;
24 import java.text.SimpleDateFormat;
25 import java.util.List;
26 import java.util.stream.Collectors;
27 import java.util.stream.Stream;
28
29
30
31
32
33
34
35
36
37
38 public class SecurityManagerCallStack implements CallStack {
39
40
41
42
43 private static class PrivateSecurityManager extends SecurityManager {
44
45
46
47
48
49
50 private List<WeakReference<Class<?>>> getCallStack() {
51 final Stream<WeakReference<Class<?>>> map = Stream.of(getClassContext()).map(WeakReference::new);
52 return map.collect(Collectors.toList());
53 }
54 }
55
56
57
58
59 private static class Snapshot {
60 private final long timestampMillis = System.currentTimeMillis();
61 private final List<WeakReference<Class<?>>> stack;
62
63
64
65
66
67
68 private Snapshot(final List<WeakReference<Class<?>>> stack) {
69 this.stack = stack;
70 }
71 }
72
73 private final String messageFormat;
74
75
76 private final DateFormat dateFormat;
77
78 private final PrivateSecurityManager securityManager;
79
80 private volatile Snapshot snapshot;
81
82
83
84
85
86
87
88 public SecurityManagerCallStack(final String messageFormat, final boolean useTimestamp) {
89 this.messageFormat = messageFormat;
90 this.dateFormat = useTimestamp ? new SimpleDateFormat(messageFormat) : null;
91 this.securityManager = AccessController.doPrivileged((PrivilegedAction<PrivateSecurityManager>) PrivateSecurityManager::new);
92 }
93
94 @Override
95 public void clear() {
96 snapshot = null;
97 }
98
99 @Override
100 public void fillInStackTrace() {
101 snapshot = new Snapshot(securityManager.getCallStack());
102 }
103
104 @Override
105 public boolean printStackTrace(final PrintWriter writer) {
106 final Snapshot snapshotRef = this.snapshot;
107 if (snapshotRef == null) {
108 return false;
109 }
110 final String message;
111 if (dateFormat == null) {
112 message = messageFormat;
113 } else {
114 synchronized (dateFormat) {
115 message = dateFormat.format(Long.valueOf(snapshotRef.timestampMillis));
116 }
117 }
118 writer.println(message);
119 snapshotRef.stack.forEach(reference -> writer.println(reference.get()));
120 return true;
121 }
122 }