RMIConnectorInternalMapTest.java revision 16177:89ef4b822745
1/*
2 * Copyright (c) 2013, 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
24import java.lang.management.ManagementFactory;
25import java.lang.ref.WeakReference;
26import java.lang.reflect.Field;
27import java.util.Collections;
28import java.util.Map;
29import javax.management.MBeanServer;
30import javax.management.MBeanServerConnection;
31import javax.management.remote.JMXConnector;
32import javax.management.remote.JMXConnectorFactory;
33import javax.management.remote.JMXConnectorServer;
34import javax.management.remote.JMXConnectorServerFactory;
35import javax.management.remote.JMXPrincipal;
36import javax.management.remote.JMXServiceURL;
37import javax.management.remote.rmi.RMIConnector;
38import javax.security.auth.Subject;
39
40/*
41 * @test
42 * @bug 6566891
43 * @summary Check no memory leak on RMIConnector's rmbscMap
44 * @author Shanliang JIANG
45 * @modules java.management/javax.management.remote.rmi:open
46 * @run clean RMIConnectorInternalMapTest
47 * @run build RMIConnectorInternalMapTest
48 * @run main RMIConnectorInternalMapTest
49 */
50
51public class RMIConnectorInternalMapTest {
52    public static void main(String[] args) throws Exception {
53        System.out.println("---RMIConnectorInternalMapTest starting...");
54
55        JMXConnectorServer connectorServer = null;
56        JMXConnector connectorClient = null;
57
58        try {
59            MBeanServer mserver = ManagementFactory.getPlatformMBeanServer();
60            JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0);
61            connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver);
62            connectorServer.start();
63
64            JMXServiceURL serverAddr = connectorServer.getAddress();
65            connectorClient = JMXConnectorFactory.connect(serverAddr, null);
66            connectorClient.connect();
67
68            Field rmbscMapField = RMIConnector.class.getDeclaredField("rmbscMap");
69            rmbscMapField.setAccessible(true);
70            Map<Subject, WeakReference<MBeanServerConnection>> map =
71                    (Map<Subject, WeakReference<MBeanServerConnection>>) rmbscMapField.get(connectorClient);
72            if (map != null && !map.isEmpty()) { // failed
73                throw new RuntimeException("RMIConnector's rmbscMap must be empty at the initial time.");
74            }
75
76            Subject delegationSubject =
77                    new Subject(true,
78                    Collections.singleton(new JMXPrincipal("delegate")),
79                    Collections.EMPTY_SET,
80                    Collections.EMPTY_SET);
81            MBeanServerConnection mbsc1 =
82                    connectorClient.getMBeanServerConnection(delegationSubject);
83            MBeanServerConnection mbsc2 =
84                    connectorClient.getMBeanServerConnection(delegationSubject);
85
86            if (mbsc1 == null) {
87                throw new RuntimeException("Got null connection.");
88            }
89            if (mbsc1 != mbsc2) {
90                throw new RuntimeException("Not got same connection with a same subject.");
91            }
92
93            map = (Map<Subject, WeakReference<MBeanServerConnection>>) rmbscMapField.get(connectorClient);
94            if (map == null || map.isEmpty()) { // failed
95                throw new RuntimeException("RMIConnector's rmbscMap has wrong size "
96                        + "after creating a delegated connection.");
97            }
98
99            delegationSubject = null;
100            mbsc1 = null;
101            mbsc2 = null;
102
103            int i = 0;
104            while (!map.isEmpty() && i++ < 60) {
105                System.gc();
106                Thread.sleep(100);
107            }
108            System.out.println("---GC times: " + i);
109
110            if (!map.isEmpty()) {
111                throw new RuntimeException("Failed to clean RMIConnector's rmbscMap");
112            } else {
113                System.out.println("---RMIConnectorInternalMapTest: PASSED!");
114            }
115        } finally {
116            try {
117                connectorClient.close();
118                connectorServer.stop();
119            } catch (Exception e) {
120            }
121        }
122    }
123}
124