ThreadInfoCompositeData.java revision 11884:b45c81ca8671
1/*
2 * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug     4982289
27 * @summary Test ThreadInfo.from to return a valid
28 *          ThreadInfo object. Or throw exception if
29 *          the input CompositeData is invalid.
30 * @author  Mandy Chung
31 *
32 * @modules java.management
33 * @compile OpenTypeConverter.java
34 * @build ThreadInfoCompositeData
35 * @run main ThreadInfoCompositeData
36 */
37
38import javax.management.openmbean.*;
39import java.lang.management.LockInfo;
40import java.lang.management.MonitorInfo;
41import java.lang.management.ThreadInfo;
42
43public class ThreadInfoCompositeData {
44    private static StackTraceElement[] ste = new StackTraceElement[1];
45    private static CompositeData[] steCD = new CompositeData[1];
46    private static String lockClassName = "myClass";
47    private static int lockIdentityHashCode = 123456;
48    private static String lockName = lockClassName + '@' +
49        Integer.toHexString(lockIdentityHashCode);
50    private static LockInfo lockInfo =
51        new LockInfo(lockClassName, lockIdentityHashCode);
52
53    public static void main(String[] argv) throws Exception {
54        // A valid CompositeData is passed to ThreadInfo
55        createGoodCompositeData();
56        // A valid CompositeData for JDK 5.0 ThreadInfo
57        // is passed to ThreadInfo
58        createV5ThreadInfo();
59        // An invalid CompositeData is passed to ThreadInfo.from()
60        badNameCompositeData();
61        badTypeCompositeData();
62        System.out.println("Test passed");
63    }
64
65    public static void createGoodCompositeData() throws Exception {
66        CompositeType ct =
67            new CompositeType("MyCompositeType",
68                              "CompositeType for ThreadInfo",
69                              validItemNames,
70                              validItemNames,
71                              validItemTypes);
72        CompositeData cd =
73            new CompositeDataSupport(ct,
74                                     validItemNames,
75                                     values);
76        ThreadInfo info = ThreadInfo.from(cd);
77        checkThreadInfo(info);
78   }
79
80    public static void createV5ThreadInfo() throws Exception {
81        String[] v5ItemNames = new String[NUM_V5_ATTS];
82        OpenType[] v5ItemTypes = new OpenType[NUM_V5_ATTS];
83        Object[] v5ItemValues = new Object[NUM_V5_ATTS];
84        for (int i = 0; i < NUM_V5_ATTS; i++) {
85            v5ItemNames[i] = validItemNames[i];
86            v5ItemTypes[i] = validItemTypes[i];
87            v5ItemValues[i] = values[i];
88        }
89        CompositeType ct =
90            new CompositeType("MyCompositeType",
91                              "CompositeType for JDK 5.0 ThreadInfo",
92                              v5ItemNames,
93                              v5ItemNames,
94                              v5ItemTypes);
95        CompositeData cd =
96            new CompositeDataSupport(ct,
97                                     v5ItemNames,
98                                     v5ItemValues);
99        ThreadInfo info = ThreadInfo.from(cd);
100        checkThreadInfo(info);
101   }
102
103   static void checkThreadInfo(ThreadInfo info) throws Exception {
104        if (info.getThreadId() != ((Long) values[THREAD_ID]).longValue()) {
105            throw new RuntimeException("Thread Id = " + info.getThreadId() +
106               " expected = " + values[THREAD_ID]);
107        }
108        if (!info.getThreadName().equals(values[THREAD_NAME])) {
109            throw new RuntimeException("Thread Name = " +
110               info.getThreadName() + " expected = " + values[THREAD_NAME]);
111        }
112        if (info.getThreadState() != Thread.State.RUNNABLE) {
113            throw new RuntimeException("Thread Name = " +
114               info.getThreadName() + " expected = " + Thread.State.RUNNABLE);
115        }
116        if (info.getBlockedTime() != ((Long) values[BLOCKED_TIME]).longValue()) {
117            throw new RuntimeException("blocked time = " +
118               info.getBlockedTime() +
119               " expected = " + values[BLOCKED_TIME]);
120        }
121        if (info.getBlockedCount() != ((Long) values[BLOCKED_COUNT]).longValue()) {
122            throw new RuntimeException("blocked count = " +
123               info.getBlockedCount() +
124               " expected = " + values[BLOCKED_COUNT]);
125        }
126        if (info.getWaitedTime() != ((Long) values[WAITED_TIME]).longValue()) {
127            throw new RuntimeException("waited time = " +
128               info.getWaitedTime() +
129               " expected = " + values[WAITED_TIME]);
130        }
131        if (info.getWaitedCount() != ((Long) values[WAITED_COUNT]).longValue()) {
132            throw new RuntimeException("waited count = " +
133               info.getWaitedCount() +
134               " expected = " + values[WAITED_COUNT]);
135        }
136        if (!info.getLockName().equals(values[LOCK_NAME])) {
137            throw new RuntimeException("Lock Name = " +
138               info.getLockName() + " expected = " + values[LOCK_NAME]);
139        }
140        if (info.getLockOwnerId() !=
141                ((Long) values[LOCK_OWNER_ID]).longValue()) {
142            throw new RuntimeException(
143               "LockOwner Id = " + info.getLockOwnerId() +
144               " expected = " + values[LOCK_OWNER_ID]);
145        }
146        if (!info.getLockOwnerName().equals(values[LOCK_OWNER_NAME])) {
147            throw new RuntimeException("LockOwner Name = " +
148               info.getLockOwnerName() + " expected = " +
149               values[LOCK_OWNER_NAME]);
150        }
151        if (!values[DAEMON].equals(info.isDaemon())) {
152            throw new RuntimeException("Daemon = " +
153               info.isDaemon() + " expected = " +
154               values[DAEMON]);
155        }
156
157        checkStackTrace(info.getStackTrace());
158
159        checkLockInfo(info.getLockInfo());
160    }
161
162    private static void checkStackTrace(StackTraceElement[] s)
163        throws Exception {
164        if (ste.length != s.length) {
165            throw new RuntimeException("Stack Trace length = " +
166                s.length + " expected = " + ste.length);
167        }
168
169        StackTraceElement s1 = ste[0];
170        StackTraceElement s2 = s[0];
171
172        if (!s1.getClassName().equals(s2.getClassName())) {
173            throw new RuntimeException("Class name = " +
174                s2.getClassName() + " expected = " + s1.getClassName());
175        }
176        if (!s1.getMethodName().equals(s2.getMethodName())) {
177            throw new RuntimeException("Method name = " +
178                s2.getMethodName() + " expected = " + s1.getMethodName());
179        }
180        if (!s1.getFileName().equals(s2.getFileName())) {
181            throw new RuntimeException("File name = " +
182                s2.getFileName() + " expected = " + s1.getFileName());
183        }
184        if (s1.getLineNumber() != s2.getLineNumber()) {
185            throw new RuntimeException("Line number = " +
186                s2.getLineNumber() + " expected = " + s1.getLineNumber());
187        }
188    }
189
190    private static void checkLockInfo(LockInfo li)
191        throws Exception {
192        if (!li.getClassName().equals(lockInfo.getClassName())) {
193            throw new RuntimeException("Class Name = " +
194                li.getClassName() + " expected = " + lockInfo.getClassName());
195        }
196        if (li.getIdentityHashCode() != lockInfo.getIdentityHashCode()) {
197            throw new RuntimeException("Class Name = " +
198                li.getIdentityHashCode() + " expected = " +
199                lockInfo.getIdentityHashCode());
200        }
201    }
202
203    public static void badNameCompositeData() throws Exception {
204        CompositeType ct =
205            new CompositeType("MyCompositeType",
206                              "CompositeType for ThreadInfo",
207                              badItemNames,
208                              badItemNames,
209                              validItemTypes);
210        CompositeData cd =
211            new CompositeDataSupport(ct,
212                                     badItemNames,
213                                     values);
214
215        try {
216            ThreadInfo info = ThreadInfo.from(cd);
217        } catch (IllegalArgumentException e) {
218            System.out.println("Expected exception: " +
219                e.getMessage());
220            return;
221        }
222        throw new RuntimeException(
223            "IllegalArgumentException not thrown");
224    }
225
226    public static void badTypeCompositeData() throws Exception {
227        CompositeType ct =
228            new CompositeType("MyCompositeType",
229                              "CompositeType for ThreadInfo",
230                              validItemNames,
231                              validItemNames,
232                              badItemTypes);
233
234        // patch values[STACK_TRACE] to Long
235        values[STACK_TRACE] = new Long(1000);
236        values[LOCK_INFO] = new Long(1000);
237        CompositeData cd =
238            new CompositeDataSupport(ct,
239                                     validItemNames,
240                                     values);
241
242        try {
243            ThreadInfo info = ThreadInfo.from(cd);
244        } catch (IllegalArgumentException e) {
245            System.out.println("Expected exception: " +
246                e.getMessage());
247            return;
248        }
249        throw new RuntimeException(
250            "IllegalArgumentException not thrown");
251    }
252
253    private static final int THREAD_ID       = 0;
254    private static final int THREAD_NAME     = 1;
255    private static final int THREAD_STATE    = 2;
256    private static final int BLOCKED_TIME    = 3;
257    private static final int BLOCKED_COUNT   = 4;
258    private static final int WAITED_TIME     = 5;
259    private static final int WAITED_COUNT    = 6;
260    private static final int LOCK_NAME       = 7;
261    private static final int LOCK_OWNER_ID   = 8;
262    private static final int LOCK_OWNER_NAME = 9;
263    private static final int STACK_TRACE     = 10;
264    private static final int SUSPENDED       = 11;
265    private static final int IN_NATIVE       = 12;
266    private static final int NUM_V5_ATTS     = 13;
267    // JDK 6.0 ThreadInfo attributes
268    private static final int LOCK_INFO       = 13;
269    // JDK 9.0 ThreadInfo attributes
270    private static final int DAEMON          = 14;
271    private static final int PRIORITY        = 15;
272
273    private static final String[] validItemNames = {
274        "threadId",
275        "threadName",
276        "threadState",
277        "blockedTime",
278        "blockedCount",
279        "waitedTime",
280        "waitedCount",
281        "lockName",
282        "lockOwnerId",
283        "lockOwnerName",
284        "stackTrace",
285        "suspended",
286        "inNative",
287        "lockInfo",
288        "daemon",
289        "priority",
290    };
291
292    private static OpenType[] validItemTypes = {
293        SimpleType.LONG,
294        SimpleType.STRING,
295        SimpleType.STRING,
296        SimpleType.LONG,
297        SimpleType.LONG,
298        SimpleType.LONG,
299        SimpleType.LONG,
300        SimpleType.STRING,
301        SimpleType.LONG,
302        SimpleType.STRING,
303        null,  // ArrayType for StackTraceElement[]
304        SimpleType.BOOLEAN,
305        SimpleType.BOOLEAN,
306        null,  // CompositeType for LockInfo
307        SimpleType.BOOLEAN,
308        SimpleType.INTEGER,
309    };
310
311    private static Object[] values = {
312        new Long(100),
313        "FooThread",
314        "RUNNABLE",
315        new Long(200),
316        new Long(10),
317        new Long(300),
318        new Long(20),
319        lockName,
320        new Long(99),
321        "BarThread",
322        steCD,
323        new Boolean(false),
324        new Boolean(false),
325        null, // To be initialized to lockInfoCD
326        new Boolean(false),
327        Thread.NORM_PRIORITY,
328    };
329
330    private static final String[] steItemNames = {
331        "className",
332        "methodName",
333        "fileName",
334        "lineNumber",
335        "nativeMethod",
336    };
337
338    private static final String[] lockInfoItemNames = {
339        "className",
340        "identityHashCode",
341    };
342
343    static {
344        // create stack trace element
345        ste[0] = new StackTraceElement("FooClass", "getFoo", "Foo.java", 100);
346
347        // initialize the ste[0] and values and validItemTypes
348        try {
349            CompositeType steCType = (CompositeType)
350                OpenTypeConverter.toOpenType(StackTraceElement.class);
351            validItemTypes[STACK_TRACE] = new ArrayType(1, steCType);
352
353            final Object[] steValue = {
354                ste[0].getClassName(),
355                ste[0].getMethodName(),
356                ste[0].getFileName(),
357                new Integer(ste[0].getLineNumber()),
358                new Boolean(ste[0].isNativeMethod()),
359            };
360
361            steCD[0] =
362                new CompositeDataSupport(steCType,
363                                         steItemNames,
364                                         steValue);
365
366            CompositeType lockInfoCType = (CompositeType)
367                OpenTypeConverter.toOpenType(LockInfo.class);
368            validItemTypes[LOCK_INFO] = lockInfoCType;
369
370            final Object[] lockInfoValue = {
371                lockInfo.getClassName(),
372                lockInfo.getIdentityHashCode(),
373            };
374
375            values[LOCK_INFO] =
376                new CompositeDataSupport(lockInfoCType,
377                                         lockInfoItemNames,
378                                         lockInfoValue);
379        } catch (Exception e) {
380            throw new RuntimeException(e);
381        }
382    }
383
384    private static final String[] badItemNames = {
385        "threadId",
386        "threadName",
387        "threadState",
388        "blockedTime",
389        "blockedCount",
390        "waitedTime",
391        "waitedCount",
392        "lockName",
393        "lockOwnerId",
394        "lockOwnerName",
395        "BadStackTrace", // bad item name
396        "suspended",
397        "inNative",
398        "lockInfo",
399        "daemon",
400        "priority",
401    };
402    private static final OpenType[] badItemTypes = {
403        SimpleType.LONG,
404        SimpleType.STRING,
405        SimpleType.STRING,
406        SimpleType.LONG,
407        SimpleType.LONG,
408        SimpleType.LONG,
409        SimpleType.LONG,
410        SimpleType.STRING,
411        SimpleType.LONG,
412        SimpleType.STRING,
413        SimpleType.LONG,  // bad type
414        SimpleType.BOOLEAN,
415        SimpleType.BOOLEAN,
416        SimpleType.LONG,  // bad type
417        SimpleType.BOOLEAN,
418        SimpleType.INTEGER,
419    };
420
421}
422