Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/management/jmxremote/bootstrap/JMXAgentInterfaceBinding.java
41153 views
1
/*
2
* Copyright (c) 2015, Red Hat Inc
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
import java.io.IOException;
25
import java.net.InetAddress;
26
import java.net.InetSocketAddress;
27
import java.net.MalformedURLException;
28
import java.net.Socket;
29
import java.net.SocketAddress;
30
import java.net.UnknownHostException;
31
import java.nio.charset.StandardCharsets;
32
import java.util.HashMap;
33
import java.util.Map;
34
import java.util.concurrent.CountDownLatch;
35
import java.util.concurrent.TimeUnit;
36
import java.util.regex.Matcher;
37
import java.util.regex.Pattern;
38
39
import javax.management.remote.JMXConnector;
40
import javax.management.remote.JMXConnectorFactory;
41
import javax.management.remote.JMXServiceURL;
42
import javax.management.remote.rmi.RMIConnectorServer;
43
import javax.net.ssl.SSLSocket;
44
import javax.net.ssl.SSLSocketFactory;
45
import javax.rmi.ssl.SslRMIClientSocketFactory;
46
47
/**
48
* Tests client connections to the JDK's built-in JMX agent server on the given
49
* ports/interface combinations.
50
*
51
* @see JMXInterfaceBindingTest
52
*
53
* @author Severin Gehwolf <[email protected]>
54
*
55
* Usage:
56
*
57
* SSL:
58
* java -Dcom.sun.management.jmxremote.ssl.need.client.auth=true \
59
* -Dcom.sun.management.jmxremote.host=127.0.0.1 \
60
* -Dcom.sun.management.jmxremote.port=9111 \
61
* -Dcom.sun.management.jmxremote.rmi.port=9112 \
62
* -Dcom.sun.management.jmxremote.authenticate=false \
63
* -Dcom.sun.management.jmxremote.ssl=true \
64
* -Dcom.sun.management.jmxremote.registry.ssl=true
65
* -Djavax.net.ssl.keyStore=... \
66
* -Djavax.net.ssl.keyStorePassword=... \
67
* JMXAgentInterfaceBinding 127.0.0.1 9111 9112 true
68
*
69
* Non-SSL:
70
* java -Dcom.sun.management.jmxremote.host=127.0.0.1 \
71
* -Dcom.sun.management.jmxremote.port=9111 \
72
* -Dcom.sun.management.jmxremote.rmi.port=9112 \
73
* -Dcom.sun.management.jmxremote.authenticate=false \
74
* -Dcom.sun.management.jmxremote.ssl=false \
75
* JMXAgentInterfaceBinding 127.0.0.1 9111 9112 false
76
*
77
*/
78
public class JMXAgentInterfaceBinding {
79
80
private final MainThread mainThread;
81
82
public JMXAgentInterfaceBinding(InetAddress bindAddress,
83
int jmxPort,
84
int rmiPort,
85
boolean useSSL) {
86
this.mainThread = new MainThread(bindAddress, jmxPort, rmiPort, useSSL);
87
}
88
89
public void startEndpoint() {
90
mainThread.start();
91
try {
92
mainThread.join();
93
} catch (InterruptedException e) {
94
throw new RuntimeException("Test failed", e);
95
}
96
if (mainThread.isFailed()) {
97
mainThread.rethrowException();
98
}
99
}
100
101
public static void main(String[] args) {
102
if (args.length != 4) {
103
throw new RuntimeException(
104
"Test failed. usage: java JMXInterfaceBindingTest <BIND_ADDRESS> <JMX_PORT> <RMI_PORT> {true|false}");
105
}
106
int jmxPort = parsePortFromString(args[1]);
107
int rmiPort = parsePortFromString(args[2]);
108
boolean useSSL = Boolean.parseBoolean(args[3]);
109
String strBindAddr = args[0];
110
System.out.println(
111
"DEBUG: Running test for triplet (hostname,jmxPort,rmiPort) = ("
112
+ strBindAddr + "," + jmxPort + "," + rmiPort + "), useSSL = " + useSSL);
113
InetAddress bindAddress;
114
try {
115
bindAddress = InetAddress.getByName(args[0]);
116
} catch (UnknownHostException e) {
117
throw new RuntimeException("Test failed. Unknown ip: " + args[0]);
118
}
119
JMXAgentInterfaceBinding test = new JMXAgentInterfaceBinding(bindAddress,
120
jmxPort, rmiPort, useSSL);
121
test.startEndpoint(); // Expect for main test to terminate process
122
}
123
124
private static int parsePortFromString(String port) {
125
try {
126
return Integer.parseInt(port);
127
} catch (NumberFormatException e) {
128
throw new RuntimeException(
129
"Invalid port specified. Not an integer! Value was: "
130
+ port);
131
}
132
}
133
134
private static class JMXConnectorThread extends Thread {
135
136
private final String addr;
137
private final int jmxPort;
138
private final int rmiPort;
139
private final boolean useSSL;
140
private final CountDownLatch latch;
141
private volatile boolean failed;
142
private volatile boolean jmxConnectWorked;
143
private volatile boolean rmiConnectWorked;
144
145
private JMXConnectorThread(String addr,
146
int jmxPort,
147
int rmiPort,
148
boolean useSSL,
149
CountDownLatch latch) {
150
this.addr = addr;
151
this.jmxPort = jmxPort;
152
this.rmiPort = rmiPort;
153
this.latch = latch;
154
this.useSSL = useSSL;
155
}
156
157
@Override
158
public void run() {
159
try {
160
connect();
161
} catch (IOException e) {
162
e.printStackTrace();
163
failed = true;
164
}
165
}
166
167
private void connect() throws IOException {
168
System.out.println(
169
"JMXConnectorThread: Attempting JMX connection on: "
170
+ addr + " on port " + jmxPort);
171
JMXServiceURL url;
172
try {
173
url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"
174
+ addr + ":" + jmxPort + "/jmxrmi");
175
} catch (MalformedURLException e) {
176
throw new RuntimeException("Test failed.", e);
177
}
178
Map<String, Object> env = new HashMap<>();
179
if (useSSL) {
180
SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory();
181
env.put("com.sun.jndi.rmi.factory.socket", csf);
182
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf);
183
}
184
// connect and immediately close
185
JMXConnector c = JMXConnectorFactory.connect(url, env);
186
c.close();
187
System.out.println("JMXConnectorThread: connection to JMX worked");
188
jmxConnectWorked = true;
189
checkRmiSocket();
190
latch.countDown(); // signal we are done.
191
}
192
193
private void checkRmiSocket() throws IOException {
194
Socket rmiConnection;
195
if (useSSL) {
196
rmiConnection = SSLSocketFactory.getDefault().createSocket();
197
} else {
198
rmiConnection = new Socket();
199
}
200
SocketAddress target = new InetSocketAddress(addr, rmiPort);
201
rmiConnection.connect(target);
202
if (useSSL) {
203
((SSLSocket)rmiConnection).startHandshake();
204
}
205
System.out.println(
206
"JMXConnectorThread: connection to rmi socket worked host/port = "
207
+ addr + "/" + rmiPort);
208
rmiConnectWorked = true;
209
// Closing the channel without sending any data will cause an
210
// java.io.EOFException on the server endpoint. We don't care about this
211
// though, since we only want to test if we can connect.
212
rmiConnection.close();
213
}
214
215
public boolean isFailed() {
216
return failed;
217
}
218
219
public boolean jmxConnectionWorked() {
220
return jmxConnectWorked;
221
}
222
223
public boolean rmiConnectionWorked() {
224
return rmiConnectWorked;
225
}
226
}
227
228
private static class MainThread extends Thread {
229
230
private static final String EXP_TERM_MSG_REG = "Exit: ([0-9]+)";
231
private static final Pattern EXIT_PATTERN = Pattern.compile(EXP_TERM_MSG_REG);
232
private static final String COOP_EXIT = "MainThread: Cooperative Exit";
233
private static final int WAIT_FOR_JMX_AGENT_TIMEOUT_MS = 20_000;
234
private final String addr;
235
private final int jmxPort;
236
private final int rmiPort;
237
private final boolean useSSL;
238
private boolean jmxAgentStarted = false;
239
private volatile Exception excptn;
240
241
private MainThread(InetAddress bindAddress, int jmxPort, int rmiPort, boolean useSSL) {
242
this.addr = wrapAddress(bindAddress.getHostAddress());
243
this.jmxPort = jmxPort;
244
this.rmiPort = rmiPort;
245
this.useSSL = useSSL;
246
}
247
248
@Override
249
public void run() {
250
try {
251
waitUntilReadyForConnections();
252
253
// Wait for termination message
254
String actualTerm = new String(System.in.readAllBytes(), StandardCharsets.UTF_8).trim();
255
System.err.println("DEBUG: MainThread: actualTerm: '" + actualTerm + "'");
256
Matcher matcher = EXIT_PATTERN.matcher(actualTerm);
257
if (matcher.matches()) {
258
int expExitCode = Integer.parseInt(matcher.group(1));
259
System.out.println(COOP_EXIT);
260
System.exit(expExitCode); // The main test expects this exit value
261
}
262
} catch (Exception e) {
263
this.excptn = e;
264
}
265
}
266
267
private void waitUntilReadyForConnections() {
268
CountDownLatch latch = new CountDownLatch(1);
269
JMXConnectorThread connectionTester = new JMXConnectorThread(
270
addr, jmxPort, rmiPort, useSSL, latch);
271
connectionTester.start();
272
boolean expired = false;
273
try {
274
expired = !latch.await(WAIT_FOR_JMX_AGENT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
275
System.out.println(
276
"MainThread: Finished waiting for JMX agent to become available: expired == "
277
+ expired);
278
jmxAgentStarted = !expired;
279
} catch (InterruptedException e) {
280
throw new RuntimeException("Test failed", e);
281
}
282
if (!jmxAgentStarted) {
283
throw new RuntimeException(
284
"Test failed. JMX server agents not becoming available.");
285
}
286
if (connectionTester.isFailed()
287
|| !connectionTester.jmxConnectionWorked()
288
|| !connectionTester.rmiConnectionWorked()) {
289
throw new RuntimeException(
290
"Test failed. JMX agent does not seem ready. See log output for details.");
291
}
292
// The main test expects this exact message being printed
293
System.out.println("MainThread: Ready for connections");
294
}
295
296
private boolean isFailed() {
297
return excptn != null;
298
}
299
300
private void rethrowException() throws RuntimeException {
301
throw new RuntimeException(excptn);
302
}
303
}
304
305
/**
306
* Will wrap IPv6 address in '[]'
307
*/
308
static String wrapAddress(String address) {
309
if (address.contains(":")) {
310
return "[" + address + "]";
311
}
312
return address;
313
}
314
}
315
316