Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java
41153 views
1
/*
2
* Copyright (c) 2003, 2018, 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
import sun.management.jmxremote.ConnectorBootstrap;
24
25
import java.io.File;
26
import java.io.FileInputStream;
27
import java.io.FilenameFilter;
28
import java.io.IOException;
29
import java.net.BindException;
30
import java.rmi.server.ExportException;
31
32
import java.util.Properties;
33
import java.util.Iterator;
34
import java.util.Set;
35
import java.util.ArrayList;
36
import java.util.HashMap;
37
import java.util.Map;
38
import java.util.Enumeration;
39
40
import javax.management.remote.*;
41
import javax.management.*;
42
43
import jdk.internal.agent.AgentConfigurationError;
44
45
import java.security.Security;
46
47
/**
48
* <p>This class implements unit test for RMI Bootstrap.
49
* When called with no arguments main() looks in the directory indicated
50
* by the "test.src" system property for files called management*ok.properties
51
* or management*ko.properties. The *ok.properties files are assumed to be
52
* valid Java M&M config files for which the bootstrap should succeed.
53
* The *ko.properties files are assumed to be configurations for which the
54
* bootstrap & connection test will fail.</p>
55
*
56
* <p>The rmi port number can be specified with the "rmi.port" system property.
57
* If not, this test will use the first available port</p>
58
*
59
* <p>When called with some argument, the main() will interprete its args to
60
* be Java M&M configuration file names. The filenames are expected to end
61
* with ok.properties or ko.properties - and are interpreted as above.</p>
62
*
63
* <p>Note that a limitation of the RMI registry (bug 4267864) prevent
64
* this test from succeeding if more than 1 configuration is used.
65
* As long as 4267864 isn't fix, this test must be called as many times
66
* as needed but with a single argument (no arguments, or several arguments
67
* will fail).</p>
68
*
69
* <p>Debug traces are logged in "sun.management.test"</p>
70
**/
71
public class RmiBootstrapTest {
72
// the number of consecutive ports to test for availability
73
private static int MAX_GET_FREE_PORT_TRIES = 10;
74
static TestLogger log =
75
new TestLogger("RmiBootstrapTest");
76
77
/**
78
* Default values for RMI configuration properties.
79
**/
80
public static interface DefaultValues {
81
public static final String PORT="0";
82
public static final String CONFIG_FILE_NAME="management.properties";
83
public static final String USE_SSL="true";
84
public static final String USE_AUTHENTICATION="true";
85
public static final String PASSWORD_FILE_NAME="jmxremote.password";
86
public static final String ACCESS_FILE_NAME="jmxremote.access";
87
public static final String KEYSTORE="keystore";
88
public static final String KEYSTORE_PASSWD="password";
89
public static final String TRUSTSTORE="truststore";
90
public static final String TRUSTSTORE_PASSWD="trustword";
91
public static final String SSL_NEED_CLIENT_AUTH="false";
92
}
93
94
/**
95
* Names of RMI configuration properties.
96
**/
97
public static interface PropertyNames {
98
public static final String PORT=
99
"com.sun.management.jmxremote.port";
100
public static final String CONFIG_FILE_NAME=
101
"com.sun.management.config.file";
102
public static final String USE_SSL=
103
"com.sun.management.jmxremote.ssl";
104
public static final String USE_AUTHENTICATION=
105
"com.sun.management.jmxremote.authenticate";
106
public static final String PASSWORD_FILE_NAME=
107
"com.sun.management.jmxremote.password.file";
108
public static final String ACCESS_FILE_NAME=
109
"com.sun.management.jmxremote.access.file";
110
public static final String INSTRUMENT_ALL=
111
"com.sun.management.instrumentall";
112
public static final String CREDENTIALS =
113
"jmx.remote.credentials";
114
public static final String KEYSTORE=
115
"javax.net.ssl.keyStore";
116
public static final String KEYSTORE_PASSWD=
117
"javax.net.ssl.keyStorePassword";
118
public static final String TRUSTSTORE=
119
"javax.net.ssl.trustStore";
120
public static final String TRUSTSTORE_PASSWD=
121
"javax.net.ssl.trustStorePassword";
122
public static final String SSL_ENABLED_CIPHER_SUITES =
123
"com.sun.management.jmxremote.ssl.enabled.cipher.suites";
124
public static final String SSL_ENABLED_PROTOCOLS =
125
"com.sun.management.jmxremote.ssl.enabled.protocols";
126
public static final String SSL_NEED_CLIENT_AUTH =
127
"com.sun.management.jmxremote.ssl.need.client.auth";
128
public static final String SSL_CLIENT_ENABLED_CIPHER_SUITES =
129
"javax.rmi.ssl.client.enabledCipherSuites";
130
}
131
132
/**
133
* A filter to find all filenames who match <prefix>*<suffix>.
134
* Note that <prefix> and <suffix> can overlap.
135
**/
136
private static class ConfigFilenameFilter implements FilenameFilter {
137
final String suffix;
138
final String prefix;
139
ConfigFilenameFilter(String prefix, String suffix) {
140
this.suffix=suffix;
141
this.prefix=prefix;
142
}
143
public boolean accept(File dir, String name) {
144
return (name.startsWith(prefix) && name.endsWith(suffix));
145
}
146
}
147
148
/**
149
* Get all "management*ok.properties" files in the directory
150
* indicated by the "test.src" management property.
151
**/
152
private static File[] findConfigurationFilesOk() {
153
final String testSrc = System.getProperty("test.src");
154
final File dir = new File(testSrc);
155
final FilenameFilter filter =
156
new ConfigFilenameFilter("management_test","ok.properties");
157
return dir.listFiles(filter);
158
}
159
160
/**
161
* Get all "management*ko.properties" files in the directory
162
* indicated by the "test.src" management property.
163
**/
164
private static File[] findConfigurationFilesKo() {
165
final String testSrc = System.getProperty("test.src");
166
final File dir = new File(testSrc);
167
final FilenameFilter filter =
168
new ConfigFilenameFilter("management_test","ko.properties");
169
return dir.listFiles(filter);
170
}
171
172
/**
173
* List all MBeans and their attributes. Used to test communication
174
* with the Java M&M MBean Server.
175
* @return the number of queried MBeans.
176
*/
177
public static int listMBeans(MBeanServerConnection server)
178
throws IOException {
179
return listMBeans(server,null,null);
180
}
181
182
/**
183
* List all matching MBeans and their attributes.
184
* Used to test communication with the Java M&M MBean Server.
185
* @return the number of matching MBeans.
186
*/
187
public static int listMBeans(MBeanServerConnection server,
188
ObjectName pattern, QueryExp query)
189
throws IOException {
190
191
final Set names = server.queryNames(pattern,query);
192
for (final Iterator i=names.iterator(); i.hasNext(); ) {
193
ObjectName name = (ObjectName)i.next();
194
log.trace("listMBeans","Got MBean: "+name);
195
try {
196
MBeanInfo info =
197
server.getMBeanInfo((ObjectName)name);
198
MBeanAttributeInfo[] attrs = info.getAttributes();
199
if (attrs == null) continue;
200
for (int j=0; j<attrs.length; j++) {
201
if (attrs[j].isReadable()) {
202
try {
203
Object o =
204
server.getAttribute(name,attrs[j].getName());
205
if (log.isDebugOn())
206
log.debug("listMBeans","\t\t" +
207
attrs[j].getName() +
208
" = "+o);
209
} catch (Exception x) {
210
log.trace("listMBeans","JmxClient failed to get " +
211
attrs[j].getName() + ": " + x);
212
final IOException io =
213
new IOException("JmxClient failed to get " +
214
attrs[j].getName());
215
io.initCause(x);
216
throw io;
217
}
218
}
219
}
220
} catch (Exception x) {
221
log.trace("listMBeans",
222
"JmxClient failed to get MBeanInfo: " + x);
223
final IOException io =
224
new IOException("JmxClient failed to get MBeanInfo: "+x);
225
io.initCause(x);
226
throw io;
227
}
228
}
229
return names.size();
230
}
231
232
/**
233
* Compute the full path name for a default file.
234
* @param basename basename (with extension) of the default file.
235
* @return ${JRE}/conf/management/${basename}
236
**/
237
private static String getDefaultFileName(String basename) {
238
final String fileSeparator = File.separator;
239
final StringBuffer defaultFileName =
240
new StringBuffer(System.getProperty("java.home")).
241
append(fileSeparator).append("conf").append(fileSeparator).
242
append("management").append(fileSeparator).
243
append(basename);
244
return defaultFileName.toString();
245
}
246
247
/**
248
* Compute the full path name for a default file.
249
* @param basename basename (with extension) of the default file.
250
* @return ${JRE}/conf/management/${basename}
251
**/
252
private static String getDefaultStoreName(String basename) {
253
final String fileSeparator = File.separator;
254
final StringBuffer defaultFileName =
255
new StringBuffer(System.getProperty("test.src")).
256
append(fileSeparator).append("ssl").append(fileSeparator).
257
append(basename);
258
return defaultFileName.toString();
259
}
260
261
262
/**
263
* Parses the password file to read the credentials.
264
* Returns an ArrayList of arrays of 2 string:
265
* {<subject>, <password>}.
266
* If the password file does not exists, return an empty list.
267
* (File not found = empty file).
268
**/
269
private ArrayList readCredentials(String passwordFileName)
270
throws IOException {
271
final Properties pws = new Properties();
272
final ArrayList result = new ArrayList();
273
final File f = new File(passwordFileName);
274
if (!f.exists()) return result;
275
FileInputStream fin = new FileInputStream(passwordFileName);
276
try {pws.load(fin);}finally{fin.close();}
277
for (Enumeration en=pws.propertyNames();en.hasMoreElements();) {
278
final String[] cred = new String[2];
279
cred[0]=(String)en.nextElement();
280
cred[1]=pws.getProperty(cred[0]);
281
result.add(cred);
282
}
283
return result;
284
}
285
286
287
/**
288
* Connect with the given url, using all given credentials in turn.
289
* A null entry in the useCredentials arrays indicate a connection
290
* where no credentials are used.
291
* @param url JMXServiceURL of the server.
292
* @param useCredentials An array of credentials (a credential
293
* is a two String array, so this is an array of arrays
294
* of strings:
295
* useCredentials[i][0]=subject
296
* useCredentials[i][1]=password
297
* if useCredentials[i] == null means no credentials.
298
* @param expectConnectOk true if connection is expected to succeed
299
* Note: if expectConnectOk=false and the test fails to connect
300
* the number of failure is not incremented. Conversely,
301
* if expectConnectOk=false and the test does not fail to
302
* connect the number of failure is incremented.
303
* @param expectReadOk true if communication (listMBeans) is expected
304
* to succeed.
305
* Note: if expectReadOk=false and the test fails to read MBeans
306
* the number of failure is not incremented. Conversely,
307
* if expectReadOk=false and the test does not fail to
308
* read MBeans the number of failure is incremented.
309
* @return number of failure.
310
**/
311
public int connectAndRead(JMXServiceURL url,
312
Object[] useCredentials,
313
boolean expectConnectOk,
314
boolean expectReadOk)
315
throws IOException {
316
317
int errorCount = 0;
318
319
for (int i=0 ; i<useCredentials.length ; i++) {
320
final Map m = new HashMap();
321
final String[] credentials = (String[])useCredentials[i];
322
final String crinfo;
323
if (credentials != null) {
324
crinfo = "{"+credentials[0] + ", " + credentials[1] + "}";
325
m.put(PropertyNames.CREDENTIALS,credentials);
326
} else {
327
crinfo="no credentials";
328
}
329
log.trace("testCommunication","using credentials: " + crinfo);
330
331
final JMXConnector c;
332
try {
333
c = JMXConnectorFactory.connect(url,m);
334
} catch (IOException x ) {
335
if (expectConnectOk) {
336
final String err = "Connection failed for " + crinfo +
337
": " + x;
338
System.out.println(err);
339
log.trace("testCommunication",err);
340
log.debug("testCommunication",x);
341
errorCount++;
342
continue;
343
} else {
344
System.out.println("Connection failed as expected for " +
345
crinfo + ": " + x);
346
continue;
347
}
348
} catch (RuntimeException x ) {
349
if (expectConnectOk) {
350
final String err = "Connection failed for " + crinfo +
351
": " + x;
352
System.out.println(err);
353
log.trace("testCommunication",err);
354
log.debug("testCommunication",x);
355
errorCount++;
356
continue;
357
} else {
358
System.out.println("Connection failed as expected for " +
359
crinfo + ": " + x);
360
continue;
361
}
362
}
363
try {
364
MBeanServerConnection conn =
365
c.getMBeanServerConnection();
366
if (log.isDebugOn()) {
367
log.debug("testCommunication","Connection is:" + conn);
368
log.debug("testCommunication","Server domain is: " +
369
conn.getDefaultDomain());
370
}
371
final ObjectName pattern =
372
new ObjectName("java.lang:type=Memory,*");
373
final int count = listMBeans(conn,pattern,null);
374
if (count == 0)
375
throw new Exception("Expected at least one matching "+
376
"MBean for "+pattern);
377
if (expectReadOk) {
378
System.out.println("Communication succeeded " +
379
"as expected for "+
380
crinfo + ": found " + count
381
+ ((count<2)?"MBean":"MBeans"));
382
} else {
383
final String err = "Expected failure didn't occur for " +
384
crinfo;
385
System.out.println(err);
386
errorCount++;
387
}
388
} catch (IOException x ) {
389
if (expectReadOk) {
390
final String err = "Communication failed with " + crinfo +
391
": " + x;
392
System.out.println(err);
393
log.trace("testCommunication",err);
394
log.debug("testCommunication",x);
395
errorCount++;
396
continue;
397
} else {
398
System.out.println("Communication failed as expected for "+
399
crinfo + ": " + x);
400
continue;
401
}
402
} catch (RuntimeException x ) {
403
if (expectReadOk) {
404
final String err = "Communication failed with " + crinfo +
405
": " + x;
406
System.out.println(err);
407
log.trace("testCommunication",err);
408
log.debug("testCommunication",x);
409
errorCount++;
410
continue;
411
} else {
412
System.out.println("Communication failed as expected for "+
413
crinfo + ": " + x);
414
}
415
} catch (Exception x) {
416
final String err = "Failed to read MBeans with " + crinfo +
417
": " + x;
418
System.out.println(err);
419
log.trace("testCommunication",err);
420
log.debug("testCommunication",x);
421
errorCount++;
422
continue;
423
} finally {
424
c.close();
425
}
426
}
427
return errorCount;
428
}
429
430
431
private void setSslProperties(String clientEnabledCipherSuites) {
432
final String defaultKeyStore =
433
getDefaultStoreName(DefaultValues.KEYSTORE);
434
final String defaultTrustStore =
435
getDefaultStoreName(DefaultValues.TRUSTSTORE);
436
437
final String keyStore =
438
System.getProperty(PropertyNames.KEYSTORE, defaultKeyStore);
439
System.setProperty(PropertyNames.KEYSTORE,keyStore);
440
log.trace("setSslProperties",PropertyNames.KEYSTORE+"="+keyStore);
441
442
final String password =
443
System.getProperty(PropertyNames.KEYSTORE_PASSWD,
444
DefaultValues.KEYSTORE_PASSWD);
445
System.setProperty(PropertyNames.KEYSTORE_PASSWD,password);
446
log.trace("setSslProperties",
447
PropertyNames.KEYSTORE_PASSWD+"="+password);
448
449
final String trustStore =
450
System.getProperty(PropertyNames.TRUSTSTORE,
451
defaultTrustStore);
452
System.setProperty(PropertyNames.TRUSTSTORE,trustStore);
453
log.trace("setSslProperties",
454
PropertyNames.TRUSTSTORE+"="+trustStore);
455
456
final String trustword =
457
System.getProperty(PropertyNames.TRUSTSTORE_PASSWD,
458
DefaultValues.TRUSTSTORE_PASSWD);
459
System.setProperty(PropertyNames.TRUSTSTORE_PASSWD,trustword);
460
log.trace("setSslProperties",
461
PropertyNames.TRUSTSTORE_PASSWD+"="+trustword);
462
463
if (clientEnabledCipherSuites != null) {
464
System.setProperty("javax.rmi.ssl.client.enabledCipherSuites",
465
clientEnabledCipherSuites);
466
} else {
467
System.clearProperty("javax.rmi.ssl.client.enabledCipherSuites");
468
}
469
}
470
471
private void checkSslConfiguration() {
472
try {
473
final String defaultConf =
474
getDefaultFileName(DefaultValues.CONFIG_FILE_NAME);
475
final String confname =
476
System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf);
477
478
final Properties props = new Properties();
479
final File conf = new File(confname);
480
if (conf.exists()) {
481
FileInputStream fin = new FileInputStream(conf);
482
try {props.load(fin);} finally {fin.close();}
483
}
484
485
// Do we use SSL?
486
final String useSslStr =
487
props.getProperty(PropertyNames.USE_SSL,
488
DefaultValues.USE_SSL);
489
final boolean useSsl =
490
Boolean.valueOf(useSslStr).booleanValue();
491
492
log.debug("checkSslConfiguration",
493
PropertyNames.USE_SSL+"="+useSsl+
494
": setting SSL");
495
// Do we use SSL client authentication?
496
final String useSslClientAuthStr =
497
props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH,
498
DefaultValues.SSL_NEED_CLIENT_AUTH);
499
final boolean useSslClientAuth =
500
Boolean.valueOf(useSslClientAuthStr).booleanValue();
501
502
log.debug("checkSslConfiguration",
503
PropertyNames.SSL_NEED_CLIENT_AUTH+"="+useSslClientAuth);
504
505
// Do we use customized SSL cipher suites?
506
final String sslCipherSuites =
507
props.getProperty(PropertyNames.SSL_ENABLED_CIPHER_SUITES);
508
509
log.debug("checkSslConfiguration",
510
PropertyNames.SSL_ENABLED_CIPHER_SUITES + "=" +
511
sslCipherSuites);
512
513
// Do we use customized SSL protocols?
514
final String sslProtocols =
515
props.getProperty(PropertyNames.SSL_ENABLED_PROTOCOLS);
516
517
log.debug("checkSslConfiguration",
518
PropertyNames.SSL_ENABLED_PROTOCOLS + "=" +
519
sslProtocols);
520
521
if (useSsl) {
522
setSslProperties(props.getProperty(
523
PropertyNames.SSL_CLIENT_ENABLED_CIPHER_SUITES));
524
}
525
} catch (Exception x) {
526
System.out.println("Failed to setup SSL configuration: " + x);
527
log.debug("checkSslConfiguration",x);
528
}
529
}
530
531
/**
532
* Tests the server bootstraped at the given URL.
533
* Uses the system properties to determine which config file is used.
534
* Loads the config file to determine which password file is used.
535
* Loads the password file to find out wich credentials to use.
536
* Also checks that unregistered user/passwords are not allowed to
537
* connect when a password file is used.
538
*
539
* This method calls connectAndRead().
540
**/
541
public void testCommunication(JMXServiceURL url)
542
throws IOException {
543
544
final String defaultConf =
545
getDefaultFileName(DefaultValues.CONFIG_FILE_NAME);
546
final String confname =
547
System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf);
548
549
final Properties props = new Properties();
550
final File conf = new File(confname);
551
if (conf.exists()) {
552
FileInputStream fin = new FileInputStream(conf);
553
try {props.load(fin);} finally {fin.close();}
554
}
555
556
// Do we use authentication?
557
final String useAuthenticationStr =
558
props.getProperty(PropertyNames.USE_AUTHENTICATION,
559
DefaultValues.USE_AUTHENTICATION);
560
final boolean useAuthentication =
561
Boolean.valueOf(useAuthenticationStr).booleanValue();
562
563
// Get Password File
564
final String defaultPasswordFileName = Utils.convertPath(
565
getDefaultFileName(DefaultValues.PASSWORD_FILE_NAME));
566
final String passwordFileName = Utils.convertPath(
567
props.getProperty(PropertyNames.PASSWORD_FILE_NAME,
568
defaultPasswordFileName));
569
570
// Get Access File
571
final String defaultAccessFileName = Utils.convertPath(
572
getDefaultFileName(DefaultValues.ACCESS_FILE_NAME));
573
final String accessFileName = Utils.convertPath(
574
props.getProperty(PropertyNames.ACCESS_FILE_NAME,
575
defaultAccessFileName));
576
577
if (useAuthentication) {
578
System.out.println("PasswordFileName: " + passwordFileName);
579
System.out.println("accessFileName: " + accessFileName);
580
}
581
582
final Object[] allCredentials;
583
final Object[] noCredentials = { null };
584
if (useAuthentication) {
585
final ArrayList l = readCredentials(passwordFileName);
586
if (l.size() == 0) allCredentials = null;
587
else allCredentials = l.toArray();
588
} else allCredentials = noCredentials;
589
590
int errorCount = 0;
591
if (allCredentials!=null) {
592
// Tests that the registered user/passwords are allowed to
593
// connect & read
594
//
595
errorCount += connectAndRead(url,allCredentials,true,true);
596
} else {
597
// Tests that no one is allowed
598
// connect & read
599
//
600
final String[][] someCredentials = {
601
null,
602
{ "modify", "R&D" },
603
{ "measure", "QED" }
604
};
605
errorCount += connectAndRead(url,someCredentials,false,false);
606
}
607
608
if (useAuthentication && allCredentials != noCredentials) {
609
// Tests that the registered user/passwords are not allowed to
610
// connect & read
611
//
612
final String[][] badCredentials = {
613
{ "bad.user", "R&D" },
614
{ "measure", "bad.password" }
615
};
616
errorCount += connectAndRead(url,badCredentials,false,false);
617
}
618
if (errorCount > 0) {
619
final String err = "Test " + confname + " failed with " +
620
errorCount + " error(s)";
621
log.debug("testCommunication",err);
622
throw new RuntimeException(err);
623
}
624
}
625
626
627
/**
628
* Test the configuration indicated by `file'.
629
* Sets the appropriate System properties for config file and
630
* port and then calls ConnectorBootstrap.initialize().
631
* eventually cleans up by calling ConnectorBootstrap.terminate().
632
* @return null if the test succeeds, an error message otherwise.
633
**/
634
private String testConfiguration(File file) throws IOException, InterruptedException {
635
636
for (int i = 0; i < MAX_GET_FREE_PORT_TRIES; i++) {
637
try {
638
int port = jdk.test.lib.Utils.getFreePort();
639
final String path;
640
try {
641
path=(file==null)?null:file.getCanonicalPath();
642
} catch(IOException x) {
643
final String err = "Failed to test configuration " + file +
644
": " + x;
645
log.trace("testConfiguration",err);
646
log.debug("testConfiguration",x);
647
return err;
648
}
649
final String config = (path==null)?"Default config file":path;
650
651
System.out.println("***");
652
System.out.println("*** Testing configuration (port=" + port + "): "
653
+ path);
654
System.out.println("***");
655
656
System.setProperty("com.sun.management.jmxremote.port",
657
Integer.toString(port));
658
if (path != null)
659
System.setProperty("com.sun.management.config.file", path);
660
else
661
System.getProperties().remove("com.sun.management.config.file");
662
663
log.trace("testConfiguration","com.sun.management.jmxremote.port="+port);
664
if (path != null && log.isDebugOn())
665
log.trace("testConfiguration",
666
"com.sun.management.config.file="+path);
667
668
checkSslConfiguration();
669
670
final JMXConnectorServer cs;
671
try {
672
cs = ConnectorBootstrap.initialize();
673
} catch (AgentConfigurationError x) {
674
if (x.getCause() instanceof ExportException) {
675
if (x.getCause().getCause() instanceof BindException) {
676
throw (BindException)x.getCause().getCause();
677
}
678
}
679
final String err = "Failed to initialize connector:" +
680
"\n\tcom.sun.management.jmxremote.port=" + port +
681
((path!=null)?"\n\tcom.sun.management.config.file="+path:
682
"\n\t"+config) +
683
"\n\tError is: " + x;
684
log.trace("testConfiguration",err);
685
log.debug("testConfiguration",x);
686
return err;
687
} catch (Exception x) {
688
log.debug("testConfiguration",x);
689
return x.toString();
690
}
691
692
try {
693
JMXServiceURL url =
694
new JMXServiceURL("rmi",null,0,"/jndi/rmi://localhost:"+
695
port+"/jmxrmi");
696
697
try {
698
testCommunication(url);
699
} catch (Exception x) {
700
final String err = "Failed to connect to agent {url="+url+
701
"}: " + x;
702
log.trace("testConfiguration",err);
703
log.debug("testConfiguration",x);
704
return err;
705
}
706
} catch (Exception x) {
707
final String err = "Failed to test configuration "+config+
708
": "+x;
709
log.trace("testConfiguration",err);
710
log.debug("testConfiguration",x);
711
return err;
712
} finally {
713
try {
714
cs.stop();
715
} catch (Exception x) {
716
final String err = "Failed to terminate: "+x;
717
log.trace("testConfiguration",err);
718
log.debug("testConfiguration",x);
719
}
720
}
721
System.out.println("Configuration " + config + " successfully tested");
722
return null;
723
} catch(BindException ex) {
724
}
725
}
726
System.err.println("Cannot find a free port after " + MAX_GET_FREE_PORT_TRIES + " tries");
727
return "Failed: cannot find a free port after " + MAX_GET_FREE_PORT_TRIES + " tries";
728
}
729
730
/**
731
* Test a configuration file which should make the bootstrap fail.
732
* The test is assumed to have succeeded if the bootstrap fails.
733
* @return null if the test succeeds, an error message otherwise.
734
**/
735
private String testConfigurationKo(File conf) throws InterruptedException, IOException {
736
String errStr = null;
737
errStr = testConfiguration(conf);
738
if (errStr == null) {
739
return "Configuration " +
740
conf + " should have failed!";
741
}
742
System.out.println("Configuration " +
743
conf + " failed as expected");
744
log.debug("runko", "Error was: " + errStr);
745
return null;
746
}
747
748
/**
749
* Test a configuration file. Determines whether the bootstrap
750
* should succeed or fail depending on the file name:
751
* *ok.properties: bootstrap should succeed.
752
* *ko.properties: bootstrap or connection should fail.
753
* @return null if the test succeeds, an error message otherwise.
754
**/
755
private String testConfigurationFile(String fileName) throws InterruptedException, IOException {
756
File file = new File(fileName);
757
758
if (fileName.endsWith("ok.properties")) {
759
String errStr = null;
760
errStr = testConfiguration(file);
761
return errStr;
762
}
763
if (fileName.endsWith("ko.properties")) {
764
return testConfigurationKo(file);
765
}
766
return fileName +
767
": test file suffix must be one of [ko|ok].properties";
768
}
769
770
/**
771
* Find all *ko.property files and test them.
772
* (see findConfigurationFilesKo() and testConfigurationKo())
773
* @throws RuntimeException if the test fails.
774
**/
775
public void runko() throws InterruptedException, IOException {
776
final File[] conf = findConfigurationFilesKo();
777
if ((conf == null)||(conf.length == 0))
778
throw new RuntimeException("No configuration found");
779
780
String errStr;
781
for (int i=0;i<conf.length;i++) {
782
errStr = testConfigurationKo(conf[i]);
783
if (errStr != null) {
784
throw new RuntimeException(errStr);
785
}
786
}
787
788
}
789
790
/**
791
* Find all *ok.property files and test them.
792
* (see findConfigurationFilesOk() and testConfiguration())
793
* @throws RuntimeException if the test fails.
794
**/
795
public void runok() throws InterruptedException, IOException {
796
final File[] conf = findConfigurationFilesOk();
797
if ((conf == null)||(conf.length == 0))
798
throw new RuntimeException("No configuration found");
799
800
String errStr = null;
801
for (int i=0;i<conf.length;i++) {
802
errStr = testConfiguration(conf[i]);
803
if (errStr != null) {
804
throw new RuntimeException(errStr);
805
}
806
}
807
808
// FIXME: No jmxremote.password is not installed in JRE by default.
809
// - disable the following test case.
810
//
811
// Test default config
812
//
813
// errStr = testConfiguration(null,port+testPort++);
814
// if (errStr != null) {
815
// throw new RuntimeException(errStr);
816
// }
817
}
818
819
/**
820
* Finds all configuration files (*ok.properties and *ko.properties)
821
* and tests them.
822
* (see runko() and runok()).
823
* @throws RuntimeException if the test fails.
824
**/
825
public void run() throws InterruptedException, IOException {
826
runok();
827
runko();
828
}
829
830
/**
831
* Tests the specified configuration files.
832
* If args[] is not empty, each element in args[] is expected to be
833
* a filename ending either by ok.properties or ko.properties.
834
* Otherwise, the configuration files will be automatically determined
835
* by looking at all *.properties files located in the directory
836
* indicated by the System property "test.src".
837
* @throws RuntimeException if the test fails.
838
**/
839
public void run(String args[]) throws InterruptedException, IOException {
840
if (args.length == 0) {
841
run() ; return;
842
}
843
for (int i=0; i<args.length; i++) {
844
final String errStr =testConfigurationFile(args[i]);
845
if (errStr != null) {
846
throw new RuntimeException(errStr);
847
}
848
}
849
}
850
851
/**
852
* Calls run(args[]).
853
* exit(1) if the test fails.
854
**/
855
public static void main(String args[]) throws Exception {
856
Security.setProperty("jdk.tls.disabledAlgorithms", "");
857
858
try {
859
MAX_GET_FREE_PORT_TRIES = Integer.parseInt(System.getProperty("test.getfreeport.max.tries", "10"));
860
} catch (NumberFormatException ex) {
861
}
862
863
RmiBootstrapTest manager = new RmiBootstrapTest();
864
try {
865
manager.run(args);
866
} catch (RuntimeException r) {
867
System.out.println("Test Failed: "+ r.getMessage());
868
System.exit(1);
869
} catch (Throwable t) {
870
System.out.println("Test Failed: "+ t);
871
t.printStackTrace();
872
System.exit(2);
873
}
874
System.out.println("**** Test RmiBootstrap Passed ****");
875
}
876
877
}
878
879