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