Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/management/remote/mandatory/loading/TargetMBeanTest.java
38867 views
1
/*
2
* Copyright (c) 2003, 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 4910428
27
* @summary Tests target MBean class loader used before JSR 160 loader
28
* @author Eamonn McManus
29
* @run clean TargetMBeanTest
30
* @run build TargetMBeanTest
31
* @run main TargetMBeanTest
32
*/
33
34
/*
35
The JSR 160 spec says that, when invoking a method (or setting an
36
attribute or creating) on a target MBean, that MBean's class loader
37
is used to deserialize parameters. The problem is that the RMI
38
connector protocol wraps these parameters as MarshalledObjects.
39
When you call get() on a MarshalledObject, the context class loader
40
is used to deserialize, so if we set this to the target MBean's
41
class loader everything should work. EXCEPT that MarshalledObject
42
first tries to load classes using the first class loader it finds in
43
the caller's stack. If our JSR 160 implementation is part of J2SE,
44
it will not find any such class loader (only the system class
45
loader). But if it's standalone, then it will find the class loader
46
of the JSR 160 implementation. If the class name of a parameter is
47
known to both the 160 loader and the target MBean loader, then we
48
will use the wrong loader for deserialization and the attempt to
49
invoke the target MBean with the deserialized object will fail.
50
51
We test this as follows. We fabricate an MLet that has the same set
52
of URLs as the 160 class loader, which we assume is the system class
53
loader (or at least, it is a URLClassLoader). This MLet is
54
therefore a "shadow class loader" -- for every class name known to
55
the 160 class loader, it can load the same name, but the result is
56
not the same class, since it has not been loaded by the same loader.
57
Then, we use the MLet to create an RMIConnectorServer MBean. This
58
MBean is an instance of "shadow RMIConnectorServer", and its
59
constructor has a parameter of type "shadow JMXServiceURL". If the
60
constructor is invoked with "real JMXServiceURL" it will fail.
61
62
While we are at it, we also test that the behaviour is correct for
63
the JMXMP protocol, if that optional protocol is present.
64
*/
65
import java.lang.reflect.*;
66
import java.net.*;
67
import java.util.*;
68
import javax.management.*;
69
import javax.management.loading.*;
70
import javax.management.remote.*;
71
import javax.management.remote.rmi.RMIConnectorServer;
72
73
public class TargetMBeanTest {
74
private static final ObjectName mletName;
75
static {
76
try {
77
mletName = new ObjectName("x:type=mlet");
78
} catch (Exception e) {
79
e.printStackTrace();
80
throw new Error();
81
}
82
}
83
84
public static void main(String[] args) throws Exception {
85
System.out.println("Test that target MBean class loader is used " +
86
"before JMX Remote API class loader");
87
88
ClassLoader jmxRemoteClassLoader =
89
JMXServiceURL.class.getClassLoader();
90
if (jmxRemoteClassLoader == null) {
91
System.out.println("JMX Remote API loaded by bootstrap " +
92
"class loader, this test is irrelevant");
93
return;
94
}
95
if (!(jmxRemoteClassLoader instanceof URLClassLoader)) {
96
System.out.println("TEST INVALID: JMX Remote API not loaded by " +
97
"URLClassLoader");
98
System.exit(1);
99
}
100
101
URLClassLoader jrcl = (URLClassLoader) jmxRemoteClassLoader;
102
URL[] urls = jrcl.getURLs();
103
PrivateMLet mlet = new PrivateMLet(urls, null, false);
104
Class shadowClass = mlet.loadClass(JMXServiceURL.class.getName());
105
if (shadowClass == JMXServiceURL.class) {
106
System.out.println("TEST INVALID: MLet got original " +
107
"JMXServiceURL not shadow");
108
System.exit(1);
109
}
110
111
MBeanServer mbs = MBeanServerFactory.newMBeanServer();
112
mbs.registerMBean(mlet, mletName);
113
114
final String[] protos = {"rmi", "iiop", "jmxmp"};
115
boolean ok = true;
116
for (int i = 0; i < protos.length; i++) {
117
try {
118
ok &= test(protos[i], mbs);
119
} catch (Exception e) {
120
System.out.println("TEST FAILED WITH EXCEPTION:");
121
e.printStackTrace(System.out);
122
ok = false;
123
}
124
}
125
126
if (ok)
127
System.out.println("Test passed");
128
else {
129
System.out.println("TEST FAILED");
130
System.exit(1);
131
}
132
}
133
134
private static boolean test(String proto, MBeanServer mbs)
135
throws Exception {
136
System.out.println("Testing for proto " + proto);
137
138
JMXConnectorServer cs;
139
JMXServiceURL url = new JMXServiceURL(proto, null, 0);
140
try {
141
cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null,
142
mbs);
143
} catch (MalformedURLException e) {
144
System.out.println("System does not recognize URL: " + url +
145
"; ignoring");
146
return true;
147
}
148
cs.start();
149
JMXServiceURL addr = cs.getAddress();
150
JMXServiceURL rmiurl = new JMXServiceURL("rmi", null, 0);
151
JMXConnector client = JMXConnectorFactory.connect(addr);
152
MBeanServerConnection mbsc = client.getMBeanServerConnection();
153
ObjectName on = new ObjectName("x:proto=" + proto + ",ok=yes");
154
mbsc.createMBean(RMIConnectorServer.class.getName(),
155
on,
156
mletName,
157
new Object[] {rmiurl, null},
158
new String[] {JMXServiceURL.class.getName(),
159
Map.class.getName()});
160
System.out.println("Successfully deserialized with " + proto);
161
mbsc.unregisterMBean(on);
162
163
client.close();
164
cs.stop();
165
return true;
166
}
167
}
168
169