Skip to content

Commit fe97874

Browse files
authored
Get rid of ReflectionUtil.dumpStackTraces(). (#431)
Java built-in way will be used now via `StackTraceUtil.dumpStackTraces()`
1 parent e4b9d58 commit fe97874

File tree

6 files changed

+115
-52
lines changed

6 files changed

+115
-52
lines changed

quickfixj-core/src/test/java/quickfix/SocketInitiatorTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import quickfix.mina.SingleThreadedEventHandlingStrategy;
3434
import quickfix.mina.ssl.SSLSupport;
3535
import quickfix.test.acceptance.ATServer;
36-
import quickfix.test.util.ReflectionUtil;
36+
import quickfix.test.util.StackTraceUtil;
3737

3838
import java.io.File;
3939
import java.io.IOException;
@@ -527,7 +527,7 @@ private void assertLoggedOn(ClientApplication clientApplication, Session clientS
527527
}
528528
if ( clientApplication.logonLatch.getCount() > 0 ) {
529529
System.err.println("XXX Dumping threads since latch count is not zero...");
530-
ReflectionUtil.dumpStackTraces();
530+
StackTraceUtil.dumpStackTraces();
531531
}
532532
});
533533
} finally {
@@ -544,7 +544,7 @@ private void assertLoggedOut(ClientApplication clientApplication, Session client
544544
assertNotNull("no client session", clientSession);
545545
final boolean await = clientApplication.logoutLatch.await(20, TimeUnit.SECONDS);
546546
if (!await) {
547-
ReflectionUtil.dumpStackTraces();
547+
StackTraceUtil.dumpStackTraces();
548548
}
549549
assertTrue("Expected logout did not occur", await);
550550
assertFalse("client session logged in?", clientSession.isLoggedOn());

quickfixj-core/src/test/java/quickfix/test/acceptance/ATServer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
import quickfix.mina.ProtocolFactory;
3939
import quickfix.mina.acceptor.AbstractSocketAcceptor;
4040
import quickfix.mina.ssl.SSLSupport;
41-
import quickfix.test.util.ReflectionUtil;
41+
import quickfix.test.util.StackTraceUtil;
4242

4343
import java.lang.management.ManagementFactory;
4444
import java.lang.management.ThreadInfo;
@@ -195,7 +195,7 @@ public void run() {
195195
final boolean await = shutdownLatch.await(30, TimeUnit.MINUTES);
196196
if (!await) {
197197
log.error("ShutdownLatch timed out. Dumping threads...");
198-
ReflectionUtil.dumpStackTraces();
198+
StackTraceUtil.dumpStackTraces(log);
199199
final ThreadMXBean bean = ManagementFactory.getThreadMXBean();
200200
long[] threadIds = bean.findDeadlockedThreads();
201201

quickfixj-core/src/test/java/quickfix/test/acceptance/ExpectMessageStep.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import org.junit.Assert;
2424
import org.slf4j.Logger;
2525
import org.slf4j.LoggerFactory;
26-
import quickfix.test.util.ReflectionUtil;
26+
import quickfix.test.util.StackTraceUtil;
2727

2828
import java.lang.management.ManagementFactory;
2929
import java.lang.management.ThreadInfo;
@@ -77,7 +77,7 @@ public void run(TestResult result, final TestConnection connection) throws Inter
7777
CharSequence message = connection.readMessage(clientId, TIMEOUT_IN_MS);
7878
if (message == null) {
7979
log.info("Dumping threads due to timeout when expecting a message...");
80-
ReflectionUtil.dumpStackTraces();
80+
StackTraceUtil.dumpStackTraces(log);
8181
final ThreadMXBean bean = ManagementFactory.getThreadMXBean();
8282
long[] threadIds = bean.findDeadlockedThreads();
8383

quickfixj-core/src/test/java/quickfix/test/acceptance/TestConnection.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import org.slf4j.LoggerFactory;
3434
import quickfix.mina.ProtocolFactory;
3535
import quickfix.mina.message.FIXProtocolCodecFactory;
36-
import quickfix.test.util.ReflectionUtil;
36+
import quickfix.test.util.StackTraceUtil;
3737

3838
import java.io.IOException;
3939
import java.lang.management.ManagementFactory;
@@ -147,7 +147,7 @@ public IoSession getSession() {
147147
boolean await = sessionCreatedLatch.await(70, TimeUnit.SECONDS); // 10 seconds more than retry time in ATServer.run()
148148
if (!await) {
149149
log.error("sessionCreatedLatch timed out. Dumping threads...");
150-
ReflectionUtil.dumpStackTraces();
150+
StackTraceUtil.dumpStackTraces(log);
151151

152152
final ThreadMXBean bean = ManagementFactory.getThreadMXBean();
153153
long[] threadIds = bean.findDeadlockedThreads();

quickfixj-core/src/test/java/quickfix/test/util/ReflectionUtil.java

Lines changed: 20 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
1+
/*******************************************************************************
2+
* Copyright (c) quickfixengine.org All rights reserved.
3+
*
4+
* This file is part of the QuickFIX FIX Engine
5+
*
6+
* This file may be distributed under the terms of the quickfixengine.org
7+
* license as defined by quickfixengine.org and appearing in the file
8+
* LICENSE included in the packaging of this file.
9+
*
10+
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
11+
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
12+
* PARTICULAR PURPOSE.
13+
*
14+
* See http://www.quickfixengine.org/LICENSE for licensing information.
15+
*
16+
* Contact ask@quickfixengine.org if any conditions of this licensing
17+
* are not clear to you.
18+
******************************************************************************/
19+
120
package quickfix.test.util;
221

3-
import java.beans.BeanInfo;
4-
import java.beans.Introspector;
5-
import java.beans.PropertyDescriptor;
6-
import java.lang.reflect.Array;
722
import java.lang.reflect.Constructor;
823
import java.lang.reflect.Field;
924
import java.lang.reflect.InvocationTargetException;
1025
import java.lang.reflect.Method;
1126
import java.util.Arrays;
1227

1328
/**
14-
* Helper class for using reflection. Initially it's focussed on
29+
* Helper class for using reflection. Initially it's focused on
1530
* invoking methods, but other tools may be added in the future.
1631
*/
1732
public class ReflectionUtil {
@@ -150,42 +165,4 @@ public static Object callStaticMethod(String methodFqn, Object[] args)
150165
return getMatchingMethod(targetClass, methodName, args).invoke(null, args);
151166
}
152167

153-
public static void dumpStackTraces() {
154-
try {
155-
Object threadMXBean = ReflectionUtil.callStaticMethod(
156-
"java.lang.management.ManagementFactory.getThreadMXBean", null);
157-
Class<?> threadMXBeanInterface = Class.forName("java.lang.management.ThreadMXBean");
158-
long[] threadIds = (long[]) ReflectionUtil.callMethod(threadMXBean,
159-
threadMXBeanInterface, "getAllThreadIds", null);
160-
Object[] threadInfos = (Object[]) ReflectionUtil.callMethod(threadMXBean,
161-
threadMXBeanInterface, "getThreadInfo", new Object[] { threadIds, 10 });
162-
for (Object threadInfo : threadInfos) {
163-
System.out.println((String) ReflectionUtil.callMethod(threadInfo,
164-
"getThreadName", null));
165-
BeanInfo info = Introspector.getBeanInfo(threadInfo.getClass());
166-
PropertyDescriptor[] parameters = info.getPropertyDescriptors();
167-
for (PropertyDescriptor parameter : parameters) {
168-
if (parameter.getReadMethod() != null) {
169-
Object value = parameter.getReadMethod().invoke(threadInfo,
170-
(Object[]) null);
171-
if (value != null && value.getClass().isArray()) {
172-
System.out.println(" " + parameter.getName() + ":");
173-
for (int a = 0; a < Array.getLength(value); a++) {
174-
System.out.println(" " + Array.get(value, a));
175-
}
176-
} else {
177-
if (value != null) {
178-
System.out.println(" " + parameter.getName() + ": " + value);
179-
}
180-
}
181-
}
182-
}
183-
System.out.println();
184-
}
185-
} catch (Exception e) {
186-
e.printStackTrace();
187-
// ignore, probably wrong JVM version
188-
}
189-
}
190-
191168
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*******************************************************************************
2+
* Copyright (c) quickfixengine.org All rights reserved.
3+
*
4+
* This file is part of the QuickFIX FIX Engine
5+
*
6+
* This file may be distributed under the terms of the quickfixengine.org
7+
* license as defined by quickfixengine.org and appearing in the file
8+
* LICENSE included in the packaging of this file.
9+
*
10+
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
11+
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
12+
* PARTICULAR PURPOSE.
13+
*
14+
* See http://www.quickfixengine.org/LICENSE for licensing information.
15+
*
16+
* Contact ask@quickfixengine.org if any conditions of this licensing
17+
* are not clear to you.
18+
******************************************************************************/
19+
package quickfix.test.util;
20+
21+
import java.lang.management.ManagementFactory;
22+
import java.lang.management.ThreadInfo;
23+
import java.lang.management.ThreadMXBean;
24+
import org.slf4j.Logger;
25+
26+
public class StackTraceUtil {
27+
28+
private static final String DEADLOCKED_THREADS_STRING = "DEADLOCKED threads:" + System.lineSeparator();
29+
30+
private StackTraceUtil() {
31+
}
32+
33+
/**
34+
* Prints stack traces for all threads via System.out.
35+
*/
36+
public static void dumpStackTraces() {
37+
ThreadInfo[] threadInfos = getThreadInfos();
38+
printThreadInfo(threadInfos, null);
39+
ThreadInfo[] deadlockedThreads = findDeadlockedThreads(null);
40+
printThreadInfo(deadlockedThreads, null);
41+
}
42+
43+
/**
44+
* Prints stack traces for all threads via passed Logger.
45+
*
46+
* @param log Logger instance to use
47+
*/
48+
public static void dumpStackTraces(Logger log) {
49+
ThreadInfo[] threadInfos = getThreadInfos();
50+
printThreadInfo(threadInfos, log);
51+
ThreadInfo[] deadlockedThreads = findDeadlockedThreads(log);
52+
printThreadInfo(deadlockedThreads, log);
53+
}
54+
55+
private static void printThreadInfo(ThreadInfo[] threadInfos, Logger log) {
56+
for (ThreadInfo threadInfo : threadInfos) {
57+
if (log != null) {
58+
log.error(threadInfo.toString());
59+
} else {
60+
System.out.println(threadInfo.toString());
61+
}
62+
}
63+
}
64+
65+
private static ThreadInfo[] getThreadInfos() {
66+
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
67+
long[] threadIds = bean.getAllThreadIds();
68+
ThreadInfo[] threadInfos = bean.getThreadInfo(threadIds, 15);
69+
return threadInfos;
70+
}
71+
72+
private static ThreadInfo[] findDeadlockedThreads(Logger log) {
73+
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
74+
long[] deadlockedThreadsIDs = bean.findDeadlockedThreads();
75+
if (deadlockedThreadsIDs != null) {
76+
if (log != null) {
77+
log.error(DEADLOCKED_THREADS_STRING);
78+
} else {
79+
System.out.println(DEADLOCKED_THREADS_STRING);
80+
}
81+
return bean.getThreadInfo(deadlockedThreadsIDs);
82+
}
83+
return new ThreadInfo[]{};
84+
}
85+
86+
}

0 commit comments

Comments
 (0)