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 
  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.testlibrary.ProcessTools;
  48 import jdk.testlibrary.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  * @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  */
  64 public 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 }