1 /* 2 * Copyright (c) 2003, 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 /* 25 * @test 26 * @bug 4940957 8025205 27 * @summary Tests behaviour when connections break 28 * @author Eamonn McManus 29 * @modules java.management 30 * @run clean BrokenConnectionTest 31 * @run build BrokenConnectionTest 32 * @run main BrokenConnectionTest 33 */ 34 35 import java.io.*; 36 import java.lang.reflect.*; 37 import java.nio.channels.ServerSocketChannel; 38 import java.net.*; 39 import java.rmi.server.*; 40 import java.util.*; 41 42 import java.rmi.UnmarshalException; 43 44 import javax.management.*; 45 import javax.management.remote.*; 46 import javax.management.remote.rmi.*; 47 48 // resolve ambiguity 49 import java.lang.reflect.Proxy; 50 51 public class BrokenConnectionTest { 52 private static ObjectName DELEGATE_NAME; 53 private static ObjectName BREAK_NAME; 54 private static ObjectName LISTENER_NAME; 55 public static void main(String[] args) throws Exception { 56 DELEGATE_NAME = 57 new ObjectName("JMImplementation:type=MBeanServerDelegate"); 58 BREAK_NAME = new ObjectName("test:type=Break"); 59 LISTENER_NAME = new ObjectName("test:type=Listener"); 60 61 String failed = ""; 62 63 final String[] protos = {"rmi", "jmxmp"}; 64 65 for (int i = 0; i < protos.length; i++) { 66 final String proto = protos[i]; 67 System.out.println(); 68 System.out.println("------- Testing for " + proto + " -------"); 69 try { 70 if (!test(proto)) 71 failed += " " + proto; 72 } catch (Exception e) { 73 System.out.println("FAILED WITH EXCEPTION:"); 74 e.printStackTrace(System.out); 75 failed += " " + proto; 76 } 77 } 78 79 System.out.println(); 80 81 if (failed.length() > 0) { 82 System.out.println("TEST FAILED FOR:" + failed); 83 System.exit(1); 84 } 85 86 System.out.println("Test passed"); 87 } 88 89 private static boolean test(String proto) throws Exception { 90 if (proto.equals("rmi")) 91 return rmiTest(); 92 else if (proto.equals("jmxmp")) 93 return jmxmpTest(); 94 else 95 throw new AssertionError(proto); 96 } 97 98 private static interface Breakable { 99 public JMXConnectorServer createConnectorServer(MBeanServer mbs) 100 throws IOException; 101 public void setBroken(boolean broken); 102 } 103 104 private static interface TestAction { 105 public String toString(); 106 public boolean test(MBeanServerConnection mbsc, Breakable breakable) 107 throws Exception; 108 } 109 110 private static abstract class Operation implements TestAction { 111 public String toString() { 112 return opName() + ", break, " + opName(); 113 } 114 void init(MBeanServerConnection mbsc) throws Exception {} 115 abstract String opName(); 116 public boolean test(MBeanServerConnection mbsc, Breakable breakable) 117 throws Exception { 118 init(mbsc); 119 operation(mbsc); 120 System.out.println("Client ran " + opName() + " OK"); 121 breakable.setBroken(true); 122 System.out.println("Broke connection, run " + opName() + " again"); 123 try { 124 operation(mbsc); 125 System.out.println("TEST FAILED: " + opName() + 126 " should fail!"); 127 return false; 128 } catch (IOException e) { 129 System.out.println("Got IOException as expected (" + e + ")"); 130 } 131 return true; 132 } 133 abstract void operation(MBeanServerConnection mbsc) throws Exception; 134 } 135 136 private static TestAction[] tests = { 137 new Operation() { 138 String opName() { 139 return "getDefaultDomain"; 140 } 141 void operation(MBeanServerConnection mbsc) throws Exception { 142 mbsc.getDefaultDomain(); 143 } 144 }, 145 new Operation() { 146 String opName() { 147 return "addNotificationListener(NL)"; 148 } 149 void operation(MBeanServerConnection mbsc) throws Exception { 150 mbsc.addNotificationListener(DELEGATE_NAME, 151 new CountListener(), null, null); 152 } 153 }, 154 new Operation() { 155 String opName() { 156 return "addNotificationListener(MB)"; 157 } 158 void init(MBeanServerConnection mbsc) throws Exception { 159 mbsc.createMBean(CountListener.class.getName(), 160 LISTENER_NAME); 161 } 162 void operation(MBeanServerConnection mbsc) throws Exception { 163 mbsc.addNotificationListener(DELEGATE_NAME, LISTENER_NAME, 164 null, null); 165 } 166 }, 167 new Operation() { 168 String opName() { 169 return "removeNotificationListener(NL)"; 170 } 171 void init(MBeanServerConnection mbsc) throws Exception { 172 for (int i = 0; i < NLISTENERS; i++) { 173 NotificationListener l = new CountListener(); 174 mbsc.addNotificationListener(DELEGATE_NAME, l, null, null); 175 listeners.add(l); 176 } 177 } 178 void operation(MBeanServerConnection mbsc) throws Exception { 179 NotificationListener l = (NotificationListener) 180 listeners.remove(0); 181 mbsc.removeNotificationListener(DELEGATE_NAME, l, null, null); 182 } 183 static final int NLISTENERS = 2; 184 List/*<NotificationListener>*/ listeners = new ArrayList(); 185 }, 186 new Operation() { 187 String opName() { 188 return "removeNotificationListener(MB)"; 189 } 190 void init(MBeanServerConnection mbsc) throws Exception { 191 mbsc.createMBean(CountListener.class.getName(), 192 LISTENER_NAME); 193 } 194 void operation(MBeanServerConnection mbsc) throws Exception { 195 try { 196 mbsc.removeNotificationListener(DELEGATE_NAME, 197 LISTENER_NAME, 198 null, null); 199 throw new IllegalArgumentException("removeNL should not " + 200 "have worked!"); 201 } catch (ListenerNotFoundException e) { 202 // normal - there isn't one! 203 } 204 } 205 }, 206 new Operation() { 207 String opName() { 208 return "createMBean(className, objectName)"; 209 } 210 void operation(MBeanServerConnection mbsc) throws Exception { 211 ObjectName name = 212 new ObjectName("test:instance=" + nextInstance()); 213 mbsc.createMBean(CountListener.class.getName(), name); 214 } 215 private synchronized int nextInstance() { 216 return ++instance; 217 } 218 private int instance; 219 }, 220 new Operation() { 221 String opName() { 222 return "getAttribute"; 223 } 224 void operation(MBeanServerConnection mbsc) throws Exception { 225 mbsc.getAttribute(DELEGATE_NAME, "ImplementationName"); 226 } 227 }, 228 new Operation() { 229 String opName() { 230 return "getAttributes"; 231 } 232 void operation(MBeanServerConnection mbsc) throws Exception { 233 mbsc.getAttribute(DELEGATE_NAME, "ImplementationName"); 234 } 235 }, 236 new Operation() { 237 String opName() { 238 return "getDomains"; 239 } 240 void operation(MBeanServerConnection mbsc) throws Exception { 241 mbsc.getDomains(); 242 } 243 }, 244 new Operation() { 245 String opName() { 246 return "getMBeanCount"; 247 } 248 void operation(MBeanServerConnection mbsc) throws Exception { 249 mbsc.getMBeanCount(); 250 } 251 }, 252 new Operation() { 253 String opName() { 254 return "getMBeanInfo"; 255 } 256 void operation(MBeanServerConnection mbsc) throws Exception { 257 mbsc.getMBeanInfo(DELEGATE_NAME); 258 } 259 }, 260 new Operation() { 261 String opName() { 262 return "getObjectInstance"; 263 } 264 void operation(MBeanServerConnection mbsc) throws Exception { 265 mbsc.getObjectInstance(DELEGATE_NAME); 266 } 267 }, 268 new Operation() { 269 String opName() { 270 return "invoke"; 271 } 272 void operation(MBeanServerConnection mbsc) throws Exception { 273 mbsc.invoke(BREAK_NAME, "doNothing", new Object[0], 274 new String[0]); 275 } 276 }, 277 new Operation() { 278 String opName() { 279 return "isInstanceOf"; 280 } 281 void operation(MBeanServerConnection mbsc) throws Exception { 282 mbsc.isInstanceOf(DELEGATE_NAME, "whatsit"); 283 } 284 }, 285 new Operation() { 286 String opName() { 287 return "isRegistered"; 288 } 289 void operation(MBeanServerConnection mbsc) throws Exception { 290 mbsc.isRegistered(DELEGATE_NAME); 291 } 292 }, 293 new Operation() { 294 String opName() { 295 return "queryMBeans"; 296 } 297 void operation(MBeanServerConnection mbsc) throws Exception { 298 mbsc.queryMBeans(new ObjectName("*:*"), null); 299 } 300 }, 301 new Operation() { 302 String opName() { 303 return "queryNames"; 304 } 305 void operation(MBeanServerConnection mbsc) throws Exception { 306 mbsc.queryNames(new ObjectName("*:*"), null); 307 } 308 }, 309 new Operation() { 310 String opName() { 311 return "setAttribute"; 312 } 313 void operation(MBeanServerConnection mbsc) throws Exception { 314 mbsc.setAttribute(BREAK_NAME, 315 new Attribute("Nothing", null)); 316 } 317 }, 318 new Operation() { 319 String opName() { 320 return "setAttributes"; 321 } 322 void operation(MBeanServerConnection mbsc) throws Exception { 323 AttributeList attrs = new AttributeList(); 324 attrs.add(new Attribute("Nothing", null)); 325 mbsc.setAttributes(BREAK_NAME, attrs); 326 } 327 }, 328 new Operation() { 329 String opName() { 330 return "unregisterMBean"; 331 } 332 void init(MBeanServerConnection mbsc) throws Exception { 333 for (int i = 0; i < NBEANS; i++) { 334 ObjectName name = new ObjectName("test:instance=" + i); 335 mbsc.createMBean(CountListener.class.getName(), name); 336 names.add(name); 337 } 338 } 339 void operation(MBeanServerConnection mbsc) throws Exception { 340 ObjectName name = (ObjectName) names.remove(0); 341 mbsc.unregisterMBean(name); 342 } 343 private static final int NBEANS = 2; 344 private List/*<ObjectName>*/ names = new ArrayList(); 345 }, 346 new TestAction() { 347 public String toString() { 348 return "break during send for setAttribute"; 349 } 350 public boolean test(MBeanServerConnection mbsc, 351 Breakable breakable) throws Exception { 352 Attribute attr = 353 new Attribute("Break", new BreakWhenSerialized(breakable)); 354 try { 355 mbsc.setAttribute(BREAK_NAME, attr); 356 System.out.println("TEST FAILED: setAttribute with " + 357 "BreakWhenSerializable did not fail!"); 358 return false; 359 } catch (IOException e) { 360 System.out.println("Got IOException as expected: " + e); 361 362 return true; 363 } 364 } 365 }, 366 new TestAction() { 367 public String toString() { 368 return "break during receive for getAttribute"; 369 } 370 public boolean test(MBeanServerConnection mbsc, 371 Breakable breakable) throws Exception { 372 try { 373 mbsc.getAttribute(BREAK_NAME, "Break"); 374 System.out.println("TEST FAILED: getAttribute of " + 375 "BreakWhenSerializable did not fail!"); 376 return false; 377 } catch (IOException e) { 378 System.out.println("Got IOException as expected: " + e); 379 380 return true; 381 } 382 } 383 }, 384 }; 385 386 public static interface BreakMBean { 387 public BreakWhenSerialized getBreak(); 388 public void setBreak(BreakWhenSerialized x); 389 // public void breakOnNotify(); 390 public void doNothing(); 391 public void setNothing(Object x); 392 } 393 394 public static class Break 395 extends NotificationBroadcasterSupport implements BreakMBean { 396 public Break(Breakable breakable) { 397 this.breakable = breakable; 398 } 399 400 public BreakWhenSerialized getBreak() { 401 return new BreakWhenSerialized(breakable); 402 } 403 404 public void setBreak(BreakWhenSerialized x) { 405 throw new IllegalArgumentException("setBreak worked but " + 406 "should not!"); 407 } 408 409 // public void breakOnNotify() { 410 // Notification broken = new Notification("type", "source", 0L); 411 // broken.setUserData(new BreakWhenSerialized(breakable)); 412 // sendNotification(broken); 413 // } 414 415 public void doNothing() {} 416 417 public void setNothing(Object x) {} 418 419 private final Breakable breakable; 420 } 421 422 private static class BreakWhenSerialized implements Serializable { 423 BreakWhenSerialized(Breakable breakable) { 424 this.breakable = breakable; 425 } 426 427 private void writeObject(ObjectOutputStream out) throws IOException { 428 breakable.setBroken(true); 429 } 430 431 private final transient Breakable breakable; 432 } 433 434 private static class FailureNotificationFilter 435 implements NotificationFilter { 436 public boolean isNotificationEnabled(Notification n) { 437 System.out.println("Filter: " + n + " (" + n.getType() + ")"); 438 439 final String failed = 440 JMXConnectionNotification.FAILED; 441 return (n instanceof JMXConnectionNotification 442 && n.getType().equals(JMXConnectionNotification.FAILED)); 443 } 444 } 445 446 public static interface CountListenerMBean {} 447 448 public static class CountListener 449 implements CountListenerMBean, NotificationListener { 450 public synchronized void handleNotification(Notification n, Object h) { 451 count++; 452 } 453 454 int count; 455 } 456 457 private static boolean test(Breakable breakable) 458 throws Exception { 459 boolean alreadyMissedFailureNotif = false; 460 String failed = ""; 461 for (int i = 1; i <= tests.length; i++) { 462 TestAction ta = tests[i - 1]; 463 System.out.println(); 464 System.out.println("Test " + i + ": " + ta); 465 MBeanServer mbs = MBeanServerFactory.newMBeanServer(); 466 Break breakMBean = new Break(breakable); 467 mbs.registerMBean(breakMBean, BREAK_NAME); 468 JMXConnectorServer cs = breakable.createConnectorServer(mbs); 469 System.out.println("Created and started connector server"); 470 JMXServiceURL addr = cs.getAddress(); 471 JMXConnector cc = JMXConnectorFactory.connect(addr); 472 CountListener failureListener = new CountListener(); 473 NotificationFilter failureFilter = new FailureNotificationFilter(); 474 cc.addConnectionNotificationListener(failureListener, 475 failureFilter, 476 null); 477 MBeanServerConnection mbsc = cc.getMBeanServerConnection(); 478 System.out.println("Client connected OK"); 479 boolean thisok = ta.test(mbsc, breakable); 480 481 try { 482 System.out.println("Stopping server"); 483 cs.stop(); 484 } catch (IOException e) { 485 System.out.println("Ignoring exception on stop: " + e); 486 } 487 if (thisok) { 488 System.out.println("Waiting for failure notif"); 489 // pass or test timeout. see 8025205 490 do { 491 Thread.sleep(100); 492 } while (failureListener.count < 1); 493 494 Thread.sleep(1000); // if more notif coming ... 495 if (failureListener.count > 1) { 496 System.out.println("Got too many failure notifs: " + 497 failureListener.count); 498 thisok = false; 499 } 500 } 501 if (!thisok) 502 failed = failed + " " + i; 503 System.out.println("Test " + i + (thisok ? " passed" : " FAILED")); 504 breakable.setBroken(false); 505 } 506 if (failed.equals("")) 507 return true; 508 else { 509 System.out.println("FAILING CASES:" + failed); 510 return false; 511 } 512 } 513 514 private static class BreakableRMI implements Breakable { 515 public JMXConnectorServer createConnectorServer(MBeanServer mbs) 516 throws IOException { 517 JMXServiceURL url = new JMXServiceURL("rmi", null, 0); 518 Map env = new HashMap(); 519 env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, 520 brssf); 521 JMXConnectorServer cs = 522 JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); 523 cs.start(); 524 return cs; 525 } 526 527 public void setBroken(boolean broken) { 528 brssf.setBroken(broken); 529 } 530 531 private final BreakableRMIServerSocketFactory brssf = 532 new BreakableRMIServerSocketFactory(); 533 } 534 535 private static boolean rmiTest() throws Exception { 536 System.out.println("RMI broken connection test"); 537 Breakable breakable = new BreakableRMI(); 538 return test(breakable); 539 } 540 541 private static class BreakableRMIServerSocketFactory 542 implements RMIServerSocketFactory { 543 544 public synchronized ServerSocket createServerSocket(int port) 545 throws IOException { 546 if (broken) 547 throw new IOException("ServerSocket has been broken"); 548 BreakableServerSocket bss = new BreakableServerSocket(port); 549 bssList.add(bss); 550 return bss; 551 } 552 553 synchronized void setBroken(boolean broken) { 554 this.broken = broken; 555 // System.out.println("BRSSF.setBroken(" + broken + ")"); 556 for (Iterator it = bssList.iterator(); it.hasNext(); ) { 557 BreakableServerSocket bss = (BreakableServerSocket) it.next(); 558 // System.out.println((broken ? "" : "un") + "break " + bss); 559 bss.setBroken(broken); 560 } 561 } 562 563 private final List/*<BreakableServerSocket>*/ bssList = 564 new ArrayList(); 565 private boolean broken = false; 566 } 567 568 private static class BreakableJMXMP implements Breakable { 569 BreakableJMXMP() throws IOException { 570 bss = new BreakableServerSocket(0); 571 } 572 573 public JMXConnectorServer createConnectorServer(MBeanServer mbs) 574 throws IOException { 575 try { 576 InvocationHandler scsih = 577 new SocketConnectionServerInvocationHandler(bss); 578 final String mcs = 579 "javax.management.remote.generic.MessageConnectionServer"; 580 final Class messageConnectionServerClass = Class.forName(mcs); 581 final Class[] proxyInterfaces = {messageConnectionServerClass}; 582 Object socketConnectionServer = 583 Proxy.newProxyInstance(this.getClass().getClassLoader(), 584 proxyInterfaces, 585 scsih); 586 Map env = new HashMap(); 587 env.put("jmx.remote.message.connection.server", 588 socketConnectionServer); 589 final String gcs = 590 "javax.management.remote.generic.GenericConnectorServer"; 591 final Class genericConnectorServerClass = Class.forName(gcs); 592 final Class[] constrTypes = {Map.class, MBeanServer.class}; 593 final Constructor constr = 594 genericConnectorServerClass.getConstructor(constrTypes); 595 JMXConnectorServer cs = (JMXConnectorServer) 596 constr.newInstance(new Object[] {env, mbs}); 597 cs.start(); 598 return cs; 599 } catch (Exception e) { 600 e.printStackTrace(System.out); 601 throw new AssertionError(e); 602 } 603 } 604 605 public void setBroken(boolean broken) { 606 bss.setBroken(broken); 607 } 608 609 private final BreakableServerSocket bss; 610 } 611 612 private static boolean jmxmpTest() throws Exception { 613 System.out.println("JMXMP broken connection test"); 614 try { 615 Class.forName("javax.management.remote.generic.GenericConnector"); 616 } catch (ClassNotFoundException e) { 617 System.out.println("Optional classes not present, skipping test"); 618 return true; 619 } 620 Breakable breakable = new BreakableJMXMP(); 621 return test(breakable); 622 } 623 624 private static class BreakableServerSocket extends ServerSocket { 625 BreakableServerSocket(int port) throws IOException { 626 super(); 627 ss = new ServerSocket(port); 628 } 629 630 synchronized void setBroken(boolean broken) { 631 this.broken = broken; 632 // System.out.println("BSS.setBroken(" + broken + ")"); 633 if (!broken) 634 return; 635 for (Iterator it = sList.iterator(); it.hasNext(); ) { 636 Socket s = (Socket) it.next(); 637 try { 638 // System.out.println("Break: " + s); 639 s.close(); 640 } catch (IOException e) { 641 System.out.println("Unable to close socket: " + s + 642 ", ignoring (" + e + ")"); 643 } 644 it.remove(); 645 } 646 } 647 648 public void bind(SocketAddress endpoint) throws IOException { 649 ss.bind(endpoint); 650 } 651 652 public void bind(SocketAddress endpoint, int backlog) 653 throws IOException { 654 ss.bind(endpoint, backlog); 655 } 656 657 public InetAddress getInetAddress() { 658 return ss.getInetAddress(); 659 } 660 661 public int getLocalPort() { 662 return ss.getLocalPort(); 663 } 664 665 public SocketAddress getLocalSocketAddress() { 666 return ss.getLocalSocketAddress(); 667 } 668 669 public Socket accept() throws IOException { 670 // System.out.println("BSS.accept"); 671 Socket s = ss.accept(); 672 // System.out.println("BSS.accept returned: " + s); 673 if (broken) 674 s.close(); 675 else 676 sList.add(s); 677 return s; 678 } 679 680 public void close() throws IOException { 681 ss.close(); 682 } 683 684 public ServerSocketChannel getChannel() { 685 return ss.getChannel(); 686 } 687 688 public boolean isBound() { 689 return ss.isBound(); 690 } 691 692 public boolean isClosed() { 693 return ss.isClosed(); 694 } 695 696 public void setSoTimeout(int timeout) throws SocketException { 697 ss.setSoTimeout(timeout); 698 } 699 700 public int getSoTimeout() throws IOException { 701 return ss.getSoTimeout(); 702 } 703 704 public void setReuseAddress(boolean on) throws SocketException { 705 ss.setReuseAddress(on); 706 } 707 708 public boolean getReuseAddress() throws SocketException { 709 return ss.getReuseAddress(); 710 } 711 712 public String toString() { 713 return "BreakableServerSocket wrapping " + ss.toString(); 714 } 715 716 public void setReceiveBufferSize (int size) throws SocketException { 717 ss.setReceiveBufferSize(size); 718 } 719 720 public int getReceiveBufferSize() throws SocketException { 721 return ss.getReceiveBufferSize(); 722 } 723 724 private final ServerSocket ss; 725 private final List/*<Socket>*/ sList = new ArrayList(); 726 private boolean broken = false; 727 } 728 729 /* We do a lot of messy reflection stuff here because we don't 730 want to reference the optional parts of the JMX Remote API in 731 an environment (J2SE) where they won't be present. */ 732 733 /* This class implements the logic that allows us to pretend that 734 we have a class that looks like this: 735 class SocketConnectionServer implements MessageConnectionServer { 736 public MessageConnection accept() throws IOException {...} 737 public JMXServiceURL getAddress() {...} 738 public void start(Map env) throws IOException {...} 739 public void stop() throws IOException {...} 740 } 741 */ 742 private static class SocketConnectionServerInvocationHandler 743 implements InvocationHandler { 744 SocketConnectionServerInvocationHandler(ServerSocket ss) { 745 this.ss = ss; 746 } 747 748 public Object invoke(Object proxy, Method method, Object[] args) 749 throws Exception { 750 final String mname = method.getName(); 751 try { 752 if (mname.equals("accept")) 753 return accept(); 754 else if (mname.equals("getAddress")) 755 return getAddress(); 756 else if (mname.equals("start")) 757 start((Map) args[0]); 758 else if (mname.equals("stop")) 759 stop(); 760 else // probably a method inherited from Object 761 return method.invoke(this, args); 762 } catch (InvocationTargetException ite) { 763 Throwable t = ite.getCause(); 764 if (t instanceof IOException) { 765 throw (IOException)t; 766 } else if (t instanceof RuntimeException) { 767 throw (RuntimeException)t; 768 } else { 769 throw ite; 770 } 771 } 772 773 return null; 774 } 775 776 private Object/*MessageConnection*/ accept() throws Exception { 777 System.out.println("SCSIH.accept()"); 778 Socket s = ss.accept(); 779 Class socketConnectionClass = 780 Class.forName("com.sun.jmx.remote.socket.SocketConnection"); 781 Constructor constr = 782 socketConnectionClass.getConstructor(new Class[] {Socket.class}); 783 return constr.newInstance(new Object[] {s}); 784 // InvocationHandler scih = new SocketConnectionInvocationHandler(s); 785 // Class messageConnectionClass = 786 // Class.forName("javax.management.generic.MessageConnection"); 787 // return Proxy.newProxyInstance(this.getClass().getClassLoader(), 788 // new Class[] {messageConnectionClass}, 789 // scih); 790 } 791 792 private JMXServiceURL getAddress() throws Exception { 793 System.out.println("SCSIH.getAddress()"); 794 return new JMXServiceURL("jmxmp", null, ss.getLocalPort()); 795 } 796 797 private void start(Map env) throws IOException { 798 System.out.println("SCSIH.start(" + env + ")"); 799 } 800 801 private void stop() throws IOException { 802 System.out.println("SCSIH.stop()"); 803 } 804 805 private final ServerSocket ss; 806 } 807 }