1 /*
2  * Copyright (c) 2012, 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 
24 import java.io.EOFException;
25 import java.io.File;
26 import java.io.IOException;
27 import java.lang.reflect.InvocationTargetException;
28 import java.lang.reflect.Method;
29 import java.net.BindException;
30 import java.net.ConnectException;
31 import java.net.ServerSocket;
32 import java.rmi.RemoteException;
33 import java.rmi.registry.LocateRegistry;
34 import java.rmi.registry.Registry;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.List;
38 import java.util.Objects;
39 import java.util.Set;
40 import java.util.concurrent.TimeoutException;
41 import java.util.concurrent.atomic.AtomicBoolean;
42 
43 import javax.management.*;
44 import javax.management.remote.*;
45 import javax.net.ssl.SSLHandshakeException;
46 
47 import jdk.test.lib.process.ProcessTools;
48 import jdk.test.lib.Utils;
49 import jdk.internal.agent.Agent;
50 import jdk.internal.agent.AgentConfigurationError;
51 import jdk.internal.agent.ConnectorAddressLink;
52 
53 /**
54  * @test
55  * @bug 7110104
56  * @key randomness intermittent
57  * @summary Makes sure that enabling/disabling the management agent through JCMD
58  *          achieves the desired results
59  *
60  * @library /test/lib
61  * @modules java.management
62  *          java.rmi
63  *          jdk.management.agent/jdk.internal.agent
64  *
65  * @build JMXStartStopTest PortAllocator TestApp ManagementAgentJcmd
66  * @run main/othervm/timeout=600 -XX:+UsePerfData JMXStartStopTest
67  */
68 public class JMXStartStopTest {
69     private static final String TEST_APP_NAME = "TestApp";
70 
71     private static final String TEST_SRC = System.getProperty("test.src");
72 
73     private static final boolean verbose = false;
74 
75     private static ManagementAgentJcmd jcmd = new ManagementAgentJcmd(TEST_APP_NAME, verbose);
76 
dbg_print(String msg)77     private static void dbg_print(String msg) {
78         if (verbose) {
79             System.out.println("DBG: " + msg);
80         }
81     }
82 
listMBeans(MBeanServerConnection server, ObjectName pattern, QueryExp query)83     private static int listMBeans(MBeanServerConnection server,
84             ObjectName pattern,
85             QueryExp query)
86             throws Exception {
87 
88         Set<ObjectName> names = server.queryNames(pattern,query);
89         for (ObjectName name : names) {
90             MBeanInfo info = server.getMBeanInfo(name);
91             dbg_print("Got MBean: " + name);
92 
93             MBeanAttributeInfo[] attrs = info.getAttributes();
94             if (attrs == null)
95                 continue;
96             for (MBeanAttributeInfo attr : attrs) {
97                 if (attr.isReadable()) {
98                     server.getAttribute(name, attr.getName());
99                 }
100             }
101         }
102         return names.size();
103     }
104 
testConnectLocal(long pid)105     private static void testConnectLocal(long pid)
106             throws Exception {
107 
108         String jmxUrlStr = null;
109 
110         try {
111             jmxUrlStr = ConnectorAddressLink.importFrom((int)pid);
112             dbg_print("Local Service URL: " +jmxUrlStr);
113             if ( jmxUrlStr == null ) {
114                 throw new Exception("No Service URL. Local agent not started?");
115             }
116 
117             JMXServiceURL url = new JMXServiceURL(jmxUrlStr);
118 
119             JMXConnector c = JMXConnectorFactory.connect(url, null);
120 
121             MBeanServerConnection conn = c.getMBeanServerConnection();
122             ObjectName pattern = new ObjectName("java.lang:type=Memory,*");
123 
124             int count = listMBeans(conn,pattern,null);
125             if (count == 0)
126                 throw new Exception("Expected at least one matching "+
127                                     "MBean for "+pattern);
128 
129         } catch (IOException e) {
130             dbg_print("Cannot find process : " + pid);
131             throw e;
132         }
133     }
134 
testNoConnect(int port)135     private static void testNoConnect(int port) throws Exception {
136         testNoConnect(port, 0);
137     }
138 
testNoConnect(int port, int rmiPort)139     private static void testNoConnect(int port, int rmiPort) throws Exception {
140         try {
141             testConnect(port, rmiPort);
142             throw new Exception("Didn't expect the management agent running");
143         } catch (Exception e) {
144             Throwable t = e;
145             while (t != null) {
146                 if (t instanceof RemoteException ||
147                     t instanceof SSLHandshakeException ||
148                     t instanceof ConnectException) {
149                     break;
150                 }
151                 t = t.getCause();
152             }
153             if (t == null) {
154                 throw new Exception("Unexpected exception", e);
155             }
156         }
157     }
158 
testConnect(int port)159     private static void testConnect(int port) throws Exception {
160         testConnect(port, 0);
161     }
162 
testConnect(int port, int rmiPort)163     private static void testConnect(int port, int rmiPort) throws Exception {
164         EOFException lastException = null;
165         // factor adjusted timeout (5 seconds) for the RMI to become available
166         long timeout = System.currentTimeMillis() + Utils.adjustTimeout(5000);
167         do {
168             try {
169                 doTestConnect(port, rmiPort);
170                 lastException = null;
171             } catch (EOFException e) {
172                 lastException = e;
173                 System.out.println("Error establishing RMI connection. Retrying in 500ms.");
174                 Thread.sleep(500);
175             }
176         } while (lastException != null && System.currentTimeMillis() < timeout);
177 
178         if (lastException != null) {
179             // didn't manage to get the RMI running in time
180             // rethrow the exception
181             throw lastException;
182         }
183     }
184 
doTestConnect(int port, int rmiPort)185     private static void doTestConnect(int port, int rmiPort) throws Exception {
186         dbg_print("RmiRegistry lookup...");
187 
188         dbg_print("Using port: " + port);
189 
190         dbg_print("Using rmi port: " + rmiPort);
191 
192         Registry registry = LocateRegistry.getRegistry(port);
193 
194         // "jmxrmi"
195         String[] relist = registry.list();
196         for (int i = 0; i < relist.length; ++i) {
197             dbg_print("Got registry: " + relist[i]);
198         }
199 
200         String jmxUrlStr = (rmiPort != 0) ?
201             String.format(
202                         "service:jmx:rmi://localhost:%d/jndi/rmi://localhost:%d/jmxrmi",
203                         rmiPort,
204                 port) :
205             String.format(
206                         "service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi",
207                         port);
208 
209         JMXServiceURL url = new JMXServiceURL(jmxUrlStr);
210 
211         JMXConnector c = JMXConnectorFactory.connect(url, null);
212 
213         MBeanServerConnection conn = c.getMBeanServerConnection();
214         ObjectName pattern = new ObjectName("java.lang:type=Memory,*");
215 
216         int count = listMBeans(conn,pattern,null);
217         if (count == 0)
218             throw new Exception("Expected at least one matching " +
219                                 "MBean for " + pattern);
220     }
221 
222     private static class Failure {
223         private final Throwable cause;
224         private final String msg;
225 
Failure(Throwable cause, String msg)226         public Failure(Throwable cause, String msg) {
227             this.cause = cause;
228             this.msg = msg;
229         }
230 
Failure(String msg)231         public Failure(String msg) {
232             this(null, msg);
233         }
234 
getCause()235         public Throwable getCause() {
236             return cause;
237         }
238 
getMsg()239         public String getMsg() {
240             return msg;
241         }
242 
243         @Override
hashCode()244         public int hashCode() {
245             int hash = 7;
246             hash = 97 * hash + Objects.hashCode(this.cause);
247             hash = 97 * hash + Objects.hashCode(this.msg);
248             return hash;
249         }
250 
251         @Override
equals(Object obj)252         public boolean equals(Object obj) {
253             if (obj == null) {
254                 return false;
255             }
256             if (getClass() != obj.getClass()) {
257                 return false;
258             }
259             final Failure other = (Failure) obj;
260             if (!Objects.equals(this.cause, other.cause)) {
261                 return false;
262             }
263             if (!Objects.equals(this.msg, other.msg)) {
264                 return false;
265             }
266             return true;
267         }
268 
269         @Override
toString()270         public String toString() {
271             if (cause != null) {
272                 return msg + "\n" + cause;
273             } else {
274                 return msg;
275             }
276         }
277     }
278 
279     private static List<Failure> failures = new ArrayList<>();
280 
main(String args[])281     public static void main(String args[]) throws Exception {
282         for (Method m : JMXStartStopTest.class.getDeclaredMethods()) {
283             if (m.getName().startsWith("test_")) {
284                 long t1 = System.currentTimeMillis();
285                 try {
286                     boolean retry = false;
287                     do {
288                         try {
289                             m.invoke(null);
290                             retry = false;
291                         } catch (InvocationTargetException e) {
292                             if (e.getCause() instanceof BindException ||
293                                 e.getCause() instanceof java.rmi.ConnectException) {
294                                 System.out.println("Failed to allocate ports. Retrying ...");
295                                 retry = true;
296                             } else {
297                                 throw e;
298                             }
299                         }
300                     } while (retry);
301                     System.out.println("=== PASSED");
302                 } catch (Throwable e) {
303                     failures.add(new Failure(e, m.getName() + " failed"));
304                 } finally {
305                     System.out.println("(took " + (System.currentTimeMillis() - t1) + "ms)\n");
306                 }
307             }
308         }
309 
310         if (!failures.isEmpty()) {
311             for(Failure f : failures) {
312                 System.err.println(f.getMsg());
313                 f.getCause().printStackTrace(System.err);
314             }
315             throw new Error();
316         }
317     }
318 
319     private static class TestAppRun {
320         private Process p;
321         private final ProcessBuilder pb;
322         private final String name;
323         private final AtomicBoolean started = new AtomicBoolean(false);
324         private volatile long pid = -1;
325 
TestAppRun(ProcessBuilder pb, String name)326         public TestAppRun(ProcessBuilder pb, String name) {
327             this.pb = pb;
328             this.name = name;
329         }
330 
start()331         public synchronized void start() throws InterruptedException, IOException, TimeoutException {
332             if (started.compareAndSet(false, true)) {
333                 try {
334                     AtomicBoolean error = new AtomicBoolean(false);
335                     p = ProcessTools.startProcess(
336                             TEST_APP_NAME + "{" + name + "}",
337                             pb,
338                             (line) -> {
339                                 boolean ok = line.equals("main enter");
340                                 error.set(line.contains("BindException"));
341 
342                                 return ok || error.get();
343                             }
344                     );
345                     if (error.get()) {
346                         throw new BindException("Starting process failed due to " +
347                                                 "the requested port not being available");
348                     }
349                     pid = p.pid();
350                 } catch (TimeoutException e) {
351                     if (p != null) {
352                         p.destroy();
353                         p.waitFor();
354                     }
355                     throw e;
356                 }
357             }
358         }
359 
getPid()360         public long getPid() {
361             return pid;
362         }
363 
stop()364         public synchronized void stop()
365                 throws IOException, InterruptedException {
366             if (started.compareAndSet(true, false)) {
367                 p.getOutputStream().write(0);
368                 p.getOutputStream().flush();
369                 int ec = p.waitFor();
370                 if (ec != 0) {
371                     StringBuilder msg = new StringBuilder();
372                     msg.append("Test application '").append(name);
373                     msg.append("' failed with exit code: ");
374                     msg.append(ec);
375 
376                     failures.add(new Failure(msg.toString()));
377                 }
378             }
379         }
380     }
381 
382     /**
383      * Runs the test application "TestApp"
384      * @param name Test run name
385      * @param args Additional arguments
386      * @return Returns a {@linkplain TestAppRun} instance representing the run
387      * @throws IOException
388      * @throws InterruptedException
389      * @throws TimeoutException
390      */
doTest(String name, String ... args)391     private static TestAppRun doTest(String name, String ... args)
392             throws Exception {
393         List<String> pbArgs = new ArrayList<>(Arrays.asList(
394                 "-cp",
395                 System.getProperty("test.class.path"),
396                 "-XX:+UsePerfData"
397         ));
398         pbArgs.addAll(Arrays.asList(args));
399         pbArgs.add(TEST_APP_NAME);
400 
401         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
402                 pbArgs.toArray(new String[pbArgs.size()])
403         );
404         TestAppRun s = new TestAppRun(pb, name);
405         s.start();
406         return s;
407     }
408 
test_01()409     static void test_01() throws Exception {
410         // Run an app with JMX enabled stop it and
411         // restart on other port
412 
413         System.out.println("**** Test one ****");
414         int ports[] = PortAllocator.allocatePorts(2);
415 
416         TestAppRun s = doTest(
417                 "test_01",
418                 "-Dcom.sun.management.jmxremote.port=" + ports[0],
419                 "-Dcom.sun.management.jmxremote.authenticate=false",
420                 "-Dcom.sun.management.jmxremote.ssl=false");
421 
422         try {
423             testConnect(ports[0]);
424 
425             jcmd.stop();
426             testNoConnect(ports[0]);
427 
428             jcmd.start("jmxremote.port=" + ports[1]);
429             testConnect(ports[1]);
430         } finally {
431             s.stop();
432         }
433     }
434 
test_02()435     static void test_02() throws Exception {
436         // Run an app without JMX enabled
437         // start JMX by jcmd
438 
439         System.out.println("**** Test two ****");
440 
441         int[] ports = PortAllocator.allocatePorts(1);
442         TestAppRun s = doTest("test_02");
443         try {
444             jcmd.start(
445                 "jmxremote.port=" + ports[0],
446                 "jmxremote.authenticate=false",
447                 "jmxremote.ssl=false"
448             );
449 
450             testConnect(ports[0]);
451         } finally {
452 //            debugPortUsage(pa);
453             s.stop();
454         }
455     }
456 
test_03()457     static void test_03() throws Exception {
458         // Run an app without JMX enabled
459         // start JMX by jcmd on one port than on other one
460 
461         System.out.println("**** Test three ****");
462 
463         int[] ports = PortAllocator.allocatePorts(2);
464         TestAppRun s = doTest("test_03");
465         try {
466             jcmd.start(
467                 "jmxremote.port=" + ports[0],
468                 "jmxremote.authenticate=false",
469                 "jmxremote.ssl=false"
470             );
471 
472             // Second agent shouldn't start
473             jcmd.start(
474                 "jmxremote.port=" + ports[1],
475                 "jmxremote.authenticate=false",
476                 "jmxremote.ssl=false"
477             );
478 
479             // First agent should connect
480             testConnect(ports[0]);
481 
482             // Second agent should not connect
483             testNoConnect(ports[1]);
484         } finally {
485             s.stop();
486         }
487     }
488 
test_04()489     static void test_04() throws Exception {
490         // Run an app without JMX enabled
491         // start JMX by jcmd on one port, specify rmi port explicitly
492 
493         System.out.println("**** Test four ****");
494 
495         int[] ports = PortAllocator.allocatePorts(2);
496         TestAppRun s = doTest("test_04");
497         try {
498             jcmd.start(
499                 "jmxremote.port=" + ports[0],
500                 "jmxremote.rmi.port=" + ports[1],
501                 "jmxremote.authenticate=false",
502                 "jmxremote.ssl=false"
503             );
504 
505             testConnect(ports[0], ports[1]);
506         } finally {
507             s.stop();
508         }
509     }
510 
test_05()511     static void test_05() throws Exception {
512         // Run an app without JMX enabled, it will enable local server
513         // but should leave remote server disabled
514 
515         System.out.println("**** Test five ****");
516         int[] ports = PortAllocator.allocatePorts(1);
517         TestAppRun s = doTest("test_05");
518         try {
519             jcmd.startLocal();
520 
521             testNoConnect(ports[0]);
522             testConnectLocal(s.getPid());
523         } finally {
524             s.stop();
525         }
526     }
527 
test_06()528     static void test_06() throws Exception {
529         // Run an app without JMX enabled
530         // start JMX by jcmd on one port, specify rmi port explicitly
531         // attempt to start it again with the same port
532         // Check for valid messages in the output
533 
534         System.out.println("**** Test six ****");
535 
536         int[] ports = PortAllocator.allocatePorts(2);
537         TestAppRun s = doTest("test_06");
538         try {
539             jcmd.start(
540                 "jmxremote.port=" + ports[0],
541                 "jmxremote.authenticate=false",
542                 "jmxremote.ssl=false"
543             );
544 
545             testConnect(ports[0], ports[1]);
546 
547             final AtomicBoolean checks = new AtomicBoolean(false);
548             jcmd.start(
549                 line -> {
550                     if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
551                         checks.set(true);
552                     }
553                 },
554                 "jmxremote.port=" + ports[0],
555                 "jmxremote.authenticate=false",
556                 "jmxremote.ssl=false"
557             );
558 
559             if (!checks.get()) {
560                 throw new Exception("Starting agent on port " + ports[0] + " should "
561                         + "report an invalid agent state");
562             }
563         } finally {
564             s.stop();
565         }
566     }
567 
test_07()568     static void test_07() throws Exception {
569         // Run an app without JMX enabled
570         // start JMX by jcmd on one port, specify rmi port explicitly
571         // attempt to start it again with other port
572         // Check for valid messages in the output
573 
574         System.out.println("**** Test seven ****");
575 
576         int[] ports = PortAllocator.allocatePorts(2);
577         TestAppRun s = doTest("test_07");
578         try {
579             jcmd.start(
580                 "jmxremote.port=" + ports[0],
581                 "jmxremote.authenticate=false",
582                 "jmxremote.ssl=false"
583             );
584 
585             testConnect(ports[0], ports[1]);
586 
587             final AtomicBoolean checks = new AtomicBoolean(false);
588 
589             jcmd.start(
590                 line -> {
591                     if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
592                         checks.set(true);
593                     }
594                 },
595                 "jmxremote.port=" + ports[1],
596                 "jmxremote.authenticate=false",
597                 "jmxremote.ssl=false"
598             );
599 
600             if (!checks.get()) {
601                 throw new Exception("Starting agent on poprt " + ports[1] + " should "
602                         + "report an invalid agent state");
603             }
604         } finally {
605             s.stop();
606         }
607     }
608 
test_08()609     static void test_08() throws Exception {
610         // Run an app without JMX enabled
611         // start JMX by jcmd on one port, specify rmi port explicitly
612         // attempt to stop it twice
613         // Check for valid messages in the output
614 
615         System.out.println("**** Test eight ****");
616 
617         int[] ports = PortAllocator.allocatePorts(2);
618         TestAppRun s = doTest("test_08");
619         try {
620             jcmd.start(
621                 "jmxremote.port=" + ports[0],
622                 "jmxremote.authenticate=false",
623                 "jmxremote.ssl=false"
624             );
625 
626             testConnect(ports[0], ports[1]);
627 
628             jcmd.stop();
629             jcmd.stop();
630         } finally {
631             s.stop();
632         }
633     }
634 
test_09()635     static void test_09() throws Exception {
636         // Run an app without JMX enabled
637         // attempt to start JMX using a non-available port
638         // Check for valid messages in the output
639 
640         System.out.println("**** Test nine ****");
641 
642         TestAppRun s = doTest("test_09");
643 
644         try (ServerSocket ss = new ServerSocket(0)) {
645             int localPort = ss.getLocalPort();
646             int[] ports;
647             do {
648                 ports = PortAllocator.allocatePorts(1);
649             } while (localPort == ports[0]);
650 
651             final AtomicBoolean checks = new AtomicBoolean(false);
652 
653             int retryCntr = 1;
654             do {
655                 final AtomicBoolean retry = new AtomicBoolean(false);
656 
657                 try {
658                     jcmd.start(
659                         line -> {
660                             if (line.contains(Agent.getText(AgentConfigurationError.AGENT_EXCEPTION))) {
661                                 retry.set(true);
662                             }
663                         },
664                         "jmxremote.port=" + ports[0],
665                         "jmxremote.rmi.port=" + localPort,
666                         "jmxremote.authenticate=false",
667                         "jmxremote.ssl=false"
668                     );
669                 } catch (BindException e) {
670                     checks.set(true);
671                 }
672                 if (!retry.get()) {
673                     break;
674                 }
675                 System.out.println("Attempt " + retryCntr + " >>>");
676                 System.out.println("Unexpected reply from the agent. Retrying in 500ms ...");
677                 Thread.sleep(500);
678             } while (retryCntr++ < 10);
679 
680             if (!checks.get()) {
681                 throw new Exception("Starting agent on port " + ports[0] + " should "
682                         + "report port in use");
683             }
684         } finally {
685             s.stop();
686         }
687 
688     }
689 
test_10()690     static void test_10() throws Exception {
691         // Run an app without JMX enabled, but with some properties set
692         // in command line.
693         // make sure these properties overridden corectly
694 
695         System.out.println("**** Test ten ****");
696 
697         int[] ports = PortAllocator.allocatePorts(2);
698         TestAppRun s = doTest(
699                 "test_10",
700                 "-Dcom.sun.management.jmxremote.authenticate=false",
701                 "-Dcom.sun.management.jmxremote.ssl=true");
702 
703         try {
704             testNoConnect(ports[0]);
705             jcmd.start(
706                 "jmxremote.port=" + ports[1],
707                 "jmxremote.authenticate=false",
708                 "jmxremote.ssl=false"
709             );
710             testConnect(ports[1]);
711         } finally {
712             s.stop();
713         }
714     }
715 
test_11()716     static void test_11() throws Exception {
717         // Run an app with JMX enabled and with some properties set
718         // in command line.
719         // stop JMX agent and then start it again with different property values
720         // make sure these properties overridden corectly
721 
722         System.out.println("**** Test eleven ****");
723         int[] ports = PortAllocator.allocatePorts(2);
724         TestAppRun s = doTest(
725                 "test_11",
726                 "-Dcom.sun.management.jmxremote.port=" + ports[0],
727                 "-Dcom.sun.management.jmxremote.authenticate=false",
728                 "-Dcom.sun.management.jmxremote.ssl=true");
729 
730         try {
731             testNoConnect(ports[0]);
732 
733             jcmd.stop();
734 
735             testNoConnect(ports[0]);
736 
737             jcmd.start(
738                 "jmxremote.port=" + ports[1],
739                 "jmxremote.authenticate=false",
740                 "jmxremote.ssl=false"
741             );
742 
743             testConnect(ports[1]);
744         } finally {
745             s.stop();
746         }
747     }
748 
test_12()749     static void test_12() throws Exception {
750         // Run an app with JMX enabled and with some properties set
751         // in command line.
752         // stop JMX agent and then start it again with different property values
753         // specifing some property in management config file and some of them
754         // in command line
755         // make sure these properties overridden corectly
756 
757         System.out.println("**** Test twelve ****");
758 
759         int[] ports = PortAllocator.allocatePorts(2);
760         TestAppRun s = doTest("test_12",
761                 "-Dcom.sun.management.config.file="
762                 + TEST_SRC + File.separator + "management_cl.properties",
763                 "-Dcom.sun.management.jmxremote.authenticate=false"
764         );
765 
766         try {
767             testNoConnect(ports[0]);
768 
769             jcmd.stop();
770 
771             testNoConnect(ports[0]);
772 
773             jcmd.start(
774                 "config.file=" + TEST_SRC + File.separator
775                 + "management_jcmd.properties",
776                 "jmxremote.authenticate=false",
777                 "jmxremote.port=" + ports[1]
778             );
779 
780             testConnect(ports[1]);
781         } finally {
782             s.stop();
783         }
784     }
785 
test_13()786     static void test_13() throws Exception {
787         // Run an app with JMX enabled and with some properties set
788         // in command line.
789         // stop JMX agent and then start it again with different property values
790         // stop JMX agent again and then start it without property value
791         // make sure these properties overridden corectly
792 
793         System.out.println("**** Test thirteen ****");
794         int[] ports = PortAllocator.allocatePorts(1);
795         TestAppRun s = doTest(
796                 "test_13",
797                 "-Dcom.sun.management.jmxremote.port=" + ports[0],
798                 "-Dcom.sun.management.jmxremote.authenticate=false",
799                 "-Dcom.sun.management.jmxremote.ssl=true");
800 
801         try {
802             testNoConnect(ports[0]);
803 
804             jcmd.stop();
805             jcmd.start(
806                 "jmxremote.ssl=false",
807                 "jmxremote.port=" + ports[0]
808             );
809             testConnect(ports[0]);
810 
811             jcmd.stop();
812             jcmd.start(
813                 "jmxremote.port=" + ports[0]
814             );
815 
816             testNoConnect(ports[0]);
817         } finally {
818             s.stop();
819         }
820     }
821 
test_14()822     static void test_14() throws Exception {
823         // Run an app with JMX enabled
824         // stop remote agent
825         // make sure local agent is not affected
826 
827         System.out.println("**** Test fourteen ****");
828         int[] ports = PortAllocator.allocatePorts(1);
829         TestAppRun s = doTest(
830                 "test_14",
831                 "-Dcom.sun.management.jmxremote.port=" + ports[0],
832                 "-Dcom.sun.management.jmxremote.authenticate=false",
833                 "-Dcom.sun.management.jmxremote.ssl=false");
834         try {
835             testConnect(ports[0]);
836             jcmd.stop();
837             testConnectLocal(s.getPid());
838         } finally {
839             s.stop();
840         }
841     }
842 
test_15()843     static void test_15() throws Exception {
844         // Run an app with JMX disabled
845         // start local agent only
846 
847         System.out.println("**** Test fifteen ****");
848 
849         int[] ports = PortAllocator.allocatePorts(1);
850         TestAppRun s = doTest("test_15");
851 
852         try {
853             testNoConnect(ports[0]);
854             jcmd.startLocal();
855 
856             testConnectLocal(s.getPid());
857 
858         } finally {
859             s.stop();
860         }
861     }
862 
863 }
864