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